Home
Physics
Lab
Linux
Mirrors

A Simple Linux Firewall

Update

I recently discovered that the iptables initscript is now deprecated.

I've written my firewall script into a simple init script (download here). You should copy this file into /etc/init.d, make it executable, and then add the needed rc.d symlinks using update-rc.d:

 update-rc.d firewall start 40 S . stop 89 0 6 . 

Firewall info

I recently wanted to install a personal firewall on a standalone linux computer. I was looking for a configuration program or script that was simple enough that I could understand what it was doing, but flexible enough that I could easily select the services I wanted to allow. Most of the solutions I found were either overcomplicated and confusing, or vastly oversimplified (too many "wizards").

In the end, I decided the best solution was to write my own script. It is very simple and short (~70 lines with comments). I decided to post it here to help others understand IPTables based firewalls so they can write thier own scripts. You can download it here.

Running this script once will generate a set of firewall rules that perform the actions I was looking for. Using the /etc/init.d/iptables script included in debian, I could then save this as the default "active" state for my firewall, resulting in this set of rules being loaded automatically on startup.

 
#!/bin/bash 

set -x

# Load needed kernel modules

modprobe ip_conntrack
modprobe ip_conntrack_ftp

# Clear any existing firewall stuff before we start

iptables --flush
iptables -t nat --flush
iptables -t mangle --flush

# As the default policies, drop all incoming traffic but allow all
# outgoing traffic.  This will allow us to make outgoing connections
# from any port, but will only allow incoming connections on the ports
# specified below.

iptables --policy INPUT DROP
iptables --policy OUTPUT ACCEPT

# Allow all incoming traffic if it is coming from the local loopback device

iptables -A INPUT -i lo -j ACCEPT

# Related and established connections: see 
#  http://www.sns.ias.edu/~jns/security/iptables/iptables_conntrack.html
#
# Accept all incoming traffic associated with an established
# connection, or a "related" connection
#
# This will automatically handle incoming UDP traffic associated with
# DNS queries, as well as PASSIVE mode FTP (provided the
# ip_conntrack_ftp module is loaded)

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

# Allow connections on selected ports to the firewalled computer:
#   22 ssh
#   80 web
#   25 smtp (mail)

iptables -A INPUT -p tcp -i eth0 --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 25 -m state --state NEW -j ACCEPT

# Allow icmp input so that people can ping us

iptables -A INPUT -p icmp -j ACCEPT

# Logging: first, eliminate any packets that are going to broadcast
# addresses, since they will overwhelm the log files if there are any
# windows computers on our network. Also, don't log pesky multicast
# packets that we block. 

iptables -A INPUT -d 255.255.255.255/0.0.0.255 -j DROP
iptables -A INPUT -d 224.0.0.1 -j DROP

# Log all other blocked packets, and change DROP to REJECT to be
# polite and allow people connecting to a blocked port to receive a
# "connection refused" message instead of timing out after 30 seconds.

iptables -A INPUT -j LOG
iptables -A INPUT -j REJECT