View the updated 2022 version here.
Using IPTables on your Raspberry Pi
When exposing your device to the outside world you want to make sure you add a firewall this will keep nasty intruders out. This is not an “end-all” solution, but you want to limit access to ports people do not need access to. There are lots of solutions you could use as your firewall, most are built on top of Linux iptables. So we will just use iptables themselves.
sudo apt-get update
sudo apt install iptables-persistent -yThis will install iptables-persistent and any dependencies. Next, we need to set up some basic rules, please make sure to set up rules for the services you are using or you will be blocked from them by the firewall.
sudo iptables -F
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -A INPUT -i lo -j ACCEPTFirst please note all commands use sudo, you need higher privileges to add firewall rules. Using the above rules we block some basic attacks we will start adding rules to open specific ports we will use. So I will list the service and then the command to open the port. We could go more in-depth and allow connections only from certain IPs.
Allow SSH connections (*Important if you want to use SSH to manage your Pi*)
sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPTAllow HTTP server
sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPTAllow HTTPS server
sudo iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPTSMTP server
sudo iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 465 -j ACCEPTPOP3 server
sudo iptables -A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 995 -j ACCEPTIMAP server
sudo iptables -A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 993 -j ACCEPTHome Assistant
sudo iptables -A INPUT -p tcp -m tcp --dport 8123 -j ACCEPT
You may have other services you want to accept connections to, we can add more rules for any port with a simple command just replace [TYPE] with the type of connection TCP, or UDP. Replace [PORT] with the port you will be accepting connections on.
sudo iptables -A INPUT -p [TYPE] -m [TYPE] --dport [PORT] -j ACCEPTFinally, we need to allow outgoing connections we will need our machine to be able to update, use wget or other outside connections.
sudo iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -P OUTPUT ACCEPT && sudo iptables -P INPUT DROPSo now we have all our rules added, but do we actually? Let’s double-check by running the following:
sudo iptables -L -nWe can save the rules using iptables-persistent using:
sudo iptables-save >/etc/iptables/rules.v4
sudo ip6tables-save >/etc/iptables/rules.v6And we are all done! Our system is more secure than it was before and it didn’t even take too long! Please note adding these rules is not a solution to solve all your problems. It just adds one more layer of security, finding open ports is half the battle when cracking a machine. Check out more security-related articles. You can also check out the man pages.
