Validating DNSSEC locally, the 2020 way
22 March 2020 ·You can find plenty of old, bad guides on validating DNSSEC online. The worst ones I’ve seen just say to do
% dig example.org
and tell you that the status: NOERROR
you see in the response means
that DNSSEC was validated (or at least, if it exists for that domain,
it was validated).
That’s not true at all. Some resolvers do in fact validate this information for you, like Google’s DNS:
% dig @8.8.8.8 bad.dnssec-or-not.com
does give you status: SERVFAIL
. But obviously you shouldn’t be
counting on that. A DNS server that doesn’t support DNSSEC, like
Level3’s, will happily return your query with the NOERROR
status.
% dig @4.2.2.1 bad.dnssec-or-not.com
Some slightly better guides tell you to look for the AD
flag. This
is part of an IETF standard
by which a recursive resolver can indicate to you that it has
verified the DNSSEC data. So if you run those two commands I have
above on a site with valid DNSSEC data (like example.org), you’ll
see that the response from Google includes the ad
flag, but the
response from Level3 does not.
Does this mean that you have verified the DNSSEC data? No. It
means that Google says it has verified the DNSSEC data. And the
interesting thing is that it’s actually quite difficult to verify
it yourself, at least with the traditional tools. And the tools
you’re using most of the time, including dig
, nslookup
, and
probably your browser too are not verifying DNSSEC data. They’re
relying on you to have configured a resolver with DNSSEC support,
and that resolver to return SERVFAILs if you query a domain with
broken DNSSEC. It’s entirely based on trust.
I’ve found one or two guides out there which tell you how to fetch
all the DNSSEC data you need and verify it yourself piece by piece.
Most of the time you’ll use dig
to get the data you need.
You can certainly do this, as long as you don’t slip up on any part
of the process. (Most guides seem woefully incomplete on how exactly
you need to do this.) But it turns out that a few years ago the BIND
folks added a new tool (alongside their others, nslookup
and dig
)
that does automatically verify DNSSEC. I discovered it by accident
when reading a man
page. You can get it on Arch Linux in the
Extra package bind-tools
,
and Ubuntu and Debian have it in dnsutils
.
The syntax is very similar to dig
. The rest of this post is pretty
self explanatory. Observe how delv
discovers that the site’s
DNSSEC is broken, even though it’s using a resolver that doesn’t
verify DNSSEC.
% delv @4.2.2.1 +short bad.dnssec-or-not.com
;; validating bad.dnssec-or-not.com/A: no valid signature found
;; RRSIG failed to verify resolving 'bad.dnssec-or-not.com/A/IN': 4.2.2.1#53
;; resolution failed: RRSIG failed to verify
Compare dig
:
% dig @4.2.2.1 +short bad.dnssec-or-not.com
173.230.152.222
And with a DNSSEC supporting resolver:
% delv @8.8.8.8 +short bad.dnssec-or-not.com
;; resolution failed: SERVFAIL
And with a site with woring DNSSEC:
% delv @4.2.2.1 +nocrypto example.org
; fully validated
example.org. 82231 IN A 93.184.216.34
example.org. 82231 IN RRSIG A 8 2 86400 20200402175057 20200312201336 63865 example.org. [omitted]