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:
- You do something like
ping foo.local
- 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 nssmdns4_minimal
client - The
mdns4_minimal
client before doing anything else tries unicast DNS looking for a SOA forlocal.
This mechanism is present in the mdns4_minimal client to avoid issues whenlocal
in under DNS control and is documented at https://github.com/lathiat/nss-mdns/blob/master/README.md - Ubuntu focal uses by default
systemd-resolved
as a caching DNS, so the query frommdns4_minimal
gets to it -
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) -
mdns4_minimal
receives a SOA reply for local and gives up - At this point DNS is queried. Back to
systemd-resolved
now trying to get the A field forfoo.local
. - 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. - 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:
- Ubuntu Focal is extremely widespread
- Ubuntu Focal is likely that it will not backport fixes to its
systemd-resolved
(because this is shipped in thesystemd
package that is quite delicate to touch) - 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.