I have been running pihole for some time on my pi zero and it works great. I've learned a lot since my humble beginnings and want to harden the security on my pi. I want to install Uncomplicated Firewall (ufw) and use it to secure the pi.
My concern is I will somehow break my pihole and hence want to post this message to ensure I am doing things correctly. Since the pihole runs dns and dhcp for my network its crucial I don't break it.
Expected Behaviour:
My intent is to start with denying all connections, then open just what I need.
Restrict SSH to my local network
ufw allow from xxx.yyy.zzz.0/24 to any port 22 proto tcp
Open DNS port 53 to my local network
ufw allow from xxx.yyy.zzz.0/24 to any port 53 proto tcp
Open DNS port 53 to the internet
ufw allow from any to any port 53 proto tcp
Enable firewall
ufw enable
Effectively, this should only allow SSH from my local network and open up DNS port 53 for my local network and the internet. If I do this, will it break the pi? Does the pihole need add'l ports to function properly?
You should not open up the DNS port to the internet! If you have a rearson to access the Pi-hole from outside your network, you should use a VPN instead.
If you're using Pi-hole for DHCP you might need to allow port 67 (maybe 68 too). You should also make sure that localhost can access port 4711 so that things can connect to FTL.
Restrict SSH to my local network
ufw allow from xxx.yyy.zzz.0/24 to any port 22 proto tcp
I'm using DHCP so open port 67 to my local network and internet.
ufw allow from xxx.yyy.zzz.0/24 to any port 67 proto tcp
ufw allow from any to any port 67 proto tcp
(a) Maybe this also for port 68
ufw allow from xxx.yyy.zzz.0/24 to any port 68 proto tcp
ufw allow from any to any port 68 proto tcp
Open port 4711 so FTL can connect
ufw allow from xxx.yyy.zzz.0/24 to any port 4711 proto tcp
ufw allow from any to any port 4711 proto tcp
You shouldn't be opening DHCP to the internet either. Why would the internet want to be assigned an IP from your local DHCP server? Also, you need to open up DNS to the local network.
2. Deny all connections.
ufw default deny incoming
3. Restrict SSH to my local network only
ufw allow from xxx.yyy.zzz.0/24 to any port 22 proto tcp
4. Open DNS port 53 on local network only
ufw allow from xxx.yyy.zzz.0/24 to any port 53 proto tcp
5. I'm using DHCP so open port 67 on my local network only
ufw allow from xxx.yyy.zzz.0/24 to any port 67 proto tcp Maybe this also: ufw allow from xxx.yyy.zzz.0/24 to any port 68 proto tcp
6. Open port 4711 so FTL can connect (local network only)
ufw allow from xxx.yyy.zzz.0/24 to any port 4711 proto tcp
Below one gives you a nice overview of all the daemons that are listening on particular ports:
sudo netstat -nltup
As you can see from below line:
udp 0 0 0.0.0.0:67 0.0.0.0:* 19335/dnsmasq
Its not 67 TCP that needs opening up but 67 UDP.
EDIT: I believe you dont need port 68.
I believe that one is used if Pi-hole were setup to acquire IP through DHCP.
Ohw, and I believe you need to open up DHCP to all 0.0.0.0 as when a client does the request for the first time, it doesnt have an IP address yet
Ohw2, and for DNS, you should open up 53 UDP too.
Both 53 TCP and UDP will work but UDP is supposed to be a little bit faster if have large volume of DNS requests.
But never ever open this one up to the public internet as it will be found and abused for amplification attacks.
It's been 3 years since this topic was active, and I've decided to make a final reply so everyone else can get the final steps based on the comprehensive analysis by deHakkelaar.
I have also added in some of my own tweaks as listed below:
Allow Port 80/TCP from the Local Area Network. This is required if you want to access Pi-Hole's lighttpd Web Admin Dashboard.
Set UFW's default policies (Deny incoming connections, allow outgoing connections)
Changed xxx.yyy.zzz.0/24 to 192.168.1.0/24 to cater to novices. You might need to change this based on your own network configuration i.e. 10.0.0.0/24
THE STEPS:
1. Start by installing Uncomplicated Firewall (UFW)
This is both more restrictive as well as still lacking coverage for some required ports when compared to Pi-hole's prerequisites firewall section, and it seems to cover IPv4 only.
Your 192.168.1.0/24 is specific to your network and may have to be adopted by others.
To avoid this, I guess you could instead cater for the generic private address ranges, which should always work:
so I would assume that it's safer to limit our firewall's permissiveness to reduce the possible attack surface?
However, thanks to reply@Bucking_Horn I've been made aware of Pi-Hole's required ports documentation and realized that we should probably allow all ports ranging from 4711-4720? So our new command would look like this:
sudo ufw allow from 127.0.0.1 to any port 4711:4720 proto tcp
sudo ufw allow from 192.168.0.0/16 to any port 22 proto tcp
4. Open Pi-Hole's Web Dashboard (Port 80 by default) to the local network only
sudo ufw allow from 192.168.0.0/16 to any port 80 proto tcp
5. Open Pi-Hole's DNS (Port 53) to the local network only
sudo ufw allow from 192.168.0.0/16 to any port 53 proto tcp
sudo ufw allow from 192.168.0.0/16 to any port 53 proto udp
6. Open Pi-Hole's DHCP server (IPV4: 67) (IPV6: 547) Note: Only do this if you are using Pi-Hole's DHCP server
sudo ufw allow from 0.0.0.0 to any port 67 proto udp
7. Open Port 4711 for Pi-Hole's FTL (from localhost only)
sudo ufw allow from 127.0.0.1 to any port 4711 proto tcp
8. Enable/reload UFW
sudo ufw enable
or
sudo ufw reload
Additional comments:
I've noticed that the firewall docs for UFW doesn't restrict connections to just the local network. I guess this would be fine if you don't port forward from your router but in my opinion, hardening a firewall would be to set more definitive rules in place I guess?
Oh and one more thing, does anyone know why pihole-FTL's ports 4711-4720 is not explicitly allowed in the UFW docs?
The "localhost interface" on most Linux distro's is named "lo":
pi@ph5:~ $ ip -br -4 address show lo
lo UNKNOWN 127.0.0.1/8
And I believe those 127.0.0.0/8 addresses cant exist/wont work on the regular interfaces for host to host networking.
See below:
If want to post generic firewall rules to cater for everyone, like Bucking_Horn suggested, I would allow the whole IPv4 127.0.0.0/8 subnet + IPv6 ::1 .
Yep I think you're right. We should probably allow the entire 127.0.0.0/8 subnet. Either that, or we could write a ufw rule to allow all connections to port 4711 from the loopback interface?
sudo ufw allow in on lo to any port 4711 proto tcp
This rule even works for IPV6 networks.
Speaking of that, I don't think adding IPV6 rules would be necessary for now because most home users only use IPV4 networks. Furthermore, all ufw rules that I had written previously is very specific to IPV4 networks i.e.
sudo ufw allow from 192.168.0.0/16 to any port 22 proto tcp
is IPV4 only.
I don't think we'll be able to cater to IPV6 users too all in one post cuz if we do that, this post might get so long that it deserves to be an independent wiki
Besides, I don't have much experience with IPV6 subnet notations so I'm a newb at hardening IPV6 networks.
are the ufw rules in this article https://docs.pi-hole.net/main/prerequisites/#ufw up to date ? The SSH port isnt even mentioned... someone could update the ufw part in the prerequisites.. Also what about the Port 4711 ?