← How-Tos
raspberry-pi Aug 21, 2026 ◑ 14 views ◯ 4 min read

Running Your Own Recursive DNS Resolver on Raspberry Pi with Unbound: Full DNS Privacy Beyond Pi-hole

raspberry piunbounddnspi-holednssecprivacyself-hostedrecursive resolver

This site's Pi-hole guides cover network-wide ad blocking — Pi-hole intercepts DNS requests and blocks known ad/tracker domains, but it still forwards legitimate lookups upstream to a resolver like Google DNS or Cloudflare, meaning that upstream provider still sees every domain you visit. Running your own recursive resolver with Unbound does something different: instead of forwarding queries anywhere, your Raspberry Pi talks directly to the DNS root servers and walks the delegation chain itself for every lookup. No third party — not your ISP's DNS, not Google, not Cloudflare — sees your browsing pattern in aggregate. This guide covers setting up Unbound on a Raspberry Pi, and — the more common real-world setup — chaining it behind Pi-hole so you get ad-blocking and full recursive resolution together.

How Recursive Resolution Differs From a Forwarder

A typical DNS "resolver" you configure — 1.1.1.1, 8.8.8.8, your ISP's DNS — is a forwarding (caching) resolver: it takes your query and passes it to another resolver, which does the real work and hands back an answer, and every one of those upstream operators can log which domains you're resolving, even without seeing the actual page content over HTTPS. A recursive resolver skips that middleman: it starts at the 13 root server clusters, gets referred to the correct top-level-domain server (.com, .org, etc.), gets referred again to the domain's authoritative nameserver, and gets the final answer directly from the source. No single party in that chain sees your full browsing pattern — each server only sees one piece of a much larger picture, and the authoritative server for the exact domain you're visiting is generally already expecting that traffic.

What You Give Up

This isn't a strictly-better replacement for a public forwarder — it's a genuine trade-off, worth stating plainly before you commit an hour to setup:

Installing Unbound

sudo apt update sudo apt install unbound -y

Unbound ships with a sensible default root hints file and works as a recursive resolver out of the box, but a few settings are worth setting explicitly in /etc/unbound/unbound.conf.d/pi-recursive.conf:

server: interface: 127.0.0.1 port: 5335 do-ip4: yes do-udp: yes do-tcp: yes prefetch: yes cache-min-ttl: 3600 cache-max-ttl: 86400 harden-glue: yes harden-dnssec-stripped: yes use-caps-for-id: yes edns-buffer-size: 1232 qname-minimisation: yes

Binding to a non-standard port (5335 here) rather than the default 53 is deliberate — it leaves port 53 free for Pi-hole to bind to, which is the setup most people actually want (see below). qname-minimisation is a meaningful privacy improvement on its own: it sends only the minimum necessary portion of a domain name to each server in the delegation chain, rather than the full query, so intermediate servers see even less of what you're resolving.

Chaining Behind Pi-hole (the Setup Most People Want)

Running Unbound standalone gives you privacy but loses Pi-hole's ad/tracker blocking. Running them together gives you both: Pi-hole handles blocklist filtering and serves as your network's DNS server on port 53, then forwards anything not blocked to Unbound running locally on port 5335 for full recursive resolution — instead of forwarding to a public DNS provider.

  1. Install and configure Unbound as above, bound to 127.0.0.1:5335.
  2. Test it directly: dig @127.0.0.1 -p 5335 example.com should return a valid answer.
  3. In the Pi-hole admin interface, go to Settings → DNS, uncheck all the default upstream providers, and under "Custom DNS servers (IPv4)" enter 127.0.0.1#5335.
  4. Save, then run a lookup from a client on your network and confirm it resolves — Pi-hole's query log will show the request being filtered against blocklists and then resolved through Unbound.

Verifying DNSSEC and Confirming It's Actually Working

Unbound validates DNSSEC by default, which protects against a resolver being fed forged answers for a domain that publishes DNSSEC records. Confirm it's active:

dig @127.0.0.1 -p 5335 sigfail.verteiltesysteme.net dig @127.0.0.1 -p 5335 sigok.verteiltesysteme.net

The first (intentionally broken DNSSEC signature) should return SERVFAIL; the second (valid signature) should resolve normally. If the first one resolves instead of failing, DNSSEC validation isn't actually working and is worth troubleshooting before you trust the setup.

Performance and Monitoring

Unbound's cache means most repeat lookups are effectively free after the first resolution. On a Raspberry Pi 4 or 5, recursive resolution for an uncached domain typically adds well under a second versus a cached public forwarder response — noticeable on the very first visit to a brand-new domain, unnoticeable for nearly everything else in normal browsing. Check unbound-control stats for cache hit rate and query volume if you want to confirm it's keeping up with your household's DNS load; a Pi 4 or better handles typical home traffic without strain.

Pi-hole plus Unbound is a meaningfully different privacy posture than Pi-hole alone — it removes the single biggest remaining party (your upstream DNS provider) that could otherwise see every domain your network visits, at the cost of a small first-lookup delay and one more service to maintain on hardware you already have running.