DNS Caching

Cache inspection, flushing (server and client-side), TTL strategy for migrations, and negative caching.

How DNS Caching Works

A caching resolver stores answers from authoritative servers and reuses them until the TTL expires. Every recursive resolver is also a cache. The cache reduces upstream query load and speeds up resolution for repeated lookups.

Configuring a Caching Resolver

BIND as caching-only resolver — no authoritative zones
options {
    directory "/var/named";
    recursion yes;
    allow-recursion { 10.50.0.0/16; 127.0.0.0/8; };
    forwarders { 10.50.1.50; 8.8.8.8; };
    forward first;
    listen-on port 53 { 127.0.0.1; 10.50.1.90; };
};

No zone declarations beyond the built-in root hints. forward first tries upstream forwarders before iterative resolution.

Restrict recursion to internal networks — never serve the internet
acl "trusted" { 10.50.0.0/16; 172.16.0.0/12; 127.0.0.0/8; };

options {
    allow-recursion { trusted; };
    allow-query-cache { trusted; };
};

An open recursive resolver is a DDoS amplification weapon. Always restrict who can use recursion.

Inspecting the Cache

Dump the entire cache to a file
sudo rndc dumpdb -cache

Writes to /var/named/data/cache_dump.db by default. The file can be enormous on busy resolvers.

Search the cache dump for a specific domain
sudo rndc dumpdb -cache && \
awk '/example\.com/{found=1} found && /^;/{found=0} found' /var/named/data/cache_dump.db

The cache dump format groups records by zone. awk extracts the relevant block.

Check remaining TTL for a cached record — watch it count down
dig example.com +noall +answer +ttlid

Query twice with a few seconds between. The TTL column decrements each time — proof the answer comes from cache.

Flushing the Cache

Flush the entire cache — nuclear reset
sudo rndc flush

All cached records are discarded. Next query for any domain requires a fresh resolution from upstream. Use sparingly — it increases latency for all clients temporarily.

Flush a single domain from cache
sudo rndc flushname inside.domusdigitalis.dev

Surgical removal. Only the specified name is evicted; the rest of the cache is preserved.

Flush an entire zone tree from cache
sudo rndc flushtree inside.domusdigitalis.dev

Removes the domain and all names under it. More thorough than flushname when subdomains are also cached.

Client-Side Caching

systemd-resolved — flush local stub resolver cache
sudo systemd-resolve --flush-caches
systemd-resolved — show cache statistics
sudo systemd-resolve --statistics

Shows current and total cache sizes, hit/miss ratio.

nscd — flush the name service cache daemon
sudo nscd -i hosts

nscd caches NSS lookups (getaddrinfo, gethostbyname). Flushing named does nothing if nscd is holding stale answers.

TTL Strategy

Low TTL before migration — prepare for IP change
; 48 hours before migration, lower TTL
webserver  300  IN A  10.50.1.100

; After migration completes, restore normal TTL
webserver  3600 IN A  10.50.1.200

Lower the TTL well before the change (at least 2x the current TTL in advance). This ensures caches expire quickly when the actual change happens.

Negative caching — NXDOMAIN TTL from SOA minimum
dig nonexistent.example.com | grep -i "SOA"

When a name does not exist, resolvers cache the NXDOMAIN for the duration specified by the SOA minimum field. High negative TTL means typos and deleted records stay "not found" in caches longer.

See Also