iptables basic firewall

Netfilter IPTables is Linux kernel implementation of software firewall. Let build a basic minimal firewall.

Let start by assuming we have a server where we have a web server listening on port 80 and 443 and SSH on port 22. We want to allow incoming connection to only these ports, traffic to any other port is denied.
With iptables we can do this by running these rules

iptables -P INPUT DROP # set default policy to drop all incoming connections

# allow unrestricted traffic to loopback interface
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# we want to allow all established and related connections
iptables -A INPUT -j ACCEPT -m state --state RELATED,ESTABLISHED

# Allow incoming traffic to SSH
iptables -A INPUT  -p tcp --dport 22  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22  -m conntrack --ctstate ESTABLISHED -j ACCEPT

# Allow incoming traffic to HTTP
iptables -A INPUT  -p tcp --dport 80  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80  -m conntrack --ctstate ESTABLISHED -j ACCEPT

# Allow incoming traffic to HTTPS
iptables -A INPUT  -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443  -m conntrack --ctstate ESTABLISHED -j ACCEPT

# finally make sure nothing comes in, this should be the last rule.
iptables -A INPUT -j DROP

We have got out basic firewall ready, ssh is still open to public, what if we want to restrict access to ssh from specific IPs only say 1.1.1.1 and 2.2.2.2, the new rules for SSH will be like

iptables -A INPUT -s 1.1.1.1/32 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -s 2.2.2.2/32 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22  -m conntrack --ctstate ESTABLISHED -j ACCEPT

FTP is a special case, it uses port 20(ftp data), 21(ftp control) and passive ports above 1023.
We will allow passive ports 22000-24000 for data transfer

iptables -A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 21 -j ACCEPT

# Assuming we use port 22000 - 24000 for passive ftp
iptables -A INPUT -p tcp -m tcp --dport 22000:24000 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 22000:24000 -j ACCEPT

We are now ready accept FTP connections.

So far we have mostly firewalled TCP traffic, let now check DNS which listens on both TCP and UDP port 53. The rules for this will be

iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT

iptables -A OUTPUT -p tcp -m tcp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp -m udp --sport 53 -j ACCEPT

Our basic firewall is now ready which allow traffic to only restricted ports. The final rules will be like

iptables -P INPUT DROP # set default policy to drop all incoming connections

# allow unrestricted traffic to loopback interface
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# we want to allow all established and related connections
iptables -A INPUT -j ACCEPT -m state --state RELATED,ESTABLISHED

# Allow incoming traffic to SSH
iptables -A INPUT  -p tcp --dport 22  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22  -m conntrack --ctstate ESTABLISHED -j ACCEPT

# Allow incoming traffic to HTTP
iptables -A INPUT  -p tcp --dport 80  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80  -m conntrack --ctstate ESTABLISHED -j ACCEPT

# Allow incoming traffic to HTTPS
iptables -A INPUT  -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443  -m conntrack --ctstate ESTABLISHED -j ACCEPT

# FTP traffic
iptables -A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 21 -j ACCEPT

# Assuming we use port 22000 - 24000 for passive ftp
iptables -A INPUT -p tcp -m tcp --dport 22000:24000 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 22000:24000 -j ACCEPT

# Allow DNS
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT

iptables -A OUTPUT -p tcp -m tcp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp -m udp --sport 53 -j ACCEPT

# finally make sure nothing comes in, this should be the last rule.
iptables -A INPUT -j DROP

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Leave a comment

Your email address will not be published. Required fields are marked *