Pi-hole and Unbound Setup
These are mostly notes I made for myself while setting up Pi-hole and Unbound on a new Raspberry Pi, but I figured I may as well post them here in case it helps someone out or gets them wanting to try it out.
If you’re unaware, Pi-hole is a network-wide ad blocker that works by looking at DNS queries and Unbound is a recursive DNS resolver. There’s a few benefits of running both:
- block ad, tracking, and known malware domains across all your devices
- potentially faster DNS queries thanks to caching
- slight privacy and security benefits since your outbound DNS queries go straight to authoritative servers
Install and configure Pi-hole
Pi-hole is pretty straightforward to get up and running so I won’t go into details here. I’ve linked the install docs below, but these commands are how to obtain and run the installer.
git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
cd "Pi-hole/automated install/"
sudo bash basic-install.sh
After Pi-hole is installed, run this command to set the admin password for the web interface.
pihole -a -p
Pi-hole Documentation: Installation
Install and configure Unbound
You should be able to install Unbound from your distro’s package repositories.
sudo apt install unbound
Unbound may fail to start due to a port conflict with Pi-hole. Don’t worry about this because you haven’t configured it yet.
Here’s my Unbound config, which for the most part is the same config that Pi-hole gives you in their documentation about Unbound but with a few additions to add more reliance on caching which should increase performance.
# /etc/unbound/unbound.conf.d/pi-hole.conf
server:
# If no logfile is specified, syslog is used
# logfile: "/var/log/unbound/unbound.log"
verbosity: 0
interface: 127.0.0.1
port: 5335
do-ip4: yes
do-udp: yes
do-tcp: yes
# May be set to yes if you have IPv6 connectivity
do-ip6: no
# You want to leave this to no unless you have *native* IPv6. With 6to4 and
# Terredo tunnels your web browser should favor IPv4 for the same reasons
prefer-ip6: no
# Use this only when you downloaded the list of primary root servers!
# If you use the default dns-root-data package, unbound will find it automatically
#root-hints: "/var/lib/unbound/root.hints"
# Trust glue only if it is within the server's authority
harden-glue: yes
# Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
harden-dnssec-stripped: yes
# Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
# see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
use-caps-for-id: no
# Reduce EDNS reassembly buffer size.
# Suggested by the unbound man page to reduce fragmentation reassembly problems
edns-buffer-size: 1472
# Perform prefetching of close to expired message cache entries
# This only applies to domains that have been frequently queried
prefetch: yes
# One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
num-threads: 1
# Ensure kernel buffer is large enough to not lose messages in traffic spikes
so-rcvbuf: 1m
# Ensure privacy of local IP ranges
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
# This refreshes expiring cache entries if they have been accessed with
# less than 10% of their TTL remaining
prefetch: yes
# This attempts to reduce latency by serving the outdated record before
# updating it instead of the other way around. Alternative is to increase
# cache-min-ttl to e.g. 3600.
cache-min-ttl: 0
serve-expired: yes
After the Unbound config has been created, go ahead and start it.
sudo systemctl start unbound
To make sure Unbound is working, run this dig command and see if you get a response.
dig pi-hole.net @127.0.0.1 -p 5335
If Unbound is working, you just need to setup Pi-hole to use it as its upstream DNS server. Go into Pi-hole’s DNS settings in the web interface and set the custom DNS server to “127.0.0.1#5335”. Disable any other upstream DNS servers.
Pi-hole Documentation: Unbound
Run a DNS performance test
There’s a handy DNS performance test bash script that you can run to test your DNS performance and see the effects of caching.
https://github.com/cleanbrowsing/dnsperftest
Run the following commands to get it.
sudo apt install bc dnsutils
git clone --depth=1 https://github.com/cleanbrowsing/dnsperftest.git
Running the bash script will run several DNS speed tests using your default DNS provider (which at this point is Pi-hole + Unbound) along with other DNS servers. The first run for your setup might be slow. For me it averaged about 200ms. But repeated runs should be near instant at about 1ms.