Taking control of your DNS data!
How to setup Pi-hole for DNS over HTTPS and DHCP duties in your home network
The Problem
Did you know that DNS queries are unencrypted? This means that your ISP could “potentially” build an advertising profile (age, gender, political bias, etc..) by data mining your DNS queries. YIKES!
But what is your average Sri Lankan techie to do about it? Unfortunately not much! Unless you have the disposable income to pay for a trusted VPN service (with decent performance); it is costly to protect your data privacy. Even if you did have the spare change, getting all your connected devices (Smart TV, Wireless Printer, Game console, .. ) on to a VPN is a challenge.
Using an encrypted DNS service is the easier option. It would protect your DNS queries from your ISP, but they can still build that profile of you by Reverse DNS’ing your traffic. That’s a lot harder to do and frankly I don’t see why an ISP would do that.
This is were Cloudflare’s free DNS over HTTPS service comes in to play. Cloudflare has been doing some great stuff over the last few years and currently they offer the fastest public DNS service (1.1.1.1). Fun fact; they also offer “DNS for families”: DNS services that will additionally block malware and adult content.
They offer free DNS over TLS and HTTPS. The HTTPS option is what we are interested in. However, getting your entire home network pointed to it is not straightforward. You can’t, just change your nameserver address. You need a software service that can except your local network’s regular (insecure) DNS queries and pipe them over HTTPS to Cloudflare’s servers. This meat that I’d have to setup a computer on my network to serve this functionality 24x7. Bummer!
So, I conceded to my ISP overloads because the cost-vs-benefit wasn’t there to go with either the VPN or DNS over HTTPS route.
An inadvertent breakthrough
A few days ago, a YouTube video by a creator called “NetworkChuck” popped up in my feed. It was called “BLOCK EVERYTHING w/ PiHole on Docker, OpenDNS and IFTTT” and O..M..G! It was like a greatest hits of bad security practices! He essentially setup an public DNS resolve and exposed an insecure API to modify it. Another YouTube “Tech Educator / Influencer” that will probably end up like Siraj Raval. Sigh!
This ordeal made me inadvertently look up Pi-hole and lo and behold, I found the solution to my problem! Pi-hole is a DNS service you can host on your network. It’s primarily objective is to block ad serving domains at the DNS level. Essentially a DNS sinkhole for ad domains. It serves the same purpose as a browser ad blocker extension; but at the network level, not limiting to your browser. This means that it can block ads everywhere, including inside Android apps. Pi-hole blocked webpages vs ad blocker extension blocked pages look different.
As you can see above, you essentially end up with blank space in a webpage with Pi-hole; where as an ad blocking extension will remove the ad elements entirely. Ad blocking plugins use local compute resources, so the Pi-hole will benefit older computers.
Pi-hole can be setup to use Cloudflare’s DNS over HTTP service and it can also work as a DHCP server. It’s pretty light weight as it has been designed to run on a Raspberry Pi. Even a Pi Zero.
Finally! the cost-vs-benefit made sense to me to go with Pi-hole for my secure DNS requirement. The included ad blocking was a nice “plus” that helped tip the balance.
Now just to be clear, this won’t get me the anonymity that I would have got had I had gone with a self hosted cloud VPN solution. But I don’t have to pay for hosting and my pings wouldn’t take a hit.
As it always is the case with security; I am trading some convenience for security. Such is life!
I decided to run Pi-hole in a VM on my NAS server (a DIY FreeNAS box), instead of using a Raspberry Pie. This is because I didn’t want to add and manage another piece of hardware on my network. I also decided not take the extra step to setup a recursive DNS server. I am not thaat paranoid.. yet!
Setup Guide
There are some gotchas that you need to be aware of if you are gonna go done the same path as I did. I’ll highlight then as “Gotcha #” in the guide below.
Step 1 : Create a new subnet
This is not required. But I thought I’d setup Pi-hole on a new subnet in my home network. Fresh Start!
- Login to your router’s Admin page
- Change the router’s IP; update new DHCP range to new subnet; delete any IP reservations
- Set static IP for FreeNAS server
I had previously used a IP reservation on my router’s DHCP, but that won’t work going forward because it needs to initialize before the VM with Pi-hole boots up.
Step 2 : Create a new VM
- Create a new VM in FreeNAS
Gotcha #1: 512MB RAM is enough, bump it up to 768MB if you have some to spare. Subjectively, installation and updates seems to run faster with the extra RAM.
Gotcha #2: Use Ubuntu 18.04 LTS server. 20.04 didn’t boot on my FreeNAS 11.2-U8 install
Gotcha #3: Untick the “Delay VM Boot until VNC connects”.. I can’t believe that this is enabled by default - Install Ubuntu server
Gotcha #4: Don’t use pihole as the username; Pi-Hole install creates a user by that name. I’m not sure whether that will break anything. But, let’s pick a different name to be on the safe side
Gotcha #5: Install OpenSSH; skip everything else
Gotcha #6: When it says remove install media and reboot; power the VM OFF via FreeNAS GUI. Remove CDROM from “Devices” menu, before Starting it back up.
Gotcha #7: Optionally, this is a good time to create a clone of the VM as a backup - Connect to VM via SSH. You can use VNC or lookup your routers DHCP list to figure out the IP
Step 3: Setup VM
- Run the following commands to do basic setups
$ sudo dpkg-reconfigure tzdata
$ sudo apt update
$ sudo apt upgrade - Install Cloudflared to use Cloudflare’s DNS over HTTPS service
Follow instructions at https://docs.pi-hole.net/guides/dns-over-https/
Gotcha #8: I preferred the “Automatic” way - Disable Ubuntu’s internal DNS service
$ sudo systemctl stop systemd-resolved.service
$ sudo systemctl disable systemd-resolved.service - Setup a static IP
Follow the instructions here: https://linuxconfig.org/how-to-configure-static-ip-address-on-ubuntu-18-04-bionic-beaver-linux
Gotcha #9: set 1.1.1.1 as temporary nameserver
Step 4: Install Pi-Hole
- Follow instructions at https://docs.pi-hole.net/main/basic-install/
Gotcha #10: “Alternative 2" method worked best for me - During install choose “Custom” for “Upstream DNS Provider” and set the IP address to 127.0.0.1 and port 5053 (as 127.0.0.1#5053)
- After Install completes, run the following command to set Admin panel password
$ sudo pihole -a -p - Run the following command to get the status
$ pihole -c -e - From your browser, go to <Pi-hole ip_address>/admin and make sure everything is OK
- Update netplan config to change the name server to 127.0.0.1
- Reboot VM by running $ sudo reboot
- Login to http://pi.hole/admin; There shouldn’t be any errors
Step 5: Switching DHCP Servers
- Turn ON DHCP from Pi-Hole
- Turn OFF your routers DHCP server
- Reboot router
Congratulations! your privacy is now a little bit more secure!
Closing thoughts
I really like Pi-hole’s DHCP! It’s more feature rich than what my router offered. There is an option to set local domain and set local DNS names too. My device host names now actually show up when I run nmap! Woo!
The Pi-hole dashboard has been pretty good too. You can dig up some interesting insights, like WTF is my TV up to?
Remember to periodically update the block list from the admin panel ->Tools -> Update Gravity.
Also, remember to update Pi-hole once in a while using:
$ pihole -up
It goes without saying.. donate and support!