16. Cheat sheet
DNS · 16. Cheat sheetEverything worth having to hand, in one place.
The eight facts
Section titled “The eight facts”1. NOTHING PROPAGATES. an old answer expires out of each cache independently. the wait is bounded by the OLD TTL, not the new one.
2. A ZONE IS NOT A DOMAIN. a zone starts at an SOA and ends at every delegation below it.
3. A CNAME CANNOT COEXIST WITH ANYTHING, therefore it cannot sit at the apex.
4. NXDOMAIN ≠ NODATA. "does not exist" is not "exists with no record of this type".
5. SERVFAIL MEANS TWO THINGS. `dig +cd` tells you which.
6. ONE BROKEN DNSSEC LINK = TOTAL OUTAGE for every validating resolver (~30–40% of queries).
7. NS, GLUE AND DS LIVE AT THE REGISTRAR. everything else lives in your zone.
8. DNS FAILOVER TAKES MINUTES. a load balancer takes milliseconds. know which problem you have.Record types
Section titled “Record types” A IPv4 address AAAA IPv6 address CNAME alias; exclusive at its name DNAME alias for a whole subtree MX mail exchange + preference (lower first; hostname, never an IP, never a CNAME) TXT arbitrary strings; ≤255 per string SRV _svc._proto; priority weight port target HTTPS / SVCB alpn, ipv4hint, ech — and an ALIAS form legal at the apex NS delegation / authority SOA one per zone, at the apex PTR reverse mapping CAA which CAs may issue TLSA DANE certificate pinning DNSKEY public key RRSIG signature over an RRset DS hash of a child's key, in the parent NSEC / NSEC3 proof of non-existence CDS / CDNSKEY child's signal for DS updates ANY a meta-query, widely refusedFlags and response codes
Section titled “Flags and response codes” FLAGS qr response aa authoritative tc truncated rd recursion desired ra recursion ad DNSSEC available validated cd checking disabled
RCODES 0 NOERROR (zero answers = NODATA) 1 FORMERR 2 SERVFAIL server broke OR DNSSEC bogus 3 NXDOMAIN 5 REFUSED not my zone / not allowed 16 BADVERS / BADSIG
READING FLAGS aa present → you reached authority aa absent → a resolver or a referral tc present → size problem; retry TCP ad present → validateddig recipes
Section titled “dig recipes”dig example.com A # the basicsdig +short example.com Adig +noall +answer example.comdig @1.1.1.1 example.com # a specific resolverdig @ns1.example.com example.com # a specific authoritydig +norecurse @ns1.example.com example.com # no recursion: see referralsdig +trace example.com # walk from the root (no cache)dig +dnssec example.com # ask for signaturesdig +cd example.com # bypass validationdig +tcp example.comdig +bufsize=1232 example.comdig +subnet=203.0.113.0/24 example.com # EDNS Client Subnetdig +nsid @k.root-servers.net . SOA # which anycast instance?dig -x 192.0.2.15 # reversedig @ns1.example.com example.com AXFR # zone transferdig +short example.com SOA | awk '{print $3}' # the serialdig example.com | awk '/^example/ {print $2}' # remaining TTL# other toolsdelv example.com # validating lookup (BIND)delv +rtrace example.comkdig +tls @1.1.1.1 example.com # DoTkdig +https @1.1.1.1 example.com # DoHdog example.com @1.1.1.1dnsviz probe example.com | dnsviz printnamed-checkzone example.com db.example.comnamed-checkconfnsupdate -k key.confresolvectl query example.comresolvectl statusresolvectl flush-cachesgetent hosts example.comwhois example.comThe SOA
Section titled “The SOA” example.com. 3600 IN SOA ns1.example.com. ; MNAME primary admin.example.com. ; RNAME admin@… 2024061503 ; SERIAL higher = ; newer 7200 ; REFRESH check ; interval 900 ; RETRY after a ; failure 1209600 ; EXPIRE secondaries ; STOP SERVING ; after this 300 ; MINIMUM negative ; cache TTLTTL policy
Section titled “TTL policy” apex / www A, AAAA 300 behind a CDN or LB 60 MX 3600 SPF / DKIM / DMARC 3600 NS at the apex 86400 SOA minimum 300 _acme-challenge 60 mid-migration 60
LOWER THE TTL THREE DAYS BEFORE A PLANNED CHANGE, THEN WAIT OUT THE OLD TTL, THEN CHANGE THE RECORD. WHO IGNORES YOUR TTL nscd its own, 3600 browsers their own, ~60 s the JVM FOREVER by default connection pools never re-resolve some ISPs floor low TTLsMail records
Section titled “Mail records” MX example.com. MX 10 mail.example.com. SPF example.com. TXT "v=spf1 include:_spf.google.com -all" ONE record. 10-lookup limit. DKIM sel._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=…" DMARC _dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com" deploy p=none FIRST. read reports. then tighten. PTR set by whoever owns the IP block. mail receivers check it. MTA-STS _mta-sts.example.com. TXT + an HTTPS policy fileStub resolver
Section titled “Stub resolver” /etc/resolv.conf
nameserver 127.0.0.1 search example.com options timeout:1 attempts:2 rotate single-request-reopen ndots:1 edns0
timeout default is 5 — change it. ndots:5 in Kubernetes costs 5 wasted NXDOMAINs per external lookup. use a trailing dot, a per-pod dnsConfig, or NodeLocal DNSCache.Encrypted DNS
Section titled “Encrypted DNS” Do53 udp/tcp 53 plaintext DoT 853 TLS; easy to permit, easy to block DoH 443 indistinguishable from HTTPS DoQ 853/udp QUIC ODoH relay + target, non-collusion assumed DDR/DNR RFC 9462/9463 a network advertises its own encrypted resolver
STILL VISIBLE: the destination IP, the SNI (unless ECH), timing, your choice of resolver. use-application-dns.net → NXDOMAIN disables Firefox auto-DoH.DNSSEC
Section titled “DNSSEC” CHAIN root KSK → root ZSK → child DS → child KSK → child ZSK → the RRset
ALGORITHM 13 (ECDSA P-256) for anything new — RSA pushes DNSKEY answers past 1232 bytes.
NSEC signs the gaps; allows zone walking NSEC3 hashes names; RFC 9276 says 0 iterations, no salt WHITE LIES synthesised NSEC, online key, no enumeration
TO DISABLE: REMOVE THE DS AT THE PARENT FIRST, WAIT OUT ITS TTL, THEN UNSIGN.
dig +cd does it work without validation? delv why not? dig +dnssec … | grep EDE the specific reasonZone operations
Section titled “Zone operations” AXFR full transfer, over TCP. RESTRICT IT. IXFR delta from a serial NOTIFY primary tells secondaries immediately TSIG shared-secret HMAC for transfers, notifies and updates. signs a timestamp — clock skew gives BADTIME. RFC 2136 dynamic update (nsupdate, DHCP, AD, certbot)
THE SERIAL CHECK, RUN IT HOURLY:for ns in $(dig +short example.com NS); do printf '%-28s %s\n' "$ns" \ "$(dig +short @"$ns" example.com SOA | awk '{print $3}')"doneSpecial names
Section titled “Special names” .arpa infrastructure; in-addr, ip6 .internal the reserved private TLD — use this .home.arpa home / lab networks .local mDNS ONLY. never unicast. .localhost always loopback .invalid never exists .example documentation .test testing .corp .home .mail PERMANENTLY BLOCKED from the rootZone file syntax
Section titled “Zone file syntax” $ORIGIN example.com. $TTL 3600
@ IN SOA ns1.example.com. admin.example.com. ( 2024061503 7200 900 1209600 300 ) IN NS ns1.example.com. IN MX 10 mail.example.com. IN A 192.0.2.1 IN CAA 0 issue "letsencrypt.org" ns1 IN A 192.0.2.1 www 300 IN CNAME cdn.example.net. * IN A 192.0.2.99
@ the current $ORIGIN blank owner repeats the previous one — INSERTING A LINE CHANGES THE OWNER OF EVERYTHING BELOW no trailing dot $ORIGIN is appended \# len hex an unknown record type (RFC 3597)named-checkzone example.com db.example.comdig @ns1.example.com example.com AXFR > exported.zoneFlushing caches
Section titled “Flushing caches”sudo resolvectl flush-caches # systemd-resolvedsudo unbound-control flush www.example.comsudo rndc flushname www.example.com # BINDsudo killall -HUP dnsmasqsudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder # macOSipconfig /flushdns # Windows# browsers: chrome://net-internals/#dns, about:networking#dns AND THE CACHES YOU CANNOT REACH: every other resolver, every browser, every JVM, every connection pool.Wildcards and empty non-terminals
Section titled “Wildcards and empty non-terminals” *.example.com A 192.0.2.99 matches anything.example.com NOT example.com (the apex) NOT any name that EXISTS with any record of any type
IF a.b.example.com EXISTS THEN b.example.com EXISTS WITH NO DATA → NODATA, not NXDOMAINDiagnostic order
Section titled “Diagnostic order”1. IS IT A CACHE? dig @ns1.yourdomain … vs dig @1.1.1.1 … read the remaining TTL. if authority is right, you are waiting. stop.
2. IS IT DNSSEC? dig +cd. one command.
3. IS THE DELEGATION RIGHT? dig +norecurse @a.gtld-servers.net … compare the parent's NS set with yours.
4. DO ALL NAMESERVERS AGREE? the SOA serial loop above.
5. IS IT THE CLIENT? resolv.conf, ndots, nsswitch, /etc/hosts, resolvectl status, the JVM.
6. IS IT THE NETWORK? TCP/53 open? dig +tcp. dig +bufsize=512. fragmentation?
7. IS IT THE REGISTRAR? whois: expiry, status, NS, DS.Anti-patterns
Section titled “Anti-patterns” ✗ a missing trailing dot in a zone file ✗ a CNAME at the apex ✗ a CNAME as an MX or NS target ✗ two SPF records, or more than 10 SPF lookups ✗ DMARC p=reject before SPF and DKIM work ✗ an SOA minimum of 86400 ✗ changing a record and its TTL together and expecting speed ✗ publishing a DS without the matching DNSKEY ✗ changing NS and DS in one operation ✗ decommissioning old nameservers immediately after an NS change ✗ a made-up internal TLD (.corp, .lan) ✗ a dangling CNAME to a deleted service ✗ an open AXFR ✗ an open recursive resolver ✗ relying on round-robin DNS for failover ✗ treating an internal-only name as an access control ✗ monitoring your own DNS through your own resolverNumbers
Section titled “Numbers” label ≤63 octets full name ≤255 octets TXT string ≤255 octets classic UDP message 512 octets recommended EDNS size 1232 octets root zone size ~2 MB top-level domains ~1,500 root server names 13 root server instances 1,900+ root key ceremonies 4 per year validating resolvers ~30–40% of queries signed .com domains ~5% cold lookup, 3 round trips ~80 ms warm lookup ~1 ms local cache hit ~0.05 ms stub timeout, default 5 s DNS failover, realistic 1–3 min DS TTL at .com 2 daysRead alongside: Consul for DNS as a read interface onto a registry with real health data, Kubernetes for CoreDNS, ndots and the conntrack race, HAProxy for the sub-second failover DNS cannot provide, Envoy for endpoint discovery that replaces DNS inside a mesh, Vault for issuing the certificates whose names all of this resolves, and Terraform for the reviewable diff that zone-as-code is after.