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), and dnsviz reports no 
errors (eg 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

Reply via email to