resolved: never allow _gateway lookups to go to the network

Make them rather fail than go to the network.

Previously we'd filter them on LLMNR (explicitly) and MDNS (implicitly,
because it doesn't have .local suffix), but not on DNS.

In order to make _gateway truly reliable, let's not allow it to go to
DNS either, and keep it local.

This is particular relevant, as clients can now request lookups without
local RR synthesis, where we'd rather have NXDOMAIN returned for
_gateway than have it hit the network.
This commit is contained in:
Lennart Poettering 2020-11-11 17:38:21 +01:00 committed by Yu Watanabe
parent 19bcef9dc3
commit fbbc72189f
1 changed files with 12 additions and 4 deletions

View File

@ -505,9 +505,8 @@ DnsScopeMatch dns_scope_good_domain(
if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, 0) & flags) == 0)
return DNS_SCOPE_NO;
/* Never resolve any loopback hostname or IP address via DNS,
* LLMNR or mDNS. Instead, always rely on synthesized RRs for
* these. */
/* Never resolve any loopback hostname or IP address via DNS, LLMNR or mDNS. Instead, always rely on
* synthesized RRs for these. */
if (is_localhost(domain) ||
dns_name_endswith(domain, "127.in-addr.arpa") > 0 ||
dns_name_equal(domain, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0)
@ -523,6 +522,15 @@ DnsScopeMatch dns_scope_good_domain(
if (dns_name_endswith(domain, "invalid") > 0)
return DNS_SCOPE_NO;
/* Never go to network for the _gateway domain, it's something special, synthesized locally. Note
* that we don't use is_gateway_hostname() here, since that has support for the legacy "gateway"
* hostname (without the prefix underscore), which we don't want to filter on all protocols. i.e. we
* don't want to filter "gateway" on classic DNS, since there might very well be such a host inside
* some search domain, and we shouldn't block that. We do filter it in LLMNR however (and on mDNS by
* side-effect, since it's a single-label name which mDNS doesn't accept anyway). */
if (dns_name_equal(domain, "_gateway") > 0)
return DNS_SCOPE_NO;
switch (s->protocol) {
case DNS_PROTOCOL_DNS: {
@ -615,7 +623,7 @@ DnsScopeMatch dns_scope_good_domain(
return DNS_SCOPE_MAYBE;
if ((dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */
!is_gateway_hostname(domain) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
!is_gateway_hostname(domain) && /* don't resolve "_gateway" with LLMNR, let local synthesizing logic handle that */
dns_name_equal(domain, "local") == 0 && /* don't resolve "local" with LLMNR, it's the top-level domain of mDNS after all, see above */
manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative