Module 1 · Lesson 5
DNS Protocols and Standards
⏱ 11 min read
DNS Protocols and Standards
DNS was designed to fit in a 512-byte UDP packet. That constraint shaped every protocol decision made in the following four decades. Here's the plumbing.
UDP First, TCP When Necessary
The default transport for DNS is UDP on port 53. UDP is connectionless — no handshake, no session, no teardown. You send a query packet, you get a response packet. For a lookup that needs to be fast and stateless, this makes sense.
A basic DNS query is tiny: the question section adds maybe 30-40 bytes to a 12-byte header. The response is larger but usually still small. UDP handles this without the 3-way TCP handshake overhead.
The trade-off: UDP has no reliability guarantees. If a packet drops, nothing retransmits it automatically. The DNS implementation handles timeouts and retries. For most queries over reliable networks, this is fine. Packet loss on a loopback query to your local resolver is essentially zero.
The 512-Byte Limit
RFC 1035 established 512 bytes as the maximum UDP payload size for DNS responses. If a response exceeded 512 bytes, the server would set the TC (Truncation) flag and the client would retry over TCP.
Why 512? It was a conservative choice for the network conditions of 1987. Most network paths could handle 512-byte packets without fragmentation. Larger packets on some links would be fragmented at the IP layer, and fragmentation caused problems (lost fragments = lost packet, no partial reassembly in DNS).
In practice, 512 bytes is plenty for simple queries. But as DNS took on more roles (DNSSEC signatures, SPF records, multiple A records, SRV records), responses started exceeding 512 bytes regularly. The workaround — falling back to TCP — added latency.
TCP for DNS
When a response is truncated (TC flag set), the client retries over TCP. The entire DNS message fits in a TCP stream, so there's no size limit beyond what TCP can carry.
TCP is also used for:
- Zone transfers (AXFR/IXFR) — transferring entire zones between nameservers
- DNS over TLS (DoT) — port 853, encrypted DNS
- Any scenario where the response will obviously exceed 512 bytes
Historically, many firewalls were configured to pass UDP/53 but block TCP/53. This broke DNS for large responses and zone transfers. You may still encounter this on misconfigured networks. If dig +vc (force TCP) returns results but the normal UDP query doesn't, that's your firewall.
# Force TCP
dig github.com A +vc
EDNS0: The Modern Standard
EDNS0 (Extension Mechanisms for DNS, version 0) was specified in RFC 2671 in 1999, updated by RFC 6891 in 2013. It extends the original DNS wire format to support larger UDP payloads, additional flags, and optional extensions.
EDNS0 is signaled by adding a special pseudo-record type to the additional section of a query:
; EDNS: version: 0, flags:; udp: 4096
The key field: udp: 4096. This tells the server "I can handle up to 4096-byte UDP responses." The server can then send a larger response without truncating.
Modern resolvers and authoritative servers all support EDNS0. In practice, most DNS responses that might have exceeded 512 bytes now fit in a larger EDNS0 UDP response, avoiding the TCP fallback entirely.
EDNS0 also enables:
- DNSSEC: The
DO(DNSSEC OK) flag is an EDNS0 extension. Requests including it will receive DNSSEC records in the response. - NSID: Name Server Identifier — allows clients to identify which specific server (behind anycast) answered a query, useful for debugging.
- ECS (EDNS Client Subnet): RFC 7871 — allows resolvers to forward part of the client's IP to authoritative servers, enabling geo-aware responses. Privacy trade-off.
Check if a server supports EDNS0:
dig github.com A +edns=0
# Look for "EDNS: version: 0" in the OPT PSEUDOSECTION of the response
To see what version a server supports:
dig github.com A +ednsopt=15:0000
Zone Transfers: AXFR and IXFR
DNS nameservers don't operate in isolation. Most zones have a primary server (where changes are made) and one or more secondary servers (which replicate the zone from the primary). Zone transfers are how secondaries stay current.
AXFR (Full Zone Transfer): Transfers the complete zone. The secondary sends a query for the zone's SOA record to get the current serial. If the serial is higher than its local copy, it initiates an AXFR — a TCP connection over which the primary streams every record in the zone. This works reliably but is bandwidth-intensive for large zones.
# Attempt an AXFR (will fail on properly configured servers — good)
dig @ns1.example.com example.com AXFR
IXFR (Incremental Zone Transfer): RFC 1995. The secondary tells the primary its current serial number. The primary sends only the records that changed since that serial. Much more efficient for large zones with frequent updates.
The security implication: unrestricted AXFR lets anyone enumerate every record in your zone. Before AXFR restrictions were common, this was a significant reconnaissance vector. Properly configured nameservers restrict AXFR to known secondary IP addresses only.
Check if a domain allows public AXFR:
dig @ns1.zonetransfer.me zonetransfer.me AXFR
# This domain intentionally allows AXFR for educational purposes
# Real domains should return REFUSED or NOTAUTH
The Relevant RFCs
Not a complete list, but the ones you'll actually reference:
| RFC | Subject |
|---|---|
| RFC 1034 | DNS Concepts and Facilities |
| RFC 1035 | DNS Implementation and Specification |
| RFC 1995 | Incremental Zone Transfer (IXFR) |
| RFC 1996 | NOTIFY — trigger zone transfer |
| RFC 2181 | Clarifications to DNS Specification |
| RFC 2308 | Negative Caching |
| RFC 4033/4034/4035 | DNSSEC |
| RFC 6891 | EDNS0 |
| RFC 7858 | DNS over TLS (DoT) |
| RFC 8484 | DNS over HTTPS (DoH) |
| RFC 8305 | Happy Eyeballs v2 (IPv4/IPv6 selection) |
DNS over TLS (DoT) and DNS over HTTPS (DoH)
The original DNS protocol sends queries and responses in plaintext. Anyone with access to the network path — your ISP, a coffee shop router, a surveillance system — can see every domain you look up.
Two standards address this:
DNS over TLS (DoT) — RFC 7858. Wraps DNS in a TLS session. Port 853. The query is encrypted, but the connection itself (the TCP connection to port 853) is visible to network observers, who can see that you're doing encrypted DNS even if they can't see the queries. Supported by Cloudflare (1.1.1.1), Google (8.8.8.8), Quad9 (9.9.9.9).
DNS over HTTPS (DoH) — RFC 8484. Sends DNS queries as HTTPS requests. Uses standard port 443. Looks like regular web traffic to observers. Harder to block. Also harder for network administrators to monitor and filter (which is either a feature or a bug, depending on your perspective).
Both are opt-in. Your system won't use them unless you configure it to. Firefox and Chrome support DoH and have it enabled by default in some regions.
# Test DoH with curl
curl -H 'accept: application/dns-json' 'https://1.1.1.1/dns-query?name=github.com&type=A'
# Or with the dedicated DNS-over-HTTPS format
curl -H 'content-type: application/dns-message' \
--data-binary @<(echo -ne '\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06github\x03com\x00\x00\x01\x00\x01') \
'https://1.1.1.1/dns-query'
Port 53
Port 53 is the well-known port for DNS, both UDP and TCP. It's a privileged port on Unix systems (below 1024), meaning only root can bind to it. When you run your own nameserver, you'll either run it as root, use capabilities (CAP_NET_BIND_SERVICE), or run it on a high port with a redirect.
One practical note: some networks filter or intercept port 53 traffic. This can cause problems if you're trying to use a different DNS resolver than your ISP's. The ISP may redirect all UDP/53 traffic to their own resolvers, ignoring the destination IP. DoT (port 853) and DoH (port 443) are harder to intercept, which is part of their appeal.
Key Takeaways
- DNS runs on UDP/53 by default. TCP/53 is used for truncated responses and zone transfers.
- The 512-byte UDP limit is a historical artifact. EDNS0 extends it to 4096+ bytes on modern networks.
- EDNS0 also enables DNSSEC, NSID, and ECS (client subnet). Modern DNS assumes EDNS0 support.
- AXFR exposes your entire zone to anyone who asks. Restrict it by IP on your nameserver.
- DoT (port 853) and DoH (port 443) encrypt DNS traffic. Useful for client privacy; may conflict with network monitoring needs.
Further Reading
- RFC 6891 — EDNS0
- RFC 7858 — DNS over TLS
- RFC 8484 — DNS over HTTPS
- zonetransfer.me — A safe place to practice AXFR
- dns.google — Google's DNS over HTTPS endpoint with UI
Up Next
The technical layer is behind us. Next: who actually controls DNS, how the governance structure works, and what 20 years in the industry looks like from the inside.