From fbbc72189f7844df8500bb10a58988f70bf90c99 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2020 17:38:21 +0100 Subject: [PATCH] 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. --- src/resolve/resolved-dns-scope.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index f23d0b6579..666aa892ea 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -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