Kresd response missing OPT pseudo-RR

Queries to multicast DNS hostnames (ending with the .local top-level domain) are blocked with an NXDOMAIN reply code, which is fine. However, if the request contains OPT pseudo-RR, the response should include one too. All public DNS resolvers I’ve tried do it.

Query to Turris:

$ dig @192.168.1.1 example.local

; <<>> DiG 9.11.25-RedHat-9.11.25-2.fc33 <<>> @192.168.1.1 example.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; 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: 28663
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;example.local.			IN	A

;; AUTHORITY SECTION:
example.local.		10800	IN	SOA	example.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"

;; Query time: 2 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Út pro 15 11:35:06 CET 2020
;; MSG SIZE  rcvd: 254

Query to Cloudflare, Google, …

dig @1.1.1.1 example.local

; <<>> DiG 9.11.25-RedHat-9.11.25-2.fc33 <<>> @1.1.1.1 example.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; 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: 49933
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.local.			IN	A

;; AUTHORITY SECTION:
.			86400	IN	SOA	a.root-servers.net. nstld.verisign-grs.com. 2020121500 1800 900 604800 86400

;; Query time: 12 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Út pro 15 11:36:48 CET 2020
;; MSG SIZE  rcvd: 117

Why is this behavior a problem? Fedora 33 (and maybe other distros) uses nss-mdns for multicast DNS hostname resolution in combination with systemd-resolved. nss-mdns uses something called a unicast SOA heuristic: if, during a request, the system-configured unicast DNS reports an SOA record for the top-level local name, the request is rejected. When systemd-resolved receives a response with no OPT pseudo-RR, it assumes the server does not support EDNS(0) and drops it for all future transactions too:

systemd-resolved[186024]: Server doesn't support EDNS(0) properly, downgrading feature level...
systemd-resolved[186024]: Using degraded feature set UDP instead of UDP+EDNS0 for DNS server 192.168.1.1.
systemd-resolved[186024]: Server feature level is now lower than when we began our transaction. Restarting with new ID.

Is it possible this is a kresd bug?

2 Likes

Thanks! That indeed is a bug in the way the blocking rules work. The EDNS(0) standard does require to return OPT iff it came.

I opened an issue upstream: https://gitlab.nic.cz/knot/knot-resolver/-/issues/657

Thanks for the confirmation and for creating the upstream issue.