DNS Security & DNSSEC
DNSSEC adds a cryptographic chain of trust from the DNS root to individual records, letting resolvers verify that responses have not been forged or tampered with.
The Problem
DNS was designed without authentication — a resolver cannot verify responses actually came from the authoritative server.
Mental Model
Like certified mail vs regular mail — regular DNS is an unsigned postcard anyone can forge, DNSSEC adds cryptographic signatures proving the response is authentic.
Architecture Diagram
How It Works
DNS is the first thing that happens on every internet connection, and it was designed in 1983 with zero authentication. A recursive resolver sends a query, receives a response, and blindly trusts that the response is legitimate. Nothing in the protocol prevents a man-in-the-middle from forging a response. DNSSEC fixes this by adding cryptographic signatures to DNS records, and DoH/DoT fix the privacy half by encrypting the query channel.
The Cache Poisoning Problem
DNS cache poisoning exploits one fundamental weakness: resolvers have no way to distinguish a legitimate response from a forged one. The attack is mechanical — an attacker races the authoritative server to deliver a response to the resolver. If the forged response arrives first with the correct transaction ID and source port, the resolver caches it and serves the fake record to every client for the duration of the TTL.
Before 2008, most resolvers used predictable source ports, making the attack trivially easy. Dan Kaminsky demonstrated that an attacker could poison a resolver's cache in under 10 seconds by flooding it with forged responses referencing attacker-controlled name servers. The fix — source port randomization — raised the entropy from 16 bits to roughly 32 bits, but a determined attacker with sufficient bandwidth can still brute-force the combined space.
The Kaminsky attack targeted the "bailiwick" rule's interaction with glue records. Instead of trying to spoof the target domain directly, the attacker queries for random nonexistent subdomains (aaa.example.com, aab.example.com) and includes forged authority records delegating example.com to an attacker-controlled name server. Each query is a fresh attempt since the random subdomain bypasses caching.
# Check if a resolver uses randomized source ports
dig +short porttest.dns-oarc.net TXT
# Response should indicate "GREAT" randomness
# Test source port entropy with dnstop or tcpdump
tcpdump -i eth0 port 53 -nn | awk '{print $3}' | cut -d. -f5 | sort -u | wc -l
DNSSEC Chain of Trust
DNSSEC does not encrypt DNS traffic. It adds digital signatures to DNS responses so a validating resolver can prove three things:
- The response came from the authoritative server for that zone
- The data has not been modified in transit
- The response is not a replay of a stale record
The chain of trust mirrors the DNS delegation hierarchy:
Root Zone. The DNS root zone is signed with a Key Signing Key (KSK) whose public key is distributed as a trust anchor — hardcoded into every validating resolver. The root KSK ceremony, conducted in physically secured facilities with multiple trusted community representatives, is one of the most carefully audited processes in internet infrastructure. The 2018 root KSK rollover from KSK-2010 to KSK-2017 was the first and only time this key has been changed.
TLD Delegation. The root zone publishes a DS (Delegation Signer) record for each signed TLD. The DS record contains a hash of the TLD's DNSKEY. When a resolver validates .com records, it fetches the DS record from the root, fetches the DNSKEY from .com, and verifies the hash matches.
Zone Delegation. The TLD publishes a DS record for each signed domain. The pattern repeats: DS in parent → DNSKEY in child → verify hash → trust established. This is the critical handoff point where most deployment failures occur — the DS record in the parent must exactly match the hash of the child's KSK.
Record Validation. The authoritative server for example.com signs each record set with its Zone Signing Key (ZSK) and publishes the signature as an RRSIG record alongside the actual data. The resolver fetches the DNSKEY, verifies the RRSIG, then walks the DS chain up to the root trust anchor.
# Walk the full DNSSEC chain
dig +dnssec +multi example.com A
# Verify the DS chain manually
dig DS example.com @a.gtld-servers.net # DS in .com TLD
dig DNSKEY example.com # Zone's public keys
# The DS record's digest should match the hash of the KSK in the DNSKEY set
KSK vs ZSK — Operational Split
| Key | Flag | Signs | Rollover Frequency | Parent Interaction |
|---|---|---|---|---|
| KSK (Key Signing Key) | 257 | Only the DNSKEY RRset | Annually or less | DS record must be updated in parent |
| ZSK (Zone Signing Key) | 256 | All other record sets | Monthly or quarterly | No parent interaction needed |
The split exists for operational reasons. ZSK rotation is routine — generate a new key, pre-publish it, sign with both keys during overlap, remove the old key. KSK rotation requires coordinating with the parent zone's operator to update the DS record, which introduces a dependency on an external party and a window where misconfiguration causes total failure.
DNSSEC Record Types
| Record | Purpose | Contents |
|---|---|---|
| RRSIG | Signature over a record set | Algorithm, expiration, inception, key tag, signer name, signature |
| DNSKEY | Zone's public keys | Flags (KSK=257, ZSK=256), algorithm, public key material |
| DS | Delegation signer in parent zone | Key tag, algorithm, digest type, digest of child's DNSKEY |
| NSEC | Authenticated denial of existence | Next domain name in zone, list of record types that exist |
| NSEC3 | Hashed denial of existence | Same as NSEC but with hashed names to prevent zone enumeration |
Authenticated Denial of Existence
How does a resolver verify that a domain does not exist? Without DNSSEC, an attacker could forge NXDOMAIN responses to block access to legitimate domains. NSEC records solve this by listing the "next" domain name in canonical order, proving there is nothing between two names.
NSEC enables zone walking — an attacker can enumerate every record in the zone by following the NSEC chain. NSEC3 addresses this by hashing domain names before ordering them. The resolver receives hashed names and can verify the requested name falls in a gap without learning other names in the zone. NSEC3 remains vulnerable to offline dictionary attacks against common names, but it eliminates trivial enumeration.
# See NSEC3 records for a nonexistent domain
dig +dnssec nonexistent.example.com
# The response includes NSEC3 records proving no record exists between two hashed names
DNS Encryption: DoH and DoT
DNSSEC solves authentication but not privacy. Even with DNSSEC, every query and response travels in plaintext. Any entity on the network path — ISP, corporate firewall, nation-state — can observe every domain being resolved.
DNS-over-TLS (DoT)
DoT wraps DNS queries in a TLS connection on port 853. The resolver authenticates using a TLS certificate, and the query/response exchange is encrypted. Straightforward, but the dedicated port makes it trivial for network operators to detect and block.
DNS-over-HTTPS (DoH)
DoH encapsulates DNS queries inside standard HTTPS POST or GET requests on port 443. From a network perspective, DoH traffic is indistinguishable from regular web traffic. Blocking it requires either blocking all HTTPS traffic to the resolver's IP address or deep packet inspection with SNI analysis.
# DoH query to Cloudflare
curl -s -H 'Accept: application/dns-json' \
'https://1.1.1.1/dns-query?name=example.com&type=A' | jq .
# DoT query using kdig
kdig -d @1.1.1.1 +tls-ca +tls-host=cloudflare-dns.com example.com
DoH vs DoT Trade-offs
| Aspect | DoH | DoT |
|---|---|---|
| Port | 443 (shared with HTTPS) | 853 (dedicated) |
| Blockability | Very hard to block selectively | Easy to block by port |
| Overhead | HTTP/2 framing adds bytes | Minimal TLS overhead |
| Debugging | Harder to inspect in packet captures | Standard TLS on known port |
| Adoption | Chrome, Firefox, Windows, iOS | Android, systemd-resolved, Unbound |
Enterprise networks often need DNS visibility for security monitoring — detecting C2 callbacks, data exfiltration via DNS tunnels, DGA domains. DoH undermines that visibility. The operational pattern for enterprises: deploy a local validating resolver (Unbound or BIND) that validates DNSSEC, serves clients over DoH/DoT internally, and logs queries for security analysis while blocking external DoH endpoints at the firewall.
Why Adoption Remains Low
Despite standardization in 2005, DNSSEC adoption hovers around 25-30% of domains globally. The barriers are operational, not theoretical.
Operational complexity. DNSSEC requires managing cryptographic keys, scheduling re-signing before RRSIG expiration, coordinating DS record updates with the parent zone, and planning key rollovers with zero-downtime overlap periods. A single mistake — an expired signature, a mismatched DS record, a botched rollover — causes a complete outage.
DNSSEC amplifies failure modes. Without DNSSEC, a misconfigured zone returns wrong answers — bad, but the site loads. With DNSSEC, a misconfigured zone returns SERVFAIL — total blackout. The incentive structure punishes deployment.
Response size inflation. DNSSEC responses are 3-5x larger than unsigned responses due to RRSIG and DNSKEY records. This increases bandwidth, amplifies DDoS reflection potential, and can cause UDP fragmentation issues that trigger TCP fallback.
Registrar friction. Submitting DS records to the parent zone requires registrar support. Many registrars have clunky or nonexistent DNSSEC workflows. CDS/CDNSKEY records (RFC 7344) allow automated DS maintenance, but registrar adoption of this automation remains inconsistent.
Deploying DNSSEC in Practice
For authoritative zones, the modern approach is managed signing. Cloudflare, AWS Route 53, and Google Cloud DNS handle key generation, zone signing, key rotation, and DNSKEY publication. The only manual step is the initial DS record submission to the registrar.
For resolvers, enable DNSSEC validation in Unbound or use a public resolver (1.1.1.1 or 8.8.8.8) that validates by default. Test with deliberately broken domains:
# This domain has a deliberately broken DNSSEC signature
dig @1.1.1.1 dnssec-failed.org
# Should return SERVFAIL (validation failure)
# Same query with validation disabled
dig +cd @1.1.1.1 dnssec-failed.org
# Should return the A record (bypassing validation)
# Check DNSSEC status of any domain
dig +dnssec +short example.com
The complete solution combines DNSSEC (authentication) with DoH or DoT (encryption). Neither alone is sufficient. DNSSEC without encryption means eavesdroppers see every query in cleartext. DoH without DNSSEC means encrypted responses might still be forged at the authoritative or upstream level. Both layers together provide authenticated, private DNS resolution.
Key Points
- •DNSSEC adds cryptographic authentication to DNS responses but does NOT encrypt them — it proves the answer is genuine, not that it is private
- •The chain of trust flows from root (.) → TLD (.com) → zone (example.com) using DS records at each delegation point
- •DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT) encrypt queries for privacy but do not authenticate responses — DNSSEC and DoH/DoT solve orthogonal problems
- •The Kaminsky attack (2008) demonstrated that DNS cache poisoning could be performed in seconds by exploiting predictable transaction IDs and source ports
- •DNSSEC adoption remains below 30% of domains despite being standardized in 2005 — key management complexity and DNSSEC-induced outages are the primary barriers
Key Components
| Component | Role |
|---|---|
| RRSIG Record | A cryptographic signature over a DNS record set — the resolver uses this to verify the record has not been tampered with since the authoritative server signed it |
| DNSKEY Record | The public key published in DNS that resolvers use to verify RRSIG signatures for a given zone |
| DS Record | A hash of the child zone's DNSKEY stored in the parent zone — the glue that builds the chain of trust from root to leaf |
| NSEC/NSEC3 Record | Authenticated denial of existence — proves that a queried name does NOT exist, preventing attackers from injecting fake NXDOMAIN responses |
| Trust Anchor | The root zone's public key, hardcoded into resolvers — the starting point for validating the entire DNSSEC chain of trust |
When to Use
Enable DNSSEC validation on every recursive resolver. Sign zones with DNSSEC when the registrar and DNS provider support it. Deploy DoH or DoT for client-to-resolver privacy. The combination of DNSSEC + DoH covers both authentication and encryption.
Tool Comparison
| Tool | Type | Best For | Scale |
|---|---|---|---|
| Cloudflare DNS (1.1.1.1) | Managed | Fastest public resolver with automatic DNSSEC validation, DoH, and DoT support out of the box | Global anycast, sub-15ms median |
| Google Public DNS (8.8.8.8) | Managed | Widely trusted public resolver with full DNSSEC validation and both DoH and DoT endpoints | Global, handles trillions of queries |
| Unbound | Open Source | Lightweight validating recursive resolver ideal for local DNSSEC validation and privacy-focused setups | Small to Enterprise |
| BIND | Open Source | Full-featured authoritative and recursive server with comprehensive DNSSEC signing and validation support | Runs root servers and large ISPs |
Debug Checklist
- Run dig +dnssec example.com to check if RRSIG records are returned alongside the answer
- Use delv example.com to perform a full DNSSEC validation walk and see exactly where the chain breaks
- Check DS record alignment: dig DS example.com @parent-ns must match the hash of the zone's KSK
- Verify signature expiration: RRSIG records have inception and expiration timestamps — expired signatures cause SERVFAIL
- Test resolver behavior: dig +cd example.com (checking disabled) bypasses validation — if this works but normal dig fails, DNSSEC is the issue
Common Mistakes
- Confusing DNSSEC with DoH/DoT. DNSSEC authenticates responses (integrity). DoH/DoT encrypt queries (privacy). They are complementary, not alternatives.
- Letting DNSSEC signatures expire. RRSIG records have explicit expiration dates — if the zone is not re-signed on schedule, resolvers reject every response as BOGUS.
- Not monitoring DNSSEC validation failures. When a resolver marks a domain as BOGUS, clients get SERVFAIL — indistinguishable from a total DNS outage without specific monitoring.
- Deploying DNSSEC without a key rollover plan. KSK rollovers require updating the DS record in the parent zone — botching this breaks the entire chain of trust.
- Assuming DNSSEC protects the last mile. DNSSEC validates the path from authoritative server to resolver, but the hop from resolver to client is unprotected without DoH/DoT.
Real World Usage
- •Cloudflare validates DNSSEC on 100% of queries through 1.1.1.1 and reports that approximately 25% of .com domains are now signed
- •Google Public DNS has performed DNSSEC validation since 2013 and publishes detailed telemetry on validation failure rates across TLDs
- •Verisign signs the .com and .net TLD zones and operates two of the thirteen root name servers with full DNSSEC
- •Comcast was one of the first large ISPs to enable DNSSEC validation for all residential customers in 2012