NxValue Stack

Pi-hole with Unbound: Private Recursive DNS Explained

Most "private DNS" setups only move your trust around. You stop asking your ISP and start asking Google, Cloudflare, or Quad9 instead. Pi-hole with Unbound goes a step further: block unwanted domains first, then resolve everything else yourself, with no public resolver in the middle.

This guide explains how the two pieces fit together, how to build the setup on your own server, and what it does and does not protect.

The two pieces

Pi-hole is a DNS filter. Your devices ask it for a domain name, and it checks the request against your blocklists. If the domain is an ad network, tracker, or telemetry endpoint, Pi-hole answers with "nothing here" and the connection never starts. It also keeps a query log, so you can see which device asked for what.

Unbound is a recursive DNS resolver. A normal setup forwards your questions to a big public resolver that does the work for you. Unbound does the work itself: it starts at the DNS root servers, follows the chain to the .com servers, then to the domain's own authoritative servers, and caches the answer. It also validates DNSSEC signatures, so forged answers are rejected.

Put together, the flow looks like this:

Your device
   │  (DoT / DoH, encrypted)
   ▼
Pi-hole        → blocked? answer immediately, nothing leaves the server
   │  (allowed)
   ▼
Unbound        → recursive lookup + DNSSEC validation + cache
   │
   ▼
Root → TLD → authoritative servers

Why not just forward to Cloudflare or Quad9?

Forwarding is fast and simple, and for many people it is a fine choice. The trade-off is that one company sees the full list of domains you look up, from every device, tied to your IP address.

With Unbound as the upstream:

Option A: Build it yourself

These steps assume a small Debian or Ubuntu server with Pi-hole already installed.

1. Install Unbound

sudo apt update
sudo apt install unbound

2. Configure it to listen only on localhost

Create /etc/unbound/unbound.conf.d/pi-hole.conf:

server:
    verbosity: 0

    interface: 127.0.0.1
    port: 5335
    do-ip4: yes
    do-udp: yes
    do-tcp: yes
    do-ip6: no

    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: no
    edns-buffer-size: 1232

    prefetch: yes
    num-threads: 1

    private-address: 192.168.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8

Port 5335 keeps Unbound out of Pi-hole's way on port 53. Binding to 127.0.0.1 means nothing outside the server can talk to it directly. The private-address lines stop Unbound from returning answers that point into your private network, which helps against DNS rebinding.

Restart it:

sudo systemctl restart unbound

3. Test Unbound on its own

dig example.com @127.0.0.1 -p 5335

You should get an answer with status: NOERROR. Now check that DNSSEC validation works:

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

The first must return SERVFAIL (a deliberately broken signature, correctly rejected). The second must return NOERROR.

4. Point Pi-hole at Unbound

In the Pi-hole web interface:

  1. Go to Settings → DNS.
  2. Untick every public upstream (Google, Cloudflare, and so on).
  3. Under Custom DNS servers, add 127.0.0.1#5335.
  4. Save.

From now on, anything Pi-hole allows is resolved by Unbound.

5. Encrypt the path from your devices

Plain DNS between your phone and your server is readable by anyone on the network path. To fix that, expose your Pi-hole over DoT (port 853) or DoH (port 443) using a TLS-terminating proxy in front of it, such as stunnel, nginx, or dnsdist, with a valid certificate for a hostname you own. Then use that hostname in Android's Private DNS setting or the equivalent on iOS and macOS.

Expect to spend most of your time on this step: certificates, renewals, firewall rules, and keeping the proxy updated.

Option B: Let a managed node do it

If you want the same architecture without the maintenance, NxValue Stack provisions a private Pi-hole + Unbound node for you. It is not a shared public resolver: it is your own isolated server running open-source Pi-hole and Unbound, configured for you alone.

You can try the demo node here.

Some limits to this setup

Summary

Pi-hole is a registered trademark of Pi-hole LLC. NxValue Stack is an independent service provider and is not affiliated with Pi-hole LLC.

Skip the setup

Get your own private Pi-hole node with DoH and DoT endpoints. Billed hourly, cancel anytime.