Pi-hole + Unbound on an old Pi 3B: my setup after 2 year, full config
Your own recursive DNS at home. No more sending every query to Google or to the ISP
Contents
Hi all, this is my first long post here. My Pi 3B is the oldest thing in my homelab and still the most important, because when it is down the whole house have no internet and my wife know exactly who to blame :)
Why Unbound and not only Pi-hole
Pi-hole alone block ads, but it still forward every query to some upstream (Google, Cloudflare, or your ISP). My ISP DNS here sometimes is slow, and when I type a domain wrong it redirect me to their own search page with ads. Very annoying. With Unbound, the Pi talk directly to the root servers, then the TLD servers, then the real authoritative server. No single company see all my queries.
Hardware
- Raspberry Pi 3B (1GB), from 2017
- Boot from USB SSD, not SD card (I learn this the hard way, like Matt say in his SD card post)
- Small UPS for router + Pi, because power cut
Step 1: Pi-hole
curl -sSL https://install.pi-hole.net | bash
Give the Pi a static IP first (DHCP reservation on router is best). In the installer, the upstream does not matter, we change it later.
Step 2: Unbound
sudo apt install unbound
Create /etc/unbound/unbound.conf.d/pi-hole.conf. This is close to the one in the Pi-hole docs, I only change small things:
server:
verbosity: 0
interface: 127.0.0.1
port: 5335
do-ip4: yes
do-udp: yes
do-tcp: yes
do-ip6: no
prefer-ip6: no
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: no
edns-buffer-size: 1232
prefetch: yes
num-threads: 1
so-rcvbuf: 1m
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8
private-address: fd00::/8
private-address: fe80::/10
Unbound listen only on localhost port 5335, so only Pi-hole can use it.
Step 3: the Debian gotcha
On Bookworm, the unbound package also bring a service that push Unbound into resolvconf, and then strange things happen (Pi-hole start, then DNS stop working after reboot). Disable it:
sudo systemctl disable --now unbound-resolvconf.service
And in /etc/resolvconf.conf comment out the line unbound_conf=... if you have it. Then:
sudo systemctl restart unbound
Step 4: test before you switch
dig pi-hole.net @127.0.0.1 -p 5335
# first time slow (100-300ms from Vietnam), second time ~0ms because cache
dig fail01.dnssec.works @127.0.0.1 -p 5335
# must be SERVFAIL. this domain has broken DNSSEC on purpose
dig +ad dnssec.works @127.0.0.1 -p 5335
# must be NOERROR and you see "ad" in the flags line
If the second one say NOERROR, DNSSEC is not working, stop and check.
Step 5: point Pi-hole to Unbound
Pi-hole admin, Settings, DNS. Untick all upstream servers. In custom upstream put 127.0.0.1#5335. Save.
Then on the router, DHCP should give the Pi-hole IP as DNS to every device. My ISP router does not allow to change the DNS (very very common in VN), so I turn off DHCP on the router and use the DHCP server inside Pi-hole. Works fine for 2 years.
Numbers after 2 year
- Around 28-34% of queries blocked, most of it is smart TV and one Android phone that I will not name (my mother in law)
- Cache hit average ~0-1 ms, cache miss 80-300 ms. Prefetch help a lot for the domains you use every day
- Pi 3B load average 0.05. It does not care
Please do NOT
Do not open port 53 to the internet. An open resolver on the internet will be used in DNS amplification attacks within days, and your ISP will be not happy with you. For DNS outside home, use VPN back to home.
hope this help :)
Written by
Nguyễn Minh Hiếu
Proxmox, Docker, ZFS, and a power bill my wife asks about. HCMC 🇻🇳 Backend dev by day, homelab by night. Founder of Self Hosted. Back up your data, seriously.
Get the best of #raspberry_pi_lab weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment