nss-resolve: add env var to specify resolved ifindex

Adds a new `SYSTEMD_NSS_RESOLVE_INTERFACE` environment variable to the nss-resolve module, whose value is subsequently passed down to the `ifindex` resolved lookup option.
This allows name lookups to be constrained to a just single interface for e.g. captive portal browsers.
This commit is contained in:
Popax21
2025-12-18 10:53:27 +01:00
committed by Zbigniew Jędrzejewski-Szmek
parent 18d90c1628
commit f603bc37f4
2 changed files with 35 additions and 3 deletions
+11
View File
@@ -141,6 +141,17 @@
<xi:include href="version-info.xml" xpointer="v250"/></listitem>
</varlistentry>
</variablelist>
<variablelist class='environment-variables'>
<varlistentry>
<term><varname>$SYSTEMD_NSS_RESOLVE_INTERFACE</varname></term>
<listitem><para>Takes an interface name or index as an argument. When specified, answers will only be
obtained from name servers belonging to the specified interface.</para>
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
+24 -3
View File
@@ -12,6 +12,7 @@
#include "glyph-util.h"
#include "in-addr-util.h"
#include "json-util.h"
#include "netlink-util.h"
#include "nss-util.h"
#include "resolved-def.h"
#include "signal-util.h"
@@ -188,6 +189,23 @@ static uint64_t query_flags(void) {
query_flag("SYSTEMD_NSS_RESOLVE_NETWORK", 0, SD_RESOLVED_NO_NETWORK);
}
static int query_ifindex(void) {
int ifindex;
const char *e;
e = secure_getenv("SYSTEMD_NSS_RESOLVE_INTERFACE");
if (!e)
return 0;
ifindex = rtnl_resolve_interface(/* rtnl= */ NULL, e);
if (ifindex < 0) {
log_debug_errno(ifindex, "Failed to resolve $SYSTEMD_NSS_RESOLVE_INTERFACE, ignoring: %m");
ifindex = 0;
}
return ifindex;
}
enum nss_status _nss_resolve_gethostbyname4_r(
const char *name,
struct gaih_addrtuple **pat,
@@ -217,7 +235,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
r = sd_json_buildo(
&cparams,
SD_JSON_BUILD_PAIR_STRING("name", name),
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
if (r < 0)
goto fail;
@@ -386,7 +405,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
&cparams,
SD_JSON_BUILD_PAIR_STRING("name", name),
SD_JSON_BUILD_PAIR_INTEGER("family", af),
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
if (r < 0)
goto fail;
@@ -606,7 +626,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
&cparams,
SD_JSON_BUILD_PAIR_BYTE_ARRAY("address", addr, len),
SD_JSON_BUILD_PAIR_INTEGER("family", af),
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
if (r < 0)
goto fail;