Resolver sometimes treats signed, insecure zone with broken DNSKEY as bogus
Summary
With a cold cache, when DNSSEC validation is on -- I don't know what happens when it's off -- BIND's resolver seems to require that signed zones (that is, zones with RRSIG
records present) also have parseable and reasonably valid DNSKEY
records, regardless of whether there are any DS
records. If not, it considers the zone bogus and returns SERVFAIL
.
If I try again a few minutes later, it works. I dunno what that's about.
I don't know what the RFCs say, but I think this is incorrect as a practical matter -- it's completely normal for zones that are enabling or disabling DNSSEC to have temporarily inconsistent records. For example, when a zone is first signed, there will probably be a few seconds or minutes where the primary nameserver has a completely signed zone while secondary nameservers still have no DNSSEC records. If a resolver happens to query different authoritative nameservers, it will get an inconsistent view of things.
The situation is worse for resolvers using forwarders, since they may get cached responses, and they don't have any way of knowing or controlling which authoritative nameservers the upstream recursive resolver queries.
Based on its traffic, I think BIND's logic goes like this (assuming the cache is emptyish and example.com
is signed but insecure):
- Query
www.example.com
A
. - See
RRSIG
. Queryexample.com
DNSKEY
.- If response is unparseable, mark bogus and return
SERVFAIL
. - If it's good, continue.
- If response is unparseable, mark bogus and return
- Query
example.com
DS
. Get negative response, mark insecure, return successful insecure response.
I've set up two zones with different issues:
-
unpublished.mattnordhoffdns.work
is signed but has a broken response toDNSKEY
queries -- it's a signed negative response saying noDNSKEY
records exist. (I'm abusing PowerDNS's algorithm rollover settings to put it in a broken state. Obviously nobody with common sense should do this in the real world.) -
half-signed.mattnordhoffdns.work
has two nameservers; one has a correctly signed version of the zone, and one has a completely unsigned version of the zone.
In the real world, I also had problems with a certain proprietary nameserver that used to have a horrible DNSKEY
bug, which has since been fixed.
BIND version used
I'm in stable distro hell. :-) I can only provide named -V
for my own resolver. The unpublished.mattnordhoffdns.work
issue was reproduced by someone else on 9.16.4. I've reproduced both issues on Quad9's 9.9.9.11; I would guess that runs some version of 9.11-S, but I don't know. (ISC might!)
BIND 9.10.3-P4-Ubuntu <id:ebd72b3>
built by make with '--prefix=/usr' '--mandir=/usr/share/man' '--libdir=/usr/lib/x86_64-linux-gnu' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-geoip=/usr' '--with-atf=no' '--enable-ipv6' '--enable-rrl' '--enable-filter-aaaa' '--enable-native-pkcs11' '--with-pkcs11=/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so' 'CFLAGS=-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -fno-strict-aliasing -fno-delete-null-pointer-checks -DNO_VERSION_DATE' 'LDFLAGS=-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2 -DDIG_SIGCHASE'
compiled by GCC 5.4.0 20160609
compiled with OpenSSL version: OpenSSL 1.0.2g 1 Mar 2016
linked to OpenSSL version: OpenSSL 1.0.2g 1 Mar 2016
compiled with libxml2 version: 2.9.3
linked to libxml2 version: 20903
Steps to reproduce
With a cold cache:
dig unpublished.mattnordhoffdns.work
-
dig half-signed.mattnordhoffdns.work
. This may or may not fail depending on which authoritative nameservers are hit.
If I try again a few minutes later, they both work. I don't know what that's about.
What is the current bug behavior?
SERVFAIL
.
What is the expected correct behavior?
NOERROR
.
Relevant configuration files
Relevant logs and/or screenshots
When dig unpublished.mattnordhoffdns.work soa
fails:
Oct 27 10:19:11 fin named[14772]: broken trust chain resolving 'unpublished.mattnordhoffdns.work/SOA/IN': 149.112.112.10#53
When it succeeds:
Oct 27 10:24:19 fin named[14772]: validating unpublished.mattnordhoffdns.work/SOA: no valid signature found