There is a lot of things you can do to protect yourself on the internet. One of them is using a firewall. In this post, we are going to configure a firewall for a Debian based Linux distros using iptables.

First, an advice. If you are working remotely (ssh) on a system, be sure to not lock yourself out of the system while playing with this. :) See below for instructions.

Ok now let’s start the configuration. To make sure we are working with a fresh set of rules, we are going to flush the current ones.

sudo iptables -F

This next step is only required if you are using a remote connection (ssh). You need to add a rule to accept yourself. Otherwise, you are going to be locked outside the machine. The -s <ip> is optional. Use it only if you want to control connections by IP:

# Allow SSH connection from an IP Address

sudo iptables -A INPUT -p tcp -s <your_ip_address> -m tcp --dport <ssh_port> -j ACCEPT

Next, we are going to add a protection against common attacks:

# Block null packets

sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# Reject syn-flood attack

sudo iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Reject XMAS packets

sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

Great! We have protection! The next step is optional. We are going to setup the http and https port for a web server. It is usually a good idea to keep these ports closed if you do not intend to use them.

# Do not execute this if you don't want these ports to be open

sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT

If you do not use IPV6, I recommend closing the connections.

# Close IPV6 incomming connections

sudo ip6tables -P INPUT DROP

# Accept IPV6 outgoing connections (from internal)

sudo ip6tables -P OUTPUT ACCEPT

# Block forwarded connections

sudo ip6tables -P FORWARD DROP

# Accept localhost (internal) connection

sudo ip6tables -A INPUT -i lo -j ACCEPT

Next, we close all the incoming connections and accept only the established ones (the ones we ask):

# Accept localhost connection (internal programs to programs)

sudo iptables -A INPUT -i lo -j ACCEPT

# Accept established connection (the ones we ask)

sudo iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# DROP ALL others INPUT/FORWARD connections (block unsolicited connections)

sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP

# WARNING: OUTPUT connections should be closed and configured carefully

# on highly secured systems.

# Accept all OUTPUT connections

sudo iptables -P OUTPUT ACCEPT

By default our new settings are going to be erased every time we restart the system. To make them permanent, we need to install a new tool called iptables-persistent:

sudo apt-get install iptables-persistent
sudo service iptables-persistent start

It can be a repetitive task to do all these commands every time we start a new machine. This is why I have created this bash program to help us:

Once you have learned the commands, you can clone the repos and execute all of them with sh

Have fun!