5 min read #networking #DNS
On this page

DNSSEC and DNS Security

DNS was not designed with security in mind—DNSSEC adds a "non-repudiable" proof to every DNS record using a chain of digital signatures. It does not encrypt (DNS over HTTPS handles encryption); it prevents tampering—the cost being the maintenance of the signature chain and the amplification effect on related domains.

Overview

Traditional DNS lacks cryptographic protection: any intermediate node can forge responses (DNS spoofing). DNSSEC does not encrypt queries; instead, it signs each DNS record, forming a chain of trust from the root to the target domain. A resolver can verify that "this A record was indeed issued by the authoritative server for example.com." The cost is larger response packets (RRSIG records) and more complex zone management (KSK/ZSK rotation). DNSSEC deployment is approximately 30% (as of 2024), partly because it does not address privacy issues—hence the need for DoH/DoT as supplements.

Problem: DNS Lacks Authentication

Traditional DNS responses have no cryptographic guarantees. Attackers can:

  1. Cache Poisoning: Send forged referrals/glue records → recursive resolver caches poisoned RRs
  2. Man-in-the-Middle Attacks: Forge DNS responses along the path → client receives fake IPs

DNSSEC solves this: sign each zone → form a chain of trust from root to leaf → resolver can verify step-by-step.

Note: DNSSEC does not encrypt queries (encryption = DoH/DoT/DoQ). Users are still exposed to: "ISP sees what domain names you queried."

Record Types

RRSIG (type 46):
  Signature for a set of RRsets (not signed individually per RR!)
  
  RDATA:
    Type Covered (2B): The RR type being signed
    Algorithm (1B): 5=RSA/SHA1 (deprecated), 7=RSASHA1-NSEC3-SHA1, 8=RSA/SHA-256,
                    10=RSA/SHA-512, 13=ECDSA-P256-SHA256, 14=ECDSA-P384-SHA384,
                    15=ED25519, 16=ED448
    Labels (1B): Number of labels in the original owner name
    Original TTL (4B): Original TTL (not the RRSIG's own TTL!)
    Signature Expiration (4B): Signature expiration time (Unix timestamp)
    Signature Inception (4B): Signature inception time
    Key Tag (2B): Numeric tag used to identify the DNSKEY
    Signer's Name (label format): The zone that produced this signature (usually the zone's apex)
    Signature (variable): The actual signature (of the canonical form of the RRset)

DNSKEY (type 48):
  Zone public key used to verify RRSIGs

  RDATA:
    Flags (2B):
      bit 7 (Zone Key): 1 → This key is used for DNSSEC
      bit 15 (Secure Entry Point): 1 → KSK (Key Signing Key),
        0 → ZSK (Zone Signing Key)
    Protocol (1B): Always 3
    Algorithm (1B): Same as RRSIG Algorithm
    Public Key (variable)

DS (type 43):
  Hash of the KSK, stored in the parent zone → forms a cross-zone trust chain

  RDATA:
    Key Tag (2B): Matches the DNSKEY's key tag
    Algorithm (1B): Same as DNSKEY
    Digest Type (1B): 1=SHA-1 (deprecated), 2=SHA-256, 4=SHA-384
    Digest (variable): SHA-256(owner name + DNSKEY RDATA)

NSEC (type 47): Authenticated denial of existence
  → "example.org A? — Not only does it not exist, but it can prove it doesn't exist"

Trust Chain Verification

Resolver starts with: root DNSKEY hash (trust anchor, pre-installed in resolver)

Querying www.example.com A:
  1. Receive A record + RRSIG (signer=example.com)
  2. Query example.com DNSKEY → Verify RRSIG using DNSKEY → OK (zone-level trust)
  3. Query .com zone: DS (example.com) + RRSIG (signer=.com)
  4. Query .com DNSKEY → Verify DS's RRSIG → OK → DNSKEY hash matches DS → OK
  5. Query root zone: DS (.com) + RRSIG → root DNSKEY → trust anchor match → OK
  → Complete trust chain: root → .com → example.com → www.example.com

Key Signing Key (KSK) vs Zone Signing Key (ZSK):
  KSK: Signs only the DNSKEY RRset — Long key (2048-bit RSA), changed infrequently (1-2 years)
  ZSK: Signs all RRsets in the zone — Short key (1024-bit RSA or ECDSA), changed frequently (monthly)
  → Reason for separating KSK/ZSK: ZSK rotates frequently (DNSSEC signatures need frequent updates), but changing KSK
    requires updating the DS in the parent zone → Parent zone operation + propagation delay

NSEC3 (RFC 5155)

Problem with NSEC: Enumerates all existing names in a zone (traversing the NSEC chain → returns next name)

NSEC3: Hashes the owner name before proving nonexistence:

NSEC3 record:
  Hash Algorithm (1): SHA-1
  Flags (1): Opt-Out (bit 0)
  Iterations (2): Hash iterations (0-65535, high iterations = DoS risk)
  Salt Length + Salt: Per-zone salt
  Hash Length + Hash (next hashed owner name)
  Type Bit Maps: Same as NSEC

→ Traversing the NSEC3 chain only shows "hashed_abc → hashed_def" → Cannot directly enumerate the zone
  (Still possible to brute-force offline; NSEC3 only increases the cost)

DANE (RFC 6698)

Replaces CA (Certificate Authority) for providing trust in TLS certificates:

TLSA record (_port._protocol.name):
  port: 443, 25, ...
  protocol: _tcp, _udp, ...

  RDATA:
    Cert Usage (1B):
      0: CA constraint (PKIX-TA)
      1: Service certificate constraint (PKIX-EE)
      2: Trust anchor assertion (DANE-TA) — Specifies your own CA
      3: Domain-issued certificate (DANE-EE) — Directly specifies the certificate or public key of this endpoint → Maximum security!
    Selector (1B): 0=full certificate, 1=SubjectPublicKeyInfo (public key only)
    Matching Type (1B): 0=exact, 1=SHA-256, 2=SHA-512
    Certificate Association Data: Hash or exact cert/pubkey

  Verification: Client receives TLS certificate → Queries TLSA record → Does hash match? → Trust
  → No need for PKI/CA, no need for CT logs; certificate validity depends solely on DNSSEC signatures
  → Problem: Current adoption is nearly zero (browsers do not support it)

References

  • RFC: 4033-4035, 5155, 6698, 6840 (DNSSEC algorithm updates)
  • Tools: dig +dnssec, delv @resolver, dnsviz.net

Keywords: DNSSEC, RRSIG, DNSKEY, DS, NSEC, NSEC3, DANE, trust anchor, zone signing, KSK, ZSK