]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: never allow _gateway lookups to go to the network
authorLennart Poettering <lennart@poettering.net>
Wed, 11 Nov 2020 16:38:21 +0000 (17:38 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 2 Dec 2020 23:56:27 +0000 (08:56 +0900)
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

index f23d0b65795be19beef71617ec970102f8da21f8..666aa892ea991a54deabe6e270011c4bdc7794f4 100644 (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