I’ve been running pihole on my NAS for a while. My router is configured to use the NAS as its primary DNS, meaning all the devices on my network get configured to use the pihole resolver. Running it on my NAS server is not ideal though, because when I do maintenance on the NAS, all the devices on the network start having issues because the DNS resolver is down. I’ve tried providing a secondary DNS resolver to my router for cases like this, but it ends up making pihole useless because ads are able to get through on the devices even when the primary resolver is up.
So I decided to try to host pihole on an inexpensive VPS. The only issue is that it’s not recommended to host a publicly accessible DNS resolver. It can be used in DNS amplification attacks. The plan to avoid this issue is to use a firewall which only allows IPs, and IP ranges I have vetted to access pihole. My home IP address is for the most part static, it hasn’t changed it years as far as I can tell. This might not be a good solution if your home IP address changes often.
pihole setup
My VPS is running Debian 11 with a couple of services like my website, my blog, Gitea, and others. It already has
docker installed on it. I installed pihole using a systemd unit file which simply spawns docker run
:
|
|
Followed by systemctl enable pihole.service
and systemctl start pihole.service
. Port 50010 is for the pihole WebUI,
my nginx
server has a proxy pass to it when the hostname pihole.sbstp.ca
is used.
ufw setup
The next step is to secure access to the resolver. I decided to use ufw
(apt-get install ufw
) for this task, but any
firewall would do. Some VPS providers have built-in firewalls that can be used. Still, I prefer to control everything at
the OS level. ufw
is a frontend for iptables and it simplifies things a lot. It’s a nice project.
There is one issue though, ufw
and docker
both play with iptable rules, and create imcompatible rules. Luckily
though, there’s a project called ufw-docker
which has instructions on how
to setup ufw properly.
The TL;DR is that you append the text below to /etc/ufw/after.rules
, which makes docker
and ufw
get along.
|
|
After this you should restart ufw
, e.g. systemctl restart ufw
.
Now you can setup ufw
:
- Allow ssh
ufw allow ssh
(shortcut for22/tcp
). - Allow other ports such as 80, 443, etc.
ufw allow 443/tcp
. - Allow udp packets coming from your home IP to be forwarded to the docker container
ufw route allow proto udp from <HOME_IP> to any port 53
. Note that this is using the internal docker port, not the external one. Seeufw-docker
for more details. - Enable
ufw
,ufw enable
. - Check status,
ufw status
.
You can also allow friends & family to access the resolver by running the
ufw route allow proto udp from <HOME_IP> to any port 53
command again and changing the IP to theirs.
Conclusion
You can test that everything works well by using dig
(apt-get install bind9-utils
). dig @<VPS IP> google.com
resolves google.com using your DNS resolver. Make sure to run the dig
command from within the network you want to run
behind pihole.
Now that all that setup is done, you can set the VPS’ IP to be the only DNS resolver in your router, and that should spread to all your devices in a few hours.