DNSSEC & DNS Security Footguns¶
Misconfigurations that take down your domain, expose your zone, or undermine the security you thought you had.
1. Publishing a DS Record Before the Child Zone Is Signed¶
You create a DS record at the registrar in advance of actually signing the zone. The parent now says "this zone uses DNSSEC" but the child zone serves no RRSIG records. Every validating resolver that queries your zone gets an authentication failure and returns SERVFAIL. Your entire domain is unreachable to any resolver with DNSSEC validation enabled (which is most major resolvers).
Fix: The correct order is: (1) sign the zone and verify locally, (2) confirm DNSKEY records are being served, (3) submit the DS record to the registrar. Never reverse this order.
Remember: The mnemonic is "sign, serve, submit" — always in that order. The parent's DS record is a promise to resolvers that the child zone is signed. If you publish the promise before the child delivers, every validating resolver rejects the zone. Undoing this requires removing the DS record from the parent and waiting for the DS TTL (up to 24 hours for .com) to expire everywhere.
2. Letting Signatures Expire Because the Auto-Signer Cron Failed¶
BIND's inline signer or your signing cron job silently stops running. Nobody notices because DNS continues to serve responses — resolvers cache the signed records. Three weeks later, cached records expire and resolvers fetch fresh records with expired RRSIG. The zone becomes SERVFAIL. The on-call page fires at 2am.
Fix: Monitor signature expiry as a first-class alert. The SOA RRSIG expiry date must always be checked:
Configure signatures-refresh in dnssec-policy to re-sign well before expiry (e.g., refresh when 5 days remain on a 30-day validity period). Alert at 14 days warning, 7 days critical.
3. Using NSEC Instead of NSEC3 on a Zone with Private Subdomains¶
NSEC creates an authenticated enumerable sorted list of all names in your zone. A single ldns-walk command gives an attacker your complete hostname inventory: admin.example.com, vpn.example.com, internal-api.example.com, staging.example.com. This is zone enumeration and it works even against zones that restrict zone transfers (AXFR).
Fix: Use NSEC3 with a random salt for any zone containing names you consider sensitive. NSEC3 hashes the names before chaining them, preventing trivial enumeration. Switch with:
4. Skipping the Parent TTL Wait During KSK Rollover¶
You generate a new KSK, submit the new DS record to the registrar, wait 5 minutes, and delete the old KSK. The parent zone still has the old DS record in resolver caches (DS TTL for .com is 86400 seconds — 24 hours). Resolvers with cached old DS records cannot validate the new KSK signature. Your zone returns SERVFAIL for those resolvers for up to 24 hours.
Fix: After submitting the new DS record, wait for the parent's DS TTL to fully expire everywhere before removing the old KSK. Use dig DS example.com @a.gtld-servers.net. to monitor propagation. The old DS must not appear at any authoritative TLD server before you remove the old KSK.
5. Confusing DNSSEC Authentication with DNS Encryption¶
Your team enables DNSSEC and believes DNS traffic is now secure. An attacker on the network path can still see every DNS query (which domains you're looking up) in plaintext on UDP port 53. DNSSEC proves the answer is authentic but does not hide it.
Fix: DNSSEC and DoT/DoH are orthogonal. For privacy, configure DNS-over-TLS (port 853) or DNS-over-HTTPS (port 443). For authentication (anti-spoofing), configure DNSSEC. Production environments should have both.
6. Not Monitoring DS Records After Registrar Migration¶
You migrate your domain to a new registrar. The new registrar does not import your existing DS records (this is common — many registrars do not support DS import and require you to re-enter them). The DS records go missing from the parent. Within 24 hours (the DS TTL), resolvers detect the broken chain and start returning SERVFAIL.
Fix: After any registrar migration, immediately verify DS records are present at the new registrar and check from the parent:
Make this a post-migration checklist item whenever you change registrars.
7. Configuring DNSSEC Validation on a Resolver Without Root Trust Anchor¶
You enable dnssec-validation yes in BIND but forget to configure or update the root trust anchor. BIND cannot validate the root zone — it returns SERVFAIL for everything. The difference:
dnssec-validation auto— uses the compiled-in root trust anchor and RFC 5011 automatic updatesdnssec-validation yes— requires you to manually specify the trust anchor in amanaged-keysortrusted-keysblock
Fix: Use dnssec-validation auto for most cases. If using yes, ensure the trust anchor is current:
dig DNSKEY . | awk '/^\..*DNSKEY 257/{print}' # current root KSK
unbound-anchor -a /var/lib/unbound/root.key # update Unbound's anchor
8. Zone Transfer Leaking DNSSEC Private Keys via Insecure AXFR¶
Your zone file is kept on a secondary server and transferred via unencrypted AXFR. If an attacker intercepts the AXFR, they get the zone data. Worse, if private keys are stored alongside zone files on the server, a compromise of the secondary server exposes the KSK. With the KSK private key, an attacker can sign fraudulent records that pass DNSSEC validation.
Fix: Use TSIG (Transaction Signatures) to authenticate AXFR:
# Generate TSIG key
tsig-keygen axfr-key > /etc/bind/tsig-axfr.key
# named.conf on primary:
key "axfr-key" { algorithm hmac-sha256; secret "base64keyhere"; };
zone "example.com" { allow-transfer { key "axfr-key"; }; };
# Store private keys in an HSM or separate key directory, never in the zone directory
9. Using Algorithm 5 (RSA/SHA-1) for New DNSSEC Keys¶
SHA-1 is cryptographically broken. Several major validators have stopped accepting Algorithm 5 DNSSEC signatures. A zone signed with Algorithm 5 may silently fail validation on modern resolvers.
Fix: Use Algorithm 13 (ECDSA P-256/SHA-256) for new zones — smaller keys, faster verification, modern security. Algorithm 15 (Ed25519) is also excellent where supported. Check existing key algorithm:
dig DNSKEY example.com | awk '{print $5}'
# 5 = RSA/SHA-1 (vulnerable, upgrade needed)
# 8 = RSA/SHA-256 (acceptable)
# 13 = ECDSA P-256 (recommended)
# 15 = Ed25519 (recommended)
If you find Algorithm 5, perform a key rollover to Algorithm 13.
10. Split-Horizon Zone Leaking to External Resolvers¶
Your internal zone corp.example.com has an AXFR restriction, but a misconfigured firewall rule allows UDP port 53 from the internet to your internal authoritative server. Or your recursing resolver is exposed to the internet and returns internal zone records. Attackers learn your internal hostnames, IP ranges, and infrastructure layout.
Fix:
- Internal authoritative servers must not be reachable from the internet on port 53
- Recursing resolvers must only serve the networks they are intended for (allow-query { 10.0.0.0/8; };)
- Test for external leakage: dig A internal.corp.example.com @<your-public-ip>
11. Trusting DoT Without Certificate Validation¶
Configuring DNS-over-TLS but disabling certificate validation (tls-no-verify) defeats the purpose. You're encrypting the channel but not authenticating who you're talking to. A MITM attacker can present their own certificate and intercept all DNS queries.
Fix: Always validate the TLS certificate when using DoT:
kdig @1.1.1.1 +tls-ca example.com A # validates against system CA store
# or specify a pinned cert:
kdig @1.1.1.1 +tls-pin=<base64-hash> example.com A
For Unbound, configure tls-cert-bundle and auth-zone to validate the resolver's identity.
12. Not Testing DNSSEC After Every Zone Change¶
You add a new A record to your zone. The inline signer processes it but you don't verify. The new record was added, but a bug in the signing workflow left the RRSIG for the A record pointing at the wrong key tag. Resolvers return SERVFAIL only for that specific record, which goes unnoticed until a monitoring check fires.
Fix: After every zone change, run a targeted validation check:
# Check that the new record is signed and valid
dig +dnssec A newhost.example.com
# Must return the A record AND a valid RRSIG
# The AD flag must be set on a validating resolver
# Full zone integrity check
dnssec-verify -o example.com /etc/bind/zones/example.com.zone.signed
Add a post-deployment test to your change management workflow.