Pi-hole Upgrade #1 – unbound DNS server

So, you’ve installed pi-hole and configured your network clients to use it as the default DNS server. Ads are disappearing! Life is good. I was happy until I realized that I could no longer resolve the other host on my network. The myriad of raspberry pis that are on my network were no longer reachable by hostname. Turns out there’s an unadvertised step in setting up pi-hole as your DNS server: you need to install a DNS server on it!

I found unbound. Unbound is a caching name server. Caching name servers are great. They save (or cache) your frequently used domain names for quick retrieval and thereby speed up your web experience. unbound actually queries the root servers instead of relying on the likes of or some other random, “free” DNS service. I’m not sure I want to send all my unresolved named queries to Google anyways. What are they doing with all that DNS query info, anyways?

Install unbound

Grab the current root servers list here and save it to a text file at /var/lib/unbound/root.hints. Install the package and enable it:

apt install unbound
systemctl enable unbound.service

Create a config file for pi-hole and save it in the includes directory. Edit /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
     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: fd00::/8
     private-address: fe80::/10

You’re welcome to pare down the list of IP ranges. They’re provided here as an example refresher of CIDR syntax. Let’s fire up unbound and see if we can get it to resolve something. NB: unbound is running on a high port! Make sure you mention that in your query:

sudo service unbound restart
dig pi-hole.net @ -p 5335

OK, we have a DNS server! Let’s configure pi-hole to use it. Use your web browser to go to the DNS admin page of pi-hole. Uncheck the DNS servers that you choose during installation and put in your new unbound server in the custom section. Notice the # sign instead of the usual “:” separator between the localhost IP address and the port number.

Hit the SAVE button at the bottom of the page. That’s it! You’ve got a caching DNS server that stores only your favorite names! Well, actually, it stores all the name lookups at happen on your network. If you’d like to see it in action, run:

tail -f /var/log/pihole.log

No joy? Try “systemctl status unbound” to see if it’s running. “journalctl -xe” could yield answers. Honestly, none of these helped me until I ran “unbound-checkconf” That was how I learned that I misspelled “root.hints”. Fixed the typo and “systemctl restart unbound” was happy!

Tune in next time for the next upgrade: dhcp!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.