Iptables is installed by default on many modern linux distros.
A good starting point is to list the current rules that are configured for iptables. It is done with the -L
flag:
sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Setting it up
I am going to start with the rule that explicitly accepts current SSH connection:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
then I will allow SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
meaning of the options:
-A INPUT: The -A
flag appends a rule to the end of a chain. This is the portion of the command that tells iptables that we wish to add a new rule, that we want that rule added to the end of the chain, and that the chain we want to operate on is the INPUT chain
-p tcp: This option matches packets if the protocol being used is TCP. This is a connection-based protocol that will be used by most applications because it allows for reliable communication.
–dport: This option is available if the -p tcp
flag is given. It gives a further requirement of matching the destination port for the matching packet. The first rule matches for TCP packets destined for port 22, while the second rule matches TCP traffic pointed towards port 80.
-j ACCEPT: This specifies the target of matching packets. Here, we tell iptables that packets that match the preceding criteria should be accepted and allowed through.
There is one more accept rule that we need to ensure that our server can function correctly. Often, services on the computer communicate with each other by sending network packets to each other. They do this by utilizing a pseudo network interface called the loopback device
, which directs traffic back to itself rather than to other computers:
sudo iptables -I INPUT 1 -i lo -j ACCEPT
-I INPUT 1: The -I flag tells iptables to insert a rule. This is different than the -A flag which appends a rule to the end. The -I flag takes a chain and the rule position where you want to insert the new rule.
To see my current rules, I use the -S
flag. This is because the -L
flag doesn’t include some information, like the interface that a rule is tied to:
sudo iptables -S
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
With my current setup the firewall isn’t actually blocking anything so one last thing to implement is the Drop Rule:
sudo iptables -P INPUT DROP
This will catch any packets that fall through our INPUT chain, and drop them. This is what we call a default drop policy.
In case I need to add more rules:
iptables -L --line-numbers
that will give you output listing line numbers – so if for example I have 20 existing rules and I want to add this rule at the end I would type:
iptables -I INPUT 21 ...........
for example:
iptables -I INPUT 21 -p tcp -m tcp --dport 25 -j ACCEPT
Saving it all
To keep the config we need to save it. First install the bits we will need:
apt-get install iptables-persistent
that will install and setup iptables-persistent service
the iptables config will be saved to:
/etc/iptables/rules.v4
the command to save the config is:
iptables-save > /etc/iptables/rules.v4
Job Done