Please document SOA included in authority section for queries within local (and how to avoid it)

As mentioned in https://forum.turris.cz/t/avahi-local-domain-warning-on-ubuntu/13437, knot resolver answers any queries within local by NXDOMAIN but it adds this SOA in the authority section:

$ dig local
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 56352
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:

;local.                         IN      A

;; AUTHORITY SECTION:

local.                  10800   IN      SOA     local. nobody.invalid. 1 3600 1200 604800 10800

;; ADDITIONAL SECTION:

explanation.invalid.    10800   IN      TXT     “Blocking is mandated by standards, see references on https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml”

Unfortunately, this confuses systemd-resolved (maybe just older versions of it) and completely breaks mDNS name resolution on ubuntu focal (and possibly other distros).

What happens is as follows:

  1. You do something like ping foo.local
  2. Ubuntu focal has by default the host field in nsswitch.conf set to: hosts: files mdns4_minimal [NOTFOUND=return] dns so it tries the /etc/hosts/ file and then mdns via the nss mdns4_minimal client
  3. The mdns4_minimal client before doing anything else tries unicast DNS looking for a SOA for local. This mechanism is present in the mdns4_minimal client to avoid issues when local in under DNS control and is documented at https://github.com/lathiat/nss-mdns/blob/master/README.md
  4. Ubuntu focal uses by default systemd-resolved as a caching DNS, so the query from mdns4_minimal gets to it
  5. systemd-resolved passes the query to the DNS it is configured to use. If this is Knot resolver it gets that special SOA in the authority section and turns it into a regular SOA reply (no NXDOMAIN)
  6. mdns4_minimal receives a SOA reply for local and gives up
  7. At this point DNS is queried. Back to systemd-resolved now trying to get the A field for foo.local.
  8. By default systemd-resolved on ubuntu is configured not to do mDNS itself (even if it has this capability). Hence the query at the previous point fails.
  9. Rather than pinging foo.local you get an error.

I believe that:

  • This is not a bug in knot resolver, rather a bug in systemd-resolved that makes itself confused by a legitimate answer from knot resolver
  • The issue in systemd-resolved may have been fixed in versions of systemd more recent than the one shipped in Ubuntu focal (at least some quick testing on a rolling distro seems not to give the problem)

However, because:

  1. Ubuntu Focal is extremely widespread
  2. Ubuntu Focal is likely that it will not backport fixes to its systemd-resolved (because this is shipped in the systemd package that is quite delicate to touch)
  3. The returning of the special SOA for things within local is something that older versions of knot resolver did not do

I believe that it could be worth adding an explicit note in the knot resolver documentation about the special SOA returned for queries within local and on how to avoid it in case it causes issues with mDNS name resolution.

I have observed that something like

policy.add(policy.suffix(policy.DROP, policy.todnames({'local.'})))

added to kresd.conf seems to be enough to workaround the problem, but I am not knowledgeable enough to know if this is the right solution.

Edited by Sergio Callegari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information