DNSSEC, signed and validated
The trust chain#
| Level | Signed by | Records | RFC |
|---|---|---|---|
root (.) | the resolver's own trust anchor | DNSKEY, RRSIG | RFC 4033 |
TLD (net.) | root, via DS | DNSKEY, DS, RRSIG | RFC 4034 |
zone (isitdns.net.) | TLD, via DS | DNSKEY, DS, RRSIG | RFC 4034 |
| a record | zone's ZSK | RRSIG | RFC 4035 |
| a name that does not exist | zone's ZSK | NSEC or NSEC3, RRSIG | RFC 4035, RFC 5155 |
A resolver walks DS → DNSKEY → RRSIG at each level and either reaches a chain it trusts, or fails. See anatomy-of-a-query for the hop-by-hop walk.
Is a zone signed?#
Two commands. isitdns.net is signed and anchored, so both return real values.
dig @1.1.1.1 +short DNSKEY isitdns.net256 3 13 oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8 KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==
257 3 13 mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+ KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==256 3 13 <key> and 257 3 13 <key> are flags, protocol, algorithm, public key (RFC 4034 section 2.1):
| Flags | Role | What points at it |
|---|---|---|
256 | ZSK, signs the zone's ordinary records | the RRSIGs over the zone's RRsets |
257 | KSK, signs the DNSKEY set; the key the parent's DS fingerprints | the DS record in the parent |
Algorithm 13 is ECDSAP256SHA256, the modern default; 8 is RSASHA256, older but still common. Both validate the same way.
dig -4 @a.gtld-servers.net +short DS isitdns.net2371 13 2 2DF8E1D4E0855DF60F2A8B51C914F2F2866ED1E3344F74F9682DAC4D 42D18802If both commands return values, the zone is signed and anchored to the parent. The keytag (2371 as of 2026-07-28) changes whenever Cloudflare rolls the KSK; treat it as a snapshot. If either is empty, the zone is unsigned or the chain is broken: dnssec-troubleshooting finds which link.
See it in action#
Asks for the address and the signature over it.
dig @1.1.1.1 example.isitdns.net A +dnssecGO ad on the flags line, and an RRSIG beside the A record
NO GO no ad, so unvalidated or stripped on the path
Modern dig requests the ad bit by default, with or without +dnssec
(BIND 9 dig manual, +adflag:
"This bit is set by default"). A path between the resolver and your stub can
still strip it: transparent interceptors, some captive portals, and consumer
routers clear the bit in transit. delv does not depend on it; it carries its
own root trust anchor and validates the chain itself. dnssec-troubleshooting
covers delv, including the macOS caveat (the system delv has no crypto
support).
Break any link in the chain and a validating resolver answers SERVFAIL
instead of an unverified answer, usually with an Extended DNS Error naming
which link broke (RFC 8914). That is
the failure mode most people meet DNSSEC through. dnssec-troubleshooting
is the fix path; extended-dns-errors has the code table.
Gotchas#
- The
adbit is the resolver's claim about the last hop, not proof you can verify yourself. Adelvverdict is computed on your own machine, so nothing on the path can fake it (RFC 4033 section 7). - DNSSEC proves the data, not the path: it does not prove your query reached a genuine authoritative server, and it does not encrypt anything. See dot-doh for query privacy.
- A compromised registrar account lets an attacker re-publish the zone's DS record and point the chain at a key they control.
- NSEC responses expose the zone's next owner name in plaintext, letting an attacker walk the chain to enumerate every name in the zone. NSEC3 hashes owner names instead (RFC 5155).
isitdns.netuses Cloudflare's compact NSEC denial, which answers a nonexistent name withNOERRORrather thanNXDOMAIN(RFC 9824). - Key rollover breaks the chain when the parent's DS and the child's DNSKEY fall out of step; timing is defined in RFC 7583. See ksk-roll-2026 for the 2026 root roll.
See also#
- dnsviz
- caa-policy
- Cloudflare DNSSEC docs
- DNSSEC chain check: walk a chain live, root to answer