For years my homelab did what most homelabs do: it pointed DNS at a forwarder, usually whichever public resolver was fashionable that month, and got on with life. It works fine right up until you start caring where your queries go and who gets to see them. I finally decided to run a proper recursive resolver of my own, and it was a far smaller job than I'd built it up to be.
The distinction matters, so quickly: a forwarding resolver hands your query to someone else's resolver and relays the answer back. A recursive resolver does the walk itself, starting at the root servers, then the TLD servers, then the authoritative server for the domain, and assembles the answer locally. With a forwarder, one company sees every domain everyone on my network looks up. With a recursive resolver, that picture is scattered across the actual authorities and nobody holds the full log.
Unbound, because it's boring
I went with Unbound. It's small, it's been doing exactly this job reliably for years, and the config is readable. The whole thing is about a dozen meaningful lines:
server:
interface: 0.0.0.0
access-control: 192.168.0.0/16 allow
access-control: 127.0.0.0/8 allow
cache-min-ttl: 300
cache-max-ttl: 86400
prefetch: yes
harden-glue: yes
harden-dnssec-stripped: yes
qname-minimisation: yes
The two lines I'd point at are qname-minimisation and the DNSSEC hardening. QName minimisation means Unbound only sends each server the part of the name it actually needs to answer: the root and TLD servers see less than the full hostname I'm resolving. It's a small privacy win that costs nothing. DNSSEC validation means I actually check the cryptographic signatures on the answers I get back, so a poisoned response from somewhere upstream gets rejected rather than cached.
What I expected to go wrong, and didn't
I assumed the first cold cache would feel slow, and it does, for exactly one query per domain. The first lookup of something new takes the full walk down from the root, maybe 60 to 120ms. Every lookup after that comes from cache, and with prefetch turned on Unbound quietly refreshes popular entries before they expire, so the common names are effectively always warm. In practice everyday browsing feels identical to before, sometimes snappier, because the cache lives on my own LAN rather than across the internet.
The one real consideration is that I'm now responsible for this. If Unbound falls over, my whole house loses DNS, which to a household is indistinguishable from "the internet is broken". So it runs as a proper service with monitoring, and there's a secondary instance so a single restart doesn't take everything down. That's the actual cost of the privacy and control: not the setup, the ongoing responsibility.
Would I recommend it? If you already run a homelab and have somewhere reliable to host it, yes, without hesitation. It's a satisfying afternoon, the config is comprehensible end to end, and there's a quiet pleasure in knowing the answers to "where does this name live" are being worked out in my own cupboard rather than rented from someone else.