Feb. 29, 2020, 8:25 p.m.

Pi-Hole HA

Or my efforts to give my family an SLA.

At work I'm constantly dealing with servers that aren't redundant and so need buy-in and advance notice whenever we need to bring them down for maintenance. I started thinking about this for the home front after I installed my first Raspberry Pi running Pi-Hole. If you aren't aware, Pi-Hole acts as a middle man for IP address requests to locations on the world-wide-web. To do this your network needs to point to your Pi-Hole as the server to ask for all DNS requests your device doesn't already know about. DNS requests happen A LOT so all networks should have multiple DNS servers that they can ask for this information. This prevents communication failures and slowdowns from impacting the always important activity of lurking r/ProgrammerHumor. On a more serious note, this also allows for the devices to be taken completely off-line to do periodic backups.

Setting up a Pi-Hole is actually really easy. I followed the official install instructions which is run in a single command. The most challenging part of the setup is getting everything else configured correctly. The next task is to configure your DHCP provider to point to the Pi-Hole for DNS. I recently upgraded my home network to Unifi equipment which allows for this kind of advanced configuration. The Comcast router that we had prior to that wouldn't allow it so running a Pi-Hole was not an option.

In the Unifi Controller these DNS settings are called "DHCP Name Server" which I guess is technically correct but I spent way too long time looking for "DNS server" settings. Unifi allows for setting up to 4 different IP addresses for DHCP name servers. Initially when I setup a single Pi-Hole I used the address for my Pi-Hole and then Google's DNS server @ 8.8.8.8. This would allow for local devices to always have an active DNS server but queries to 8.8.8.8 would by-pass the Pi-Hole and could let ads slip through.

It's tempting to think of these multiple DNS servers as "primary" and "secondary" where the secondary is the fallback in-case the primary isn't available. In fact the DNS spec doesn't define how devices use multiple DNS server addresses so it's up to the device manufacturer to set that behavior. All of the devices that I have mainly use the first DHCP name server so I never really noticed ads getting through. Regardless, DNS for my network wasn't going through the pi's at 100% which was a major motivation to setup the second one.

My next task was to add hostnames for all the devices on my network with static IP addresses. At this time I've got 3 pi's running, a router, a switch, and a couple of wireless access points. Defining local DNS names isn't supported out of the box with pi-hole so there's some manual configuration that needs to be done. I found HOWTO: Using pi-hole as LAN DNS server on pi-hole.net that shows the steps to accomplish this. It's an easy task and IMO a great improvement for homelabs.

The last task was to setup a system for syncing the configuration between the two Pi-Holes. This includes the white lists, black lists, and most importantly for me, the lan list which is where my hostnames are defined. Initially I found a script that was fairly simple which used rsync to transfer the files to the second pi-hole and then restart the pi-hole services if any were updated. It was written in bash and I was tempted to re-write with Python to make it my own. While searching for a source on github I cam across another version of the script which was named, Pi-Hole Gemini (instructions) (script). This version was a vast improvement and I definitely didn't have anything to gain by trying to do it myself so I installed it as is. The script still uses rsync to transfer the data but it also has logging, better IP address & port customization, and better handling of updates on the remote pi-hole.

I'm really really happy with the dual Pi-Hole setup. All of the DNS queries coming out of my network are being filtered for advertising which is a benefit the whole family can enjoy! Plus they cache DNS requests so we get "better performance" and I get to define hostnames for all my Pi projects :D.

TLDR;