01-12-2019, 12:47 PM
Basic secure Firewall setup with iptables
Hi!
This brief tutorial will teach you how to peform a basic secure Firewall setup on any Linux based server (any type of server: dedicated server, VPS, etc...) with the iptables Firewall software.
At the end of this guide you will be able to establish basic guidelines in terms of Firewall security and you will be able to control access in and out of your server. This will help to minimize attack vectors and reduce the risk level of getting your server hacked.
I will be covering the IPv4 setup only! IPv6 is a little different and the same rules for IPv4 will absolutely not work with IPv6. In fact the IPv4 iptables rule set for IPv6 will break IPv6 inside your server entirely. This is kind of a personal experience from the past .
This brief tutorial will teach you how to peform a basic secure Firewall setup on any Linux based server (any type of server: dedicated server, VPS, etc...) with the iptables Firewall software.
At the end of this guide you will be able to establish basic guidelines in terms of Firewall security and you will be able to control access in and out of your server. This will help to minimize attack vectors and reduce the risk level of getting your server hacked.
I will be covering the IPv4 setup only! IPv6 is a little different and the same rules for IPv4 will absolutely not work with IPv6. In fact the IPv4 iptables rule set for IPv6 will break IPv6 inside your server entirely. This is kind of a personal experience from the past .
Step One
Flush (delete) all current iptables rules with the two commands below:
Code: (Select All)
iptables -F
iptables -X
Step Two
Setup the main iptables policies to block everything incoming/forwarded by default and allow outgoing traffic to the Internet by default with the commands below:
Code: (Select All)
iptables -P FORWARD DROP
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
Incoming traffic is blocked by default unless allowed through additional rules.
Forward traffic is blocked by default unless allowed through additional rules.
Outgoing traffic is allowed by default unless blocked through additional rules.
Step Three
Allow incoming responses to outgoing Internet traffic on already established connections with the command below:
Code: (Select All)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
This is very important. It will allow to receive replies for connections that you initiated. For example you initiate a download via wget. If you don't set this rule up you won't be able to download anything because your server blocks the download of the file. Or initiating a PING will lead to not receiving replies from the host you pinged.
Don't miss this rule or any kind of communication with the Internet will totally break.
Step Four
Allow local traffic on the loopback network with the command below:
Code: (Select All)
iptables -A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT
With this rule you enable local traffic within the server (remember the default incoming policy is set to block unless allowed through additional rules). This rule is also important to have a working internal network on the VPS. It allows access to locally hosted services like MySQL on 127.0.0.1/localhost and etc.
Don't miss this rule either as it also is very important.
Step Five
Allow incoming traffic to services hosted on your server like SSH, webserver and etc (following command is an example for a server with SSH and a webserver only):
Code: (Select All)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
Other services can be allowed through this same rules. Just adjust the port and protocol if needed.
Another example for FTP (TCP Port 21):
Code: (Select All)
iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
A example for DNS (UDP Port 53):
Code: (Select All)
iptables -A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
You can also allow incoming traffic for certain IP addresses only with the command below (remember to adjust the IP, protocol and port for the corresponding service):
Code: (Select All)
iptables -A INPUT -s 187.123.100.231 -p tcp --dport 3128 -m state --state NEW -j ACCEPT
This will allow connections to port 3128 TCP (SQUID PROXY) only for the IP address 187.123.100.231. Such restrictive rules are great to secure SSH for your own IP address (if you have a static IP address). So no on else other than you can connect to the service/server on that port.
You can also allow IP address ranges:
Code: (Select All)
iptables -A INPUT -s 123.231.67.0/24 -p tcp --dport 22 -m state --state NEW -j ACCEPT
This rule would allow connections to SSH from the IP address range 123.231.67.1 to 123.231.67.254. This can be useful if you want to allow a specific IP ranges to access your server (if you have a dynamic IP address that is always in the same range). It is important to use the right netmask when working with subnets and ranges!
As iptables rules are not persistent across reboots you can simply paste all the rules into a shell script and let this script run at boot to apply the rules when you start or reboot the server.
Simply open a new empty file called "firewall.sh" with nano or another text editor. Paste all the commands into that file and save it. Apply the right permissions so it can be executed with chmod +x firewall.sh. Use crontab or /etc/rc.local to add the script to startup. If you don't know how to do it exactly feel free to ask and I will explain it in an additional post.
Alternatively you can install the package iptables-persistent. This will allow you to change iptables rules and they will survive across reboots. Always remember to save rules when changing them! Same applies for the method with the shell script. When you change rules or add new rules make sure you add them to the firewall.sh file and save it.
That's about it. You have setup the basic policies to block everything other than outgoing traffic. Then you have created rules to allow specific services to be accessed. You created rules to allow local traffic inside the server and also created a rule to allow automatic unblocking of replies to connections you have initiated.
You can use the same rules to extend your setup for future services and projects. Feel free to ask any questions.