DNS Cheatsheet
DNSSEC
Use this DNS reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
What DNSSEC does and does not do
DNSSEC signs DNS answers so a validating resolver can prove the data came from the zone owner and was not modified in transit.
- It does provide origin authentication and integrity, plus authenticated
proof that a name does not exist.
- It does not encrypt anything. Queries and answers are still plaintext on
the wire, which is what DoT, DoH, and DoQ are for.
- It does not stop a compromised registrar or a stolen key.
- It does break loudly. A misconfigured zone returns SERVFAIL to every
validating resolver.
The four record types
| Type | Lives in | Holds |
|---|---|---|
| DNSKEY | The zone itself | A public key. Flag 257 is a KSK, 256 is a ZSK |
| RRSIG | The zone, beside every RRset | A signature over one RRset |
| DS | The parent zone | A hash of the child's KSK. This is the link |
| NSEC / NSEC3 | The zone | Proof that a name or type does not exist |
$ dig cloudflare.com DNSKEY +multiline +noall +answer cloudflare.com. 2099 IN DNSKEY 257 3 13 ( mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+Gq JxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ== ) ; KSK; alg = ECDSAP256SHA256 ; key id = 2371 $ dig cloudflare.com DS +short 2371 13 2 32996839A6D808AFE3EB4A795A0E6A7A39A76FC52FF228B22B76F6D63826F2B9
Note the 2371 in both. The DS at the parent must reference a DNSKEY the child
actually publishes, matched by key tag and algorithm. That single number is
where most DNSSEC outages live.
The two keys
| KSK (Key Signing Key) | ZSK (Zone Signing Key) | |
|---|---|---|
| DNSKEY flag | 257 | 256 |
| Signs | The DNSKEY RRset only | Every other RRset in the zone |
| Referenced by the parent DS | Yes | No |
| Rotation | Hard, requires a DS update at the parent | Easy, purely internal |
| Typical size | Larger, longer lived | Smaller, rotated often |
Splitting them lets you rotate the ZSK freely without touching the registrar. A single CSK (combined signing key) is simpler and makes every rotation a parent update.
The chain of trust
Validation walks down from a hardcoded root key, and each step is the same pattern: the parent's DS hashes the child's KSK.
1. The resolver ships with the root trust anchor, the root KSK, compiled in.
It is the only key trusted a priori, and the root DNSKEY is checked against it.
2. The root publishes a DS for com., signed by the root ZSK. com.'s
DNSKEY is fetched and hashed, and the hash must equal that DS. Now com.
is trusted.
3. com. publishes a DS for example.com.. Same check, so the zone becomes
trusted.
4. The A record's RRSIG is verified with example.com.'s ZSK.
5. The resolver sets the ad flag in its answer to the client.
# every link in the chain, in order dig . DNSKEY +short | head -2 dig com DS +short dig example.com DS +short dig example.com DNSKEY +short | head -1 dig example.com A +dnssec +noall +answer delv +vtrace example.com A # or let a tool walk it and explain
A break anywhere returns SERVFAIL for the whole subtree. There is no partial validation and no fallback to unsigned.
Algorithms and NSEC3
| Number | Algorithm | Verdict |
|---|---|---|
| 5, 7 | RSASHA1 variants | Deprecated |
| 8 | RSASHA256 | Fine, universal support, large signatures |
| 10 | RSASHA512 | Fine, larger still |
| 13 | ECDSAP256SHA256 | The current default choice |
| 14 | ECDSAP384SHA384 | Fine, less common |
| 15 | ED25519 | Modern and small, support is now broad |
Algorithm 13 gives the smallest signatures of the widely supported options, which matters because DNSSEC answers are large enough to force TCP fallback.
NSEC vs NSEC3, for proving a name does not exist:
- NSEC returns the alphabetically adjacent existing name. That leaks the entire zone contents to anyone who walks it. - NSEC3 returns hashed names instead, optionally with iterations and a salt. It resists casual enumeration but is offline-crackable, and iterations above 0 are now discouraged. - NSEC3 opt-out skips proof for unsigned delegations, which large TLDs use to keep zone size manageable.
dig nonexistent.cloudflare.com A +dnssec +noall +authority
# NSEC3 records plus RRSIGs, proving the absenceEnabling, rotating, disabling
Enabling, in the only safe order:
1. Turn on signing at your DNS provider. Managed providers do this with one
toggle and handle the keys.
2. Verify the zone validates on its own before touching the parent, with
delv @ns1.provider.net example.com A or DNSViz.
3. Copy the DS record into the registrar, not into your zone. Some
registrars take the DNSKEY and compute the DS themselves.
4. Confirm the parent published it: dig example.com DS +short.
5. Test against a validating resolver, dig @1.1.1.1 example.com A +dnssec
should show ad in the flags.
Disabling, and the order is the whole thing:
- Remove the DS at the registrar first.
- Wait out the DS TTL, typically 86400, plus a margin. A full day.
- Only then turn off signing at the provider.
Reversing those two steps takes the domain down. A DS at the parent with no matching DNSKEY in the child means every validating resolver returns SERVFAIL. This is the single most common DNSSEC outage, and it usually happens during a nameserver migration.
Rotating: a ZSK rollover is internal to the provider, so pre-publish the new key, switch signing, retire the old one after the DNSKEY TTL. A KSK rollover needs a DS update at the parent, so publish both DS records, wait out the TTL, switch, then remove the old DS. CDS and CDNSKEY records let a cooperating registry automate that.
Debugging
The diagnostic that separates DNSSEC from everything else is +cdflag, which
tells the resolver to skip validation.
$ dig @1.1.1.1 dnssec-failed.org A +noall +comments ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 31104 $ dig @1.1.1.1 dnssec-failed.org A +cdflag +noall +comments ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51151
SERVFAIL without +cdflag and NOERROR with it is a DNSSEC failure, full
stop. The data is there and the signatures do not check out.
| Symptom | Likely cause |
|---|---|
SERVFAIL everywhere, NOERROR with +cdflag | Broken chain: DS/DNSKEY mismatch |
| SERVFAIL after a nameserver change | DS left at the parent, new provider not signing |
| SERVFAIL that started at a specific hour | Expired RRSIG, signer stopped running |
Works on 8.8.8.8, fails on 1.1.1.1 | Cached pre-break answer on one of them |
No ad flag but answers work | Zone is unsigned, or your resolver does not validate |
| Intermittent timeouts on large answers | Response exceeds MTU, TCP 53 blocked |
delv example.com A # validates and says why not delv +vtrace example.com A # show the validation steps dig example.com A +dnssec +multiline # read the RRSIG expiry yourself dig example.com DNSKEY +multiline # key tags and algorithms, annotated
DNSViz draws the chain and marks the broken link, which is faster than reading RRSIG timestamps by hand.
Gotchas
- Removing signing before removing the DS takes the domain offline for every
validating resolver. Always DS first, then wait a full day.
- RRSIGs expire. A signer that stops running takes the zone down when the last
signature lapses, commonly 14 to 30 days later, long after anyone connects it
to the change.
- Clock skew breaks validation. An RRSIG has inception and expiration
timestamps, so a resolver or signer with a wrong clock rejects valid data.
- DNSSEC answers are big and force TCP fallback. A firewall permitting UDP 53
but blocking TCP 53 turns DNSSEC into intermittent timeouts.
- The ad flag is set by your resolver, not by the zone. Its absence can mean
the zone is unsigned or your resolver does not validate. Test against
1.1.1.1 or 8.8.8.8, both of which validate.
- Registrar UIs differ on DS versus DNSKEY. Some want the four DS fields
(key tag, algorithm, digest type, digest), some want the DNSKEY and compute the
DS. Pasting the wrong one produces a chain that never validates.