Pi-Hole has been a staple of my homelab for several years now. Even if you don’t want to use the ad-blocking feature, the reporting and logging I find to be very helpful. Anyway, it’s one of my favorite projects and I highly encourage anyone and everyone to check it out!
The default configuration is very good, particularly if you want to simply block the majority of ads. I’m a bit over zealous, so I like to block ads, trackers, malware, and many other things. Additionally, I use Pi-Hole for DHCP on my network, having made the change when I moved from a pfSense router to a USG.
I’m going to assume you are able to follow the Pi-Hole deployment instructions and get everything up and running in the default configuration. I use a virtual machine (running CentOS 7.7) to host my instance, but you can use a RaspberryPi, almost any old hardware, even a container on an existing Linux machine if you’d like. I’ll also assume that you’re capable of updating your network and/or clients to use the Pi-Hole.
Block lists and white lists
To block all the things I want blocked I use a number of additional lists. Specifically, I use the list of lists found at https://firebog.net/. I find that the owner, WaLLy3K does a great job identifying new and cleaning up old lists, as well as the metadata about how prone the list is to breaking things other than ads.
I’ve trained my family to let me know when a site they visit is broken or misfunctioning, so I don’t mind using the “non-crossed lists”, meaning the ones with a check or > next to them. The latter meaning that there is some potential to break popular and/or desirable sites. To quickly get the list of sites to populate Pi-Hole’s list of lists, simply download from here.
# download the list of lists
curl -Ss https://v.firebog.net/hosts/lists.php?type=nocross -o /etc/pihole/adlists.list
Next, we want to whitelist some known sites to prevent things from breaking. Fortunately, anudeepND kindly keeps a whitelist updated for us.
# download the whitelist
curl -sS https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt -o /etc/pihole/whitelist.txt
With both of those in place, have Pi-Hole ingest the new lists and updates its block list:
# update gravity
Pi-Hole uses dnsmasq (technically a fork, but the functionality we care about is identical), which means that it’s only a DNS forwarder. It will resolve host names for DHCP addresses it gives out, but any other result is forwarded. I’m a big fan of privacy and encourage you to use whatever secure DNS method you like, either DNS over HTTPS (DoH) or DNS over TLS (DoT). I prefer DoT over DoH, so I take measures to actively block DoH on my firewall by blocking all traffic to the most common DoH servers, such as Google and CloudFlare.
If you want to adopt DoH/DoT for your outbound DNS traffic, I would recommend following this guide from Pi-Hole, which configures the
cloudflared client on your Pi-Hole. NextDNS also offers an excellent service (which I prefer!) and their client can be configured the same way as the CloudFlare client with Pi-Hole.
If you don’t want to use anyone else’s DNS service, you can also configure your own resolver on your Pi-Hole instance. Simply follow the guide here to deploy UnBound with Pi-Hole.
I have used all three of these, and they all work well, however at the moment I’m using NextDNS.
Additional dnsmasq options
Last, but not least, I am adding some extra config options to Pi-Hole’s FTL (a.k.a. dnsmasq). I do this mostly because my network is uncommonly complex. In particular, I have three networks: home, work, and lab. Each one has it’s own DNS and DHCP services, so in order to have things resolve correctly I add the config to Pi-Hole.
Pi-Hole stores dnsmasq configuration in
/etc/dnsmasq.d. You’ll find one to three files in there already depending on if you use DHCP and static DHCP assignments.
# put our config into a file which Pi-Hole won't accidentially overwrite
cat << EOF > /etc/dnsmasq.d/99-local.conf
# don't forward anything for the local domain
# configure forward and reverse for the work lan
# configure forward and reverse for the lab lan
# allow responses from work and lab to include private IP ranges
# append the domain name to ips/names from the hosts file
# disable firefox trr
# stupid WPAD
# restart for the settings to take effect
At the end I’m telling any clients looking for a WPAD config to a specific host, which happens to be the IP of the Pi-Hole itself. I’m not actually using a proxy, so the WPAD config is simple and just keeps a bunch of obnoxious log entries from showing up.
cat << EOF > /var/www/html/wpad.dat
function FindProxyForURL(url, host)
Any clients looking for the config will receive the above file, which is served by Pi-Hole’s lighttpd instance.