Frontend Labs
⋯

Chapter 38 — DNS security

In one sentence

DNS was designed with no authentication, so an attacker who can answer (or guess) a query controls where your traffic goes — and the fixes are DNSSEC (authenticate the data) and DoH/DoT (encrypt the transport).

How a lookup works, and where it's attackable

   your app -> STUB RESOLVER (OS) -> RECURSIVE RESOLVER (ISP / 1.1.1.1 /
               8.8.8.8 / your own) -> ROOT -> TLD (.op) -> AUTHORITATIVE
               (securesh.op's nameserver) -> answer flows back and is CACHED
               at the recursive resolver for the TTL.

   ATTACK SURFACE:
     [1] stub <-> recursive : on-path sniff/spoof; rogue DHCP sets a
                              malicious resolver; malware edits /etc/resolv.conf
     [2] recursive <-> auth : off-path CACHE POISONING (spoof the answer
                              before the real one arrives)
     [3] the recursive's cache itself, or a compromised resolver
     [4] the registrar / registry account -> DOMAIN HIJACK (change the NS
         records; game over, and it happens regularly)
     [5] the authoritative server or its zone file

Cache poisoning and the Kaminsky attack (2008)

   A spoofed DNS response is accepted if it matches:
     - the 16-bit TRANSACTION ID
     - the source/dest IP and PORT
     - the question

   Classic attack: guess the 16-bit ID (65,536 values) while the resolver
   waits for an answer. Kaminsky's insight: you don't have to win once for
   one name -- query aaa.bank.com, bbb.bank.com, ... and each attempt is a
   fresh race, and a winning spoof can inject a poisoned NS record for the
   WHOLE zone. Suddenly feasible.

   MITIGATION (deployed 2008, still essential, NOT a real fix):
     * randomise the SOURCE PORT too  -> ~32 bits of entropy
     * 0x20 encoding (randomise query-name case)
     * these make it HARDER, not impossible. DNSSEC is the actual fix.

DNSSEC — authenticating the answers

DNSSEC signs DNS records so a resolver can verify they're genuine and unmodified.

   Each zone signs its records (RRSIG) with a private key. The public key
   (DNSKEY) is vouched for by a hash (DS record) in the PARENT zone, which
   is itself signed... up to the ROOT, whose key is a well-known trust
   anchor (and whose rotation is a globally-televised ceremony).

     . (root, trust anchor)
       signs DS for  .op
         .op signs DS for  securesh.op
           securesh.op signs its own A / MX / TXT ... records

   A VALIDATING resolver rejects answers that fail the chain -> cache
   poisoning and on-path answer forgery stop working.

What DNSSEC does and doesn't do:

   DOES:  data-origin authentication + integrity for DNS records.
          Authenticated denial of existence (NSEC/NSEC3): "that name
          really doesn't exist" is provable.
   DOES NOT: encrypt anything (queries/answers are still public --
             that's DoH/DoT's job).
   DOES NOT: protect the stub <-> recursive hop unless that hop also
             validates and you trust it (or you validate locally).
   COSTS:  key management, signing, larger responses (UDP fragmentation,
           amplification-DDoS potential), operational foot-guns (an
           expired RRSIG = your domain vanishes for validating resolvers).
   ADOPTION: patchy. Most TLDs signed; a minority of second-level domains.

DNSSEC also enables DANE (TLSA records: "here's the exact cert my mail server uses") — widely used to secure SMTP between mail servers, rarely for the web (browsers didn't adopt it; they rely on the CA/CT system instead).

Encrypted DNS transport: DoT and DoH

   Plain DNS (port 53, UDP/TCP): everyone on-path sees every name you
   resolve, and can tamper (if not DNSSEC-validated).

   DoT  -- DNS over TLS, port 853. Dedicated port -> easy to see "DNS is
           happening" and to block, but content is encrypted.
   DoH  -- DNS over HTTPS, port 443. Looks like normal web traffic ->
           hard to block or distinguish; also usable from inside browsers.
   DoQ  -- DNS over QUIC, port 853. DoT's benefits without head-of-line
           blocking.

   These hide your queries from the LOCAL network and your ISP, moving
   that visibility to your chosen resolver (Cloudflare, Google, Quad9,
   NextDNS, or your own). Trade-off: you must trust that operator, and
   enterprises lose DNS-based filtering/visibility (hence "enterprise
   DoH" controls and DDR/DNR discovery).

DNSSEC and DoH/DoT are complementary: DNSSEC = is this answer authentic? DoH/DoT = who got to watch me ask? Ideally both.

Domain-level hygiene (the boring stuff that prevents disasters)

   [ ] Registrar account: unique password + phishing-resistant MFA;
       REGISTRY LOCK (a manual, out-of-band step to change NS/transfer) --
       this alone stops most domain hijacks.
   [ ] CAA records (Ch 30) so only your CA can issue certs.
   [ ] SPF, DKIM, DMARC (p=reject) so nobody spoofs your email domain;
       MTA-STS + TLS-RPT for inbound mail transport security.
   [ ] Watch for dangling records: a CNAME to a decommissioned S3
       bucket / Heroku app / Azure resource -> SUBDOMAIN TAKEOVER.
       Inventory and prune DNS regularly.
   [ ] Separate, minimal-privilege accounts for DNS management; audit logs.
   [ ] Monitor: alerts on any NS / MX / DS / A change to your zones;
       external checks that your domain still resolves and validates.
   [ ] DNSSEC if your registrar/DNS host supports easy signing + managed
       key rollover. If they don't automate it, the operational risk may
       outweigh the benefit -- decide deliberately.

Practice (35 min)

# 1. Trace a resolution and see the hierarchy
dig +trace securesh.op          # root -> TLD -> authoritative
dig +norecurse @a.root-servers.net NS op.    # ask root directly

# 2. Inspect DNSSEC
dig +dnssec cloudflare.com A                 # look for the RRSIG records
dig DS cloudflare.com                        # the delegation hash in the parent
dig +dnssec dnssec-failed.org A              # a deliberately-broken domain

# 3. Validate the chain explicitly
delv cloudflare.com A                        # "fully validated" (needs a
                                             # crypto-capable delv build;
                                             # macOS's may say "no crypto support"
                                             # -- another Ch 0.4 trap; use Linux
                                             # or `dig +sigchase`, or unbound-host)

# 4. See a poisoning mitigation in action: source-port randomisation
sudo tcpdump -i any -n 'udp port 53' -c 10 &
for i in 1 2 3 4 5; do dig +short example$i.com; done
sudo pkill tcpdump
#   note the SOURCE port differs every query -- that's the anti-Kaminsky entropy.

# 5. Encrypted DNS
kdig -d @1.1.1.1 +tls-ca +tls-host=cloudflare-dns.com example.com  # DoT (knot-dnsutils)
curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=example.com&type=A'    # DoH (JSON)

# 6. Check your domain's email + CAA posture
dig +short TXT example.com | grep -i spf
dig +short TXT _dmarc.example.com
dig +short CAA example.com

# 7. Subdomain-takeover sweep (your domains only): list CNAMEs and check
#    each target still exists
dig +short CNAME assets.example.com

Mini-project (45 min): DNS + domain monitor

   A script (cron, every 15 min) that for each zone you own:
     1. Resolves NS, MX, DS, SOA, and key A/AAAA records.
     2. Diffs against a committed baseline; alerts loudly on any change.
     3. Runs `delv` / a validating query and alerts if DNSSEC validation
        fails (expired RRSIG is a classic 2 a.m. incident).
     4. For every CNAME, checks the target resolves (dangling -> takeover
        risk).
     5. Confirms CAA, SPF, and DMARC records are present and unchanged.
   Output: OK / WARN / CRIT, exit codes for your monitoring system.

Common confusions

  • "DNSSEC encrypts my DNS." No. It authenticates records. Encryption is DoH/DoT/DoQ. You want both.
  • "I use 1.1.1.1 so my DNS is secure." It encrypts stub→resolver and 1.1.1.1 validates DNSSEC for you — but you're now trusting Cloudflare to see every name you look up, and the answer's authenticity still depends on the zone being signed.
  • "DNS over HTTPS is always more private." More private from the local network; less private from the DoH provider, and it can bypass enterprise security controls. Context matters.
  • "Cache poisoning was fixed in 2008." Source-port randomisation made it hard. Researchers keep finding side channels (SAD DNS, 2020/2021). DNSSEC is the durable fix.
  • "My domain can't be hijacked, I have a strong password." Registrar-account phishing and social-engineering the registrar are the common paths. Registry Lock is the control.

Check yourself

  1. Name three points in the DNS resolution path where an attacker can interfere.
  2. What made the Kaminsky attack powerful, and what mitigations were deployed (and why aren't they a true fix)?
  3. What does DNSSEC provide, and name two things it does not do.
  4. DoT vs DoH — the port, and the practical trade-off between them.
  5. What is Registry Lock and which attack does it stop?
  6. What is a dangling DNS record and what attack does it enable?

Further reading

  • Book: DNS and BIND (5th ed.) for fundamentals; DNSSEC Mastery (2nd ed.), Michael W. Lucas, for the signing side.
  • Article: "An Illustrated Guide to the Kaminsky DNS Vulnerability" (unixwiz.net) — the classic explainer. Plus "SAD DNS" (UC Riverside, 2020) for the modern revival.
  • Docs: Cloudflare Learning Center "DNSSEC" and "DNS over HTTPS" pages; RFC 4033-4035 (DNSSEC), RFC 8484 (DoH), RFC 7858 (DoT).
  • Tool: dnsviz.net — visualises a domain's DNSSEC chain and flags problems.
  • Guidance: ICANN's Registry Lock explainer; the CISA "Emergency Directive 19-01" on DNS infrastructure tampering (a real campaign, well documented).

Generated from real-life-guide.md · 8 Oct 2026 16:36