About 2 years ago, I started running Pi-hole as a DNS resolver and ad-blocker. Then last year, I ditched it.
After seeing a recent post by Troy Hunt, though, I thought it might be worth revisiting..but I needed a better way to control how it worked.
Enter OpenVPN – a service I already run on three endpoints. Here’s what I did:
Install Pi-hole per the usual (curl -sSL https://install.pi-hole.net | bash
if you’re feeling brave, curl -sSL https://install.pi-hole.net
, inspect, then run, if you’re feeling a little more wary).
This time, though, I set my upstream DNS providers to Cloudflare (1.1.1.1) and Quad9 (9.9.9.9) instead of Freenom and Google.
I also did a two-step install – once with Pi-hole listening on the primary network interface on my OpenVPN endpoint (ie the public IP), and then, once I made sure all was happy, I flipped it to listen on tun0
– the OpenVPN-provided interface. This means Pi-hole can only hear DNS queries if you’re connected to the VPN.
Why the change from how I’d done it before? Two reasons (at least):
First, if you leave Pi-hole open to the world, you can get involved in DNS amplification attacks. That is muy no bueno.
Second, sometimes I don’t care about ads – sometimes I do. I don’t care, for example, most of the time when I’m home. But when I’m traveling or on my iPhone? I care a lot more then.
Bonus – since it’s only “working” when connected to my VPN, it’s super easy to check if a site isn’t working because of Pi-hole, or because it just doesn’t like my browser (hop off the VPN, refresh, and see if all is well that wasn’t when on the VPN).
Changes you need to make to your OpenVPN’s server.conf
:
push "dhcp-option DNS 10.8.0.1"
This ensures clients use the OpenVPN server as their DNS resolver. (Note: 10.8.0.1 might not be your OpenVPN parent IP address; adjust as necessary.) Restart OpenVPN after making this change.
My setupVars.conf for Pi-hole:
PIHOLE_INTERFACE=tun0
IPV4_ADDRESS=10.8.0.1/24
IPV6_ADDRESS=
QUERY_LOGGING=true
INSTALL_WEB_SERVER=true
INSTALL_WEB_INTERFACE=true
LIGHTTPD_ENABLED=false
WEBPASSWORD=01f3217c12bcdf8aa0ca08cdf737f99cd68a46dbdc92ce35fd75f39ce2faaf81
DNSMASQ_LISTENING=single
PIHOLE_DNS_1=1.1.1.1
PIHOLE_DNS_2=1.0.0.1
PIHOLE_DNS_3=9.9.9.9
DNS_FQDN_REQUIRED=true
DNS_BOGUS_PRIV=true
DNSSEC=false
CONDITIONAL_FORWARDING=false
I tried getting lighttpd to only listen on on port 443 so I could use Let’s Encrypt’s SSL certs following a handful of tutorials and walk-throughs, but was unsuccessful. So I disabled lighttpd, and only start it by hand if I want to check on my Pi-hole’s status.
Speaking of which, as I write this, here is what the admin console looks like:
Hope this helps you.