Configure a firewall to only allow SSH access
by Alex Arica

We are going to create firewall rules using iptables and only allow connections via SSH on port 22.

We assume that we have a server with a network interface “eth0” which has a Public IP address exposing the server to the internet. The interface “eth0” will only allow SSH connections and nothing else.

Using the command "ip a" select the network interface that you want to use and replace "eth0" in the commands below by your interface's name.

Configure the firewall

Check the current iptable rules:

sudo iptables -L -v
sudo ip6tables -L -v

Let’s back-up the existing rules in case of we have to roll back our changes:

sudo iptables-save > rules.v4.backup
sudo ip6tables-save > rules.v6.backup

First, we define the default policy rules:

sudo iptables -P INPUT ACCEPT
sudo ip6tables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo ip6tables -P FORWARD ACCEPT

Then, delete all existing non default rules:

sudo iptables -F
sudo ip6tables -F

We accept already established connections for interface "eth0":

sudo iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

We accept ssh connections for interface "eth0":

sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
sudo ip6tables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

Finally, we drop anythink else on interface "eth0":

sudo iptables -A INPUT -i eth0 -j DROP
sudo ip6tables -A INPUT -i eth0 -j DROP
sudo iptables -A FORWARD -i eth0 -j DROP
sudo ip6tables -A FORWARD -i eth0 -j DROP


Save the changes:

sudo iptables-save
sudo ip6tables-save

Persist the changes on reboot

By default, the changes made to the Firewall using iptables are not persisted and would be lost on reboot. The package “iptables-persistent” allows to persist the iptables rules.

Install "iptables-persistent":

sudo apt-get install iptables-persistent

During the installation, the initial setup will ask to save the rules for IPv4 and IPv6, just select “Yes” and press enter for both. The rules are saved in the file “/etc/iptables/rules.v4” for IPv4 and “/etc/iptables/rules.v6” for IPv6.

Check the iptables rules are saved by "iptables-persistent":

cat /etc/iptables/rules.v4
cat /etc/iptables/rules.v6

“Iptables-persistent” is a service which starts automatically on each reboot and loads the iptables rules from the folder “/etc/iptables/”.

Check the service is running:

sudo systemctl list-unit-files --state=enabled | grep netfilter-persistent.service

Manually reboot the server :

sudo reboot

After reboot, connect to the server and check that the current iptable rules are the ones that were persisted:

sudo iptables -L -v
sudo ip6tables -L -v

From your local computer, check that only port 22 is opened from outside by using the command "nmap":

sudo nmap -Pn [server's public IP]
Starting Nmap 7.80 ( ) at 2021-04-05 15:55 BST
Nmap scan report for [server's hostname] ([server's public IP])
Host is up (0.026s latency).
Not shown: 999 filtered ports
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 8.66 seconds

The firewall rules are ready.

Considerations for future changes to iptables rules

On reboot, “iptables-persistent” read the firewall rules from the folder “/etc/iptables/”. And each time we make changes using the commands "iptables" and "ip6tables", we need to make sure that those changes are persisted for next reboots by updating the files in the folder “/etc/iptables”.

Once we made the changes, we are going to use the commands "iptables-save" and "ip6tables-save" in order to persist those changes.

First, we become root so that the files have specific linux permissions when persisted:

su -

Persist the firewall rules:

iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

Exit from root:


The changes are persisted.

Additional useful commands

Restores backed-up iptables rules:

sudo iptables-restore < [path to the backed-up v4 file]
sudo ip6tables-restore < [path to the backed-up v6 file]

Delete all custom user-defined iptables rules so that only the default policy rule will be used:

sudo iptables -X
sudo ip6tables -X

Additional readings about iptables