Skip to main content

Two resolvers and an authority: splitting internal DNS in two

The usual homelab DNS setup is one box — Pi-hole, or AdGuard, or a single Unbound — doing everything: recursion for the internet, answers for your internal names, and ad-blocking on the side. It works. But it merges two jobs that are genuinely different, and merging them means a bug or an upgrade in one takes down the other.

I split internal DNS into two layers, each with its own high-availability VIP.

Layer 1 — recursive (the only thing clients see)
#

Clients get exactly one DNS address: a floating virtual IP shared by three small VMs, each running dnsdist in front of Unbound.

  • Unbound does the actual recursion — walking from the root servers down — with qname-minimisation and caching. It’s the engine.
  • dnsdist sits in front as the client-facing front door: it’s where per-client rules, logging, and (later) filtering live, and it’s built to be the thing exposed.
  • keepalived floats a VIP across the three so one VM can die without clients noticing.

That VIP is the address DHCP hands out. Clients never know there are three boxes.

Layer 2 — authoritative (owns the internal zone)
#

A separate trio serves the internal zone (*.int.example.net) and reverse DNS — and it does no recursion and no forwarding at all. Ask it about google.com and it says “not my domain,” full stop. One node is the primary; the other two are secondaries that pull the zone over TSIG-signed transfers with NOTIFY. Standard, boring, correct — no proprietary clustering.

The recursive layer forwards only the internal zones to this authoritative VIP, and recurses everything else.

Why bother splitting them?
#

Three reasons that earned their keep:

  1. Different blast radii. A cache-poisoning class of bug lives in the recursive layer; a zone-transfer or record-management bug lives in the authoritative layer. Keeping them apart means one failure mode can’t become the other.
  2. Upgrade independently. I can restart or rebuild the resolvers without touching the authority for my internal names, and vice versa.
  3. Recursion is a big attack surface; authority is a small one. The thing that reaches the whole internet (Unbound) and the thing that holds my private records don’t need to be the same process.

It also maps to a clean firewall story, which matters once you’re doing zone-based firewalling: every VLAN may reach the resolver VIP on port 53, and nothing else. One sentence.

The honest caveat
#

All six of these VMs run on repurposed old laptops that my own tiering policy classifies as expendable hardware. That’s a deliberate, documented accepted-risk: three instances plus a VIP per layer buys enough redundancy for a family, and there’s a planned exit to proper always-on hardware later. Writing that trade-off down — rather than pretending the laptops are Tier-0 — is the point.

What I’d tell past-me
#

  • “One DNS box” is fine until it isn’t; the split costs a little now and saves a bad day later.
  • The recursive VIP is the only DNS address anything should ever be handed. If you find a client pointed at the authoritative layer, that’s a bug — it can’t resolve the internet.
  • Keepalived with all nodes as BACKUP + nopreempt means the VIP moves on failure and stays put when the failed node returns — no flapping.

Next up: time. It sounds trivial until a service host’s NTP replies start leaving by the wrong door.