Skip to content
yutils

How DNS Actually Works

Walk through a DNS query — root server, TLD, authoritative resolver, recursive resolver, TTL caching, the A/AAAA/CNAME/MX record zoo, and why DNS-over-HTTPS exists.

~9 min read

Type github.com in the browser — within milliseconds the IP 140.82.114.4 comes back. What happens in between? DNS resolves names through a four-step hierarchical lookup: root → TLD → authoritative server → resolver. Add TTL caching and the move to DNS-over-HTTPS, and DNS gets interesting. This guide walks the internals.

The DNS hierarchy

.                                ← root (the trailing dot, usually omitted)
├── com.                         ← TLD (top-level domain)
│   ├── github.                  ← second level
│   │   └── (A record: 140.82.114.4)
│   ├── google.
│   └── ...
├── kr.
│   ├── co.kr.
│   │   └── naver.co.kr.
│   ├── or.kr.
│   └── go.kr.
├── org.
│   ├── wikipedia.
│   └── ...
└── ...

Domain names are a tree, read right-to-left. In www.github.com. the trailing dot is root, com is TLD, github is the second level, www is the host.

A single query — four steps

User: what's the IP of github.com?
                ↓
Browser → OS resolver (/etc/resolv.conf)
                ↓
OS → ISP's recursive resolver (e.g. 168.126.63.1 KT, or 1.1.1.1)
                ↓
The recursive resolver does:

1. Ask a root server
   "who is responsible for .com?"
   ↓
   One of the 13 root servers (a-m.root-servers.net)
   ↓
   Reply: "com's nameserver = a.gtld-servers.net"

2. Ask the .com TLD server
   "who is responsible for github.com?"
   ↓
   Reply: "github.com's nameserver = ns-1283.awsdns-32.org"

3. Ask the authoritative server
   "what's github.com's A record?"
   ↓
   Reply: "A 140.82.114.4 TTL=60"

4. Recursive resolver replies to the user
   "140.82.114.4"

The recursive resolver does the heavy lifting; the client asks once. That split is what makes DNS caching effective.

Recursive vs authoritative

  • Authoritative — the "official" source for a specific zone (like github.com). Operated by the domain owner.
  • Recursive resolver — follows queries from client all the way to authoritative. Run by ISPs, Cloudflare (1.1.1.1), Google (8.8.8.8), or your company's network.

Recursive resolvers cache responses, so the second query is instant.

Record types — the essential nine

TypePurposeExample
AIPv4 addressgithub.com → 140.82.114.4
AAAAIPv6 address ("quad-A")github.com → 2a01:4f8::1
CNAMEAlias to another namewww.example.com → example.com
MXMail serverexample.com → mail.example.com (priority 10)
TXTArbitrary text (SPF, DKIM, verification)"v=spf1 include:_spf.google.com ~all"
NSNameservers for this zoneexample.com NS ns1.example.com
SOAZone metadata (serial, TTL, etc.)SOA ns1.example.com hostmaster... 2024010101
SRVService location (port / priority / weight)_sip._tcp.example.com → 10 60 5060 sip.example.com
CAAAllowed CA(s) for cert issuanceexample.com CAA 0 issue "letsencrypt.org"
PTRReverse lookup (IP → domain)4.114.82.140.in-addr.arpa → github.com

TTL — the caching dial

Every record carries a TTL (in seconds) — how long resolvers may cache the answer:

github.com.  60     IN   A   140.82.114.4
              │
              └─ TTL = 60s, then re-query

Trade-off:

  • Low TTL (60s) — changes propagate fast, but more lookups
  • High TTL (86400 = 24h) — fewer lookups, slower to change

Operational pattern:

  • Regular A records: 300-3600 (5 min - 1 hour)
  • Lower TTL to ~60 before a planned migration
  • Stable records (NS): 86400

CNAME gotchas

www.example.com.   CNAME  example.com.
example.com.       A      203.0.113.5

That's fine — www → example.com → real IP.

Restrictions:

  • No CNAME at the apexexample.com itself can't be a CNAME. It would collide with MX / NS / SOA.
  • Route 53 ALIAS / Cloudflare ANAME flattening offer the same effect at the apex
  • CNAME chains are allowed but stay shallow (1-2 hops)

MX records — mail routing

example.com.  MX  10  mail1.example.com.
example.com.  MX  20  mail2.example.com.
                │
                └─ priority. lower = tried first.

mail1 down → fall back to mail2.

SPF / DKIM / DMARC also live in TXT:

SPF:    "v=spf1 include:_spf.google.com ~all"
DKIM:   selector._domainkey.example.com TXT "v=DKIM1; p=...."
DMARC:  _dmarc.example.com TXT "v=DMARC1; p=reject"

DNS over UDP, TCP, HTTPS

  • UDP port 53 by default — queries are small, no connection overhead
  • Falls back to TCP for responses > 512 bytes — UDP packet limit. DNSSEC responses trigger this.
  • DNS-over-HTTPS (DoH, RFC 8484) — DNS over HTTPS. Prevents plaintext UDP eavesdropping / spoofing. Firefox / Chrome / 1.1.1.1 / 8.8.8.8 support it.
  • DNS-over-TLS (DoT, port 853) — DNS over TLS. Similar to DoH on a separate port.

DNSSEC — defense against spoofing

Plaintext DNS lets the ISP, your café Wi-Fi, or anyone in the path forge responses. github.com queries get the attacker's IP instead of GitHub's.

DNSSEC signs every response:

github.com.  A      140.82.114.4
github.com.  RRSIG  A 13 2 60 ...signature...

Resolver verifies the signature:
  Fetch github.com's DNSKEY (public key)
  Verify
  Failure → respond SERVFAIL

Adoption is slow — complicated to run, easy to break. .gov / .mil and some EU mandates push it. Public domain coverage sits around 10%.

DNS debugging tools

dig github.com           # default A record
dig github.com AAAA      # IPv6
dig github.com MX        # mail server
dig +trace github.com    # full hierarchy trace
dig @8.8.8.8 github.com  # ask a specific resolver

# Windows
nslookup github.com
nslookup -type=MX example.com

# Web tools
https://www.whatsmydns.net/   ← global propagation check

After a DNS change — wait the TTL, then check from multiple regions. whatsmydns.net queries 50+ resolvers simultaneously.

Common pitfalls

1. Stale DNS cache

OS, browser, and ISP each cache independently. Even after the TTL passes, some caches lag. ipconfig /flushdns (Win), sudo dscacheutil -flushcache (Mac).

2. CNAME at the apex

Trying to CNAME example.com itself violates DNS rules. Use Route 53 ALIAS or Cloudflare CNAME flattening.

3. NS / A mismatch

# Registrar configures NS:
example.com NS ns1.cloudflare.com.

# But the Cloudflare zone has no A record for example.com
→ "DNS resolution failed"

Registrar NS settings have to match nameserver zone data — especially around transfers.

4. TTL traps

You lowered TTL to 60 before a migration, but downstream caches still hold the old longer TTL → some users see the old IP for days. Lowering TTL needs its own propagation window first.

5. SPF over-include

SPF allows at most 10 lookups (include depth). Stack too many include: entries and you hit PermError. Carriers silently drop the mail.

References

Summary

  • DNS = domain → IP, via a hierarchy: root → TLD → authoritative → resolver.
  • Recursive resolvers do the lookup work and cache the answers. Authoritative servers are run by zone owners.
  • Core records — A / AAAA / CNAME / MX / TXT / NS / SOA / SRV / CAA. Each has its own purpose.
  • TTL governs cache time. Shorter = changes propagate faster, more queries.
  • CNAME can't sit at the apex. ALIAS / CNAME flattening fakes it.
  • UDP 53 by default; large responses use TCP; DoH/DoT bring encryption.
  • DNSSEC signs answers to prevent spoofing — slow adoption, ~10% of domains.
  • Debug with dig / nslookup / whatsmydns.net. Honor the TTL when waiting for changes.
  • Try it: IP / CIDR Calculator to inspect the resulting IP; URL Parser to pull the host out of a URL.
Back to guides