I'm always seeing people playing with iptables, in seemingly "the hard way". I'm always seeing people entering and removing rules very manually. There is an easier way!! There is still a bit of a learning curve involved, but this essentially blocks ALL traffic, unless you explicitly set a rule for it.
A while back, I found a good read on How to set up a secure Raspberry Pi web server, mail server and Owncloud installation.
Within this guide is a demonstration of how to easily manipulate iptables, without it being terribly difficult.
I'm going to focus on the section titled
"Creating a Firewall"
These will need to be tweaked a bit to work for pihole's dhcp and dns,,, as well as any custom stuff you plan on doing. I mostly want to focus on the ease of using this method.
If any of you have played with iptables much, you have run sudo iptables -L
to see what rules you have in place.
Create a file to hold your firewall rules by entering the following command:
sudo nano /etc/iptables.firewall.rules
This will be the file that we keep all of our rules. These are the rules borrowed from the page linked above. I'll try and explain rules that I have tweaked for my own setup later.
*filter
# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT
# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allows SMTP access
-A INPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --dport 465 -j ACCEPT
-A INPUT -p tcp --dport 587 -j ACCEPT
# Allows pop and pops connections
# -A INPUT -p tcp --dport 110 -j ACCEPT
# -A INPUT -p tcp --dport 995 -j ACCEPT
# Allows imap and imaps connections
-A INPUT -p tcp --dport 143 -j ACCEPT
-A INPUT -p tcp --dport 993 -j ACCEPT
# Allow SSH connections
# The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# Allow ping
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT
ctrl+x and press y to save
This command takes the file you created, and doesn't just merge into iptables, but the rules you place here, replace everything in iptables. if you rerun sudo iptables -L
you will find your new rules in place.
sudo iptables-restore < /etc/iptables.firewall.rules
You will want these rules to be enforced at boot.
sudo nano /etc/network/if-pre-up.d/firewall
Then enter
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules
Then
ctrl+x and press y to save
Then to set permissions for this new bash file.
sudo chmod +x /etc/network/if-pre-up.d/firewall
An idea I just had writing this, is to set up a cronjob for this. You could potentially have it rewrite your iptables every 6 hours, since I just had this idea, I can't confirm that it works, use at your own discretion.
Crontab -e
Then add:
0 */6 * * * sudo bash /etc/network/if-pre-up.d/firewall
Things you will have to tweak:
-
I had an issue connecting devices to my network, and I realized that I wasn't allowing DHCP ports. I opened ports 67 and 68 in my rules,, and devices started getting leases again.
-
I use xrdp now, because I was playing with iptables, and inadvertently locked myself out of ssh. I had to use the following ports: 3389 , 3350 , 5910 . xrdp, allows you to remote-in, fix ssh, and then use terminal in putty like normal.
-
If you use Fail2Ban, you will need to set a rule.
-
If you use OpenVPN, you may need to allow port 1194.
-
Any other webservice you use, you will need to allow traffic on those ports.
-
If you use Squid or Privoxy, you could potentially reroute all traffic using iptables. I personally haven't gotten that to work yet, but the rule suggested goes something like (Do NOT place it anywhere between *filter and COMMIT):
*nat
-A PREROUTING -i tun0 -p tcp --dport 80 -j REDIRECT --to-port 8118
COMMIT
- Also within
*nat
you would place This rule autogenerated by openvpn
-A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source IPADDRESSOFPI