Graham, thanks for this comprehensive exposition of the problem.

You are entirely correct that this particular bit of the DNS Camel has passe me by up to this point.

The behavior mandated by RFC4035 looks pretty straightforward to implement, and would, I think solve your immediate problem. The stuff in
RFC 6672 will need quite a lot more head-scratching.

In any case, I'll address both of these, but not for the long-delayed 2.91 release; that just needs to be out there now for all the things it does fix.

Cheers,

Simon.



On 3/12/25 12:05, Clinch, Graham wrote:
Hello,

We have a pair of signed DNS zones: lancs.ac.uk & lancaster.ac.uk. lancaster.ac.uk contains a DNAME record which "redirects" all names beneath it to the same name within lancs.ac.uk (i.e. abc.def.lancaster.ac.uk becomes abc.def.lancs.ac.uk).

-=-

$ dig www.lancaster.ac.uk

[…]

;; ANSWER SECTION:

lancaster.ac.uk.              43200   IN           DNAME lancs.ac.uk.

www.lancaster.ac.uk.   43200   IN           CNAME www.lancs.ac.uk.

www.lancs.ac.uk.           3600      IN           A             148.88.65.80

-=-

Bind, unbound & knot resolver are happy to (validate &) resolve names beneath either zone (although kresd had difficulty before 2020: https:// gitlab.nic.cz/knot/knot-resolver/-/issues/234 <https://gitlab.nic.cz/ knot/knot-resolver/-/issues/234>), and dnsviz reports no errors (eg https://dnsviz.net/d/www.lancaster.ac.uk/dnssec/ <https://dnsviz.net/d/ www.lancaster.ac.uk/dnssec/>) so we believe the zones are configured reasonably.

dnsmasq, when dnssec validation is enabled, is unhappy with names beneath lancaster.ac.uk.  I suspect that dnsmasq is unsure how to validate the synthesized, unsigned (correctly: rfc 4035 sect. 3 final para), CNAME record - a quick skim of dnsmasq's source doesn't show as much referencing of T_DNAME as I would expect for a DNAME-aware resolver).

I've recreated this with dnsmasq 2.91rc5:

-=-

# make COPTS=-DHAVE_DNSSEC

[…]

# ./src/dnsmasq --version

Dnsmasq version 2.91rc5  Copyright (c) 2000-2025 Simon Kelley

Compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop- detect inotify dumpfile

This software comes with ABSOLUTELY NO WARRANTY.

Dnsmasq is free software, and you are welcome to redistribute it

under the terms of the GNU General Public License, version 2 or 3.

-=-

===

First, without dnssec validation, resolution is successful:

-=-

$ dig -p 5353 @127.0.0.1 www.lancaster.ac.uk

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> -p 5353 @127.0.0.1 www.lancaster.ac.uk

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19572

;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 1232

; COOKIE: b6f0093fa57419c20100000067d16e0a0b00303eb49db846 (good)

;; QUESTION SECTION:

;www.lancaster.ac.uk.                 IN           A

;; ANSWER SECTION:

lancaster.ac.uk.              43200   IN           DNAME lancs.ac.uk.

www.lancaster.ac.uk.   43200   IN           CNAME wWw.lancs.ac.uk.

www.lancs.ac.uk.           3600      IN           A             148.88.65.80

;; Query time: 0 msec

;; SERVER: 127.0.0.1#5353(127.0.0.1) (UDP)

;; WHEN: Wed Mar 12 11:20:42 GMT 2025

;; MSG SIZE  rcvd: 154

-=-

-=-

# ./src/dnsmasq --listen-address=127.0.0.1 --no-daemon --no-hosts -- port=5353 --log-queries --no-resolv --server=148.88.65.52

dnsmasq: started, version 2.91rc5 cachesize 150

dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile

dnsmasq: using nameserver 148.88.65.52#53

dnsmasq: cleared cache

dnsmasq: query[A] www.lancaster.ac.uk from 127.0.0.1

dnsmasq: forwarded www.lancaster.ac.uk to 148.88.65.52

dnsmasq: reply www.lancaster.ac.uk is <CNAME>

dnsmasq: reply www.lancs.ac.uk is 148.88.65.80

-=-

===

Then, with dnssec validation enabled, the status is SERVFAIL, with an "NSEC Missing" error:

-=-

$ dig -p 5353 @127.0.0.1 www.lancaster.ac.uk

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> -p 5353 @127.0.0.1 www.lancaster.ac.uk

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 18645

;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 1232

; COOKIE: efab28c4571261b60100000067d16e90e4d4929c967d9830 (good)

; EDE: 12 (NSEC Missing)

;; QUESTION SECTION:

;www.lancaster.ac.uk.                 IN           A

;; Query time: 32 msec

;; SERVER: 127.0.0.1#5353(127.0.0.1) (UDP)

;; WHEN: Wed Mar 12 11:22:56 GMT 2025

;; MSG SIZE  rcvd: 82

-=-

-=-

# ./src/dnsmasq --listen-address=127.0.0.1 --no-daemon --no-hosts -- port=5353 --log-queries --no-resolv --server=148.88.65.52 --dnssec

dnsmasq: started, version 2.91rc5 cachesize 150

dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile

dnsmasq: DNSSEC validation enabled

dnsmasq: configured with trust anchor for <root> keytag 20326

dnsmasq: using nameserver 148.88.65.52#53

dnsmasq: cleared cache

dnsmasq: query[A] www.lancaster.ac.uk from 127.0.0.1

dnsmasq: forwarded www.lancaster.ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DS] uk to 148.88.65.52

dnsmasq: dnssec-query[DNSKEY] . to 148.88.65.52

dnsmasq: reply . is DNSKEY keytag 20326, algo 8

dnsmasq: reply . is DNSKEY keytag 38696, algo 8

dnsmasq: reply . is DNSKEY keytag 26470, algo 8

dnsmasq: reply uk is DS for keytag 43876, algo 8, digest 2

dnsmasq: dnssec-query[DS] ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DNSKEY] uk to 148.88.65.52

dnsmasq: reply uk is DNSKEY keytag 43876, algo 8

dnsmasq: reply uk is DNSKEY keytag 43056, algo 8

dnsmasq: reply ac.uk is DS for keytag 45874, algo 8, digest 2

dnsmasq: dnssec-query[DS] lancaster.ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DNSKEY] ac.uk to 148.88.65.52

dnsmasq: reply ac.uk is truncated

dnsmasq: dnssec-query[DNSKEY] ac.uk to 148.88.65.52

dnsmasq: reply ac.uk is DNSKEY keytag 63831, algo 8

dnsmasq: reply ac.uk is DNSKEY keytag 63490, algo 8

dnsmasq: reply ac.uk is DNSKEY keytag 54274, algo 8

dnsmasq: reply ac.uk is DNSKEY keytag 45874, algo 8

dnsmasq: reply lancaster.ac.uk is DS for keytag 18943, algo 13, digest 2

dnsmasq: dnssec-query[DNSKEY] lancaster.ac.uk to 148.88.65.52

dnsmasq: reply lancaster.ac.uk is DNSKEY keytag 52067, algo 13

dnsmasq: reply lancaster.ac.uk is DNSKEY keytag 18943, algo 13

dnsmasq: dnssec-query[DS] www.lancaster.ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DS] lancs.ac.uk to 148.88.65.52

dnsmasq: reply lancs.ac.uk is DS for keytag 30106, algo 13, digest 2

dnsmasq: dnssec-query[DNSKEY] lancs.ac.uk to 148.88.65.52

dnsmasq: reply lancs.ac.uk is DNSKEY keytag 30106, algo 13

dnsmasq: reply lancs.ac.uk is DNSKEY keytag 37821, algo 13

dnsmasq: validation www.lancaster.ac.uk is BOGUS

-=-

===

As an aside, see that a request for the lancaster.ac.uk DNAME itself is indeed successful:

-=-

$ dig -p 5353 @127.0.0.1 DNAME lancaster.ac.uk

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> -p 5353 @127.0.0.1 DNAME lancaster.ac.uk

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55357

;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 1232

; COOKIE: d05676a64991eea80100000067d16ece6573dd2d0a5376b5 (good)

;; QUESTION SECTION:

;lancaster.ac.uk.                             IN           DNAME

;; ANSWER SECTION:

lancaster.ac.uk.              43200   IN           DNAME lancs.ac.uk.

;; Query time: 40 msec

;; SERVER: 127.0.0.1#5353(127.0.0.1) (UDP)

;; WHEN: Wed Mar 12 11:23:58 GMT 2025

;; MSG SIZE  rcvd: 112

-=-

-=-

# ./src/dnsmasq --listen-address=127.0.0.1 --no-daemon --no-hosts -- port=5353 --log-queries --no-resolv --server=148.88.65.52 --dnssec

dnsmasq: started, version 2.91rc5 cachesize 150

dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile

dnsmasq: DNSSEC validation enabled

dnsmasq: configured with trust anchor for <root> keytag 20326

dnsmasq: using nameserver 148.88.65.52#53

dnsmasq: cleared cache

dnsmasq: query[DNAME] lancaster.ac.uk from 127.0.0.1

dnsmasq: forwarded lancaster.ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DS] uk to 148.88.65.52

dnsmasq: dnssec-query[DNSKEY] . to 148.88.65.52

dnsmasq: reply . is DNSKEY keytag 26470, algo 8

dnsmasq: reply . is DNSKEY keytag 20326, algo 8

dnsmasq: reply . is DNSKEY keytag 38696, algo 8

dnsmasq: reply uk is DS for keytag 43876, algo 8, digest 2

dnsmasq: dnssec-query[DS] ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DNSKEY] uk to 148.88.65.52

dnsmasq: reply uk is DNSKEY keytag 43056, algo 8

dnsmasq: reply uk is DNSKEY keytag 43876, algo 8

dnsmasq: reply ac.uk is DS for keytag 45874, algo 8, digest 2

dnsmasq: dnssec-query[DS] lancaster.ac.uk to 148.88.65.52

dnsmasq: dnssec-query[DNSKEY] ac.uk to 148.88.65.52

dnsmasq: reply ac.uk is truncated

dnsmasq: dnssec-query[DNSKEY] ac.uk to 148.88.65.52

dnsmasq: reply ac.uk is DNSKEY keytag 45874, algo 8

dnsmasq: reply ac.uk is DNSKEY keytag 54274, algo 8

dnsmasq: reply ac.uk is DNSKEY keytag 63831, algo 8

dnsmasq: reply ac.uk is DNSKEY keytag 63490, algo 8

dnsmasq: reply lancaster.ac.uk is DS for keytag 18943, algo 13, digest 2

dnsmasq: dnssec-query[DNSKEY] lancaster.ac.uk to 148.88.65.52

dnsmasq: reply lancaster.ac.uk is DNSKEY keytag 52067, algo 13

dnsmasq: reply lancaster.ac.uk is DNSKEY keytag 18943, algo 13

dnsmasq: validation result is SECURE

dnsmasq: reply lancaster.ac.uk is <DNAME>

-=-

===

For reference, here is the result of querying unbound with validation enabled:

-=-

$ dig +short @127.0.0.1 txt ch version.bind

"unbound 1.17.1"

$ dig  @127.0.0.1 www.lancaster.ac.uk

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @127.0.0.1 www.lancaster.ac.uk

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31627

;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 1232

;; QUESTION SECTION:

;www.lancaster.ac.uk.                 IN           A

;; ANSWER SECTION:

lancaster.ac.uk.              43200   IN           DNAME lancs.ac.uk.

www.lancaster.ac.uk.   43200   IN           CNAME www.lancs.ac.uk.

www.lancs.ac.uk.           3600      IN           A             148.88.65.80

;; Query time: 72 msec

;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)

;; WHEN: Wed Mar 12 11:30:09 GMT 2025

;; MSG SIZE  rcvd: 113

-=-

RFC 4035 section 4.8 and RFC 6672 section 5.3 describe some of the contortions required to validate when a DNAME is involved.

DNSSEC signing is rare, and DNAME records are also rare, so I am unfortunately not aware of any other real-world instances of signed DNAMEs.  Other (unsigned) DNAME records seen in the wild include oxford- brookes.ac.uk & hrz.uni-bonn.de.

With thanks,

Graham


_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to