bit-tech.net

Build your own Router

About Tables, Chains and Processing

Before we can start writing our own firewall rules, we need to have some understanding of how iptables actually works. It all starts with tables, which many of you have already guessed by the name.

Tables are really categories for iptables to know what to do with different package headers. There are three main tables: filter, NAT and mangle. The easiest table is the "mangle" table - it's responsible for quality of service, and alters the TCP headers of the data packet accordingly. Because most don't use QoS on their networks, this also is the least used table.

The second table is the NAT table. This table takes care of the address translations in the data packets header file. By default, it has two "chains", PREROUTING and POSTROUTING. As the name of the chains imply the former occurs before the NAT translation, and the latter occurs after the NAT translation. A chain is nothing more than a sequence of rules that either match or don't. If there is a match to a rule, the firewall will take a specific action, which is defined by the rules. Actions can include (among others) ACCEPT, DROP, REJECT, LOG.

The filter table is the one responsible for packet filtering. It consists of three chains. INPUT, OUTPUT and FORWARD, which define what is going to happen with the data packet once it's run through the corresponding chain. Everything that's meant for the firewall box goes into the INPUT chain, all data originating from the firewall goes through the OUTPUT chain and all the data that is forwarded through the firewall to computers inside the network goes through the FORWARD chain.

The rules for each table and its chains make up the blocks of all iptables scripts. They start with the declaration of a couple of variables which will be used further down the script, setting some parameters for the system, defining firewall rules and then opening up needed ports and defining forwardings.

In this article I'll build up a basic iptables script. It will show the basics of what is possible, but it won't be a copy/paste solution for most situations, because every situation is different. What it will do is give you the fundamentals to build and tweak your own.

So fire up your favourite text editor. Let's start by setting some variables for the script to use.
# Determine interfaces

EXTIF="eth0"

INTIF="eth1"

# Loop device/localhost

LPDIF="lo"

LPDIP="127.0.0.1"

LPDMSK="255.0.0.0"

LPDNET="$LPDIP/$LPDMSK"


# Internal servers IP (static)

#SERVERIP=10.0.1.2


# Text tools paths

IFC="/sbin/ifconfig"

G="/bin/grep"

SED="/bin/sed"

AWK="/usr/bin/awk"

ECHO="/bin/echo"

export LC_ALL="en"


# Setting up external interface environment variables

EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"

EXTBC="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"

EXTMSK="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"

EXTNET="$EXTIP/$EXTMSK"


# Setting up internal interface environment variables

INTIP="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"

INTBC="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"

INTMSK="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"

INTNET="$INTIP/$INTMSK"
The main things in this piece of code are the EXTIF and INTIF variables. Here we define what interface is connected to what network. EXTIF is what is connected to the big, bad interwebs. INTIF is your comfy, secure home network. Another important part is the Internal servers IP section. If there are systems on your network that require ports to be forwarded to, you define their IP address over here.

Next up is to load some kernel modules and allow the system to do NAT translation. NAT handles the actual routing function of the machine. When a data packet arrives on the external interface that is meant for an internal computer, the destination IP address will be altered by the NAT table. This is done because the destination of the original packet was your external IP address, but the actual destination internally is the machines IP address. This process is called Network Address Translation, hence the name NAT.

# Load Kernel modules

modprobe ip_conntrack

modprobe ip_conntrack_ftp

modprobe ip_nat_ftp

modprobe ip_nat


# Enable forwarding

echo 1 > /proc/sys/net/ipv4/ip_forward


# Enable NAT translation (MASQUERADE)

iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE
Now we have a system that's ready for some hefty firewall rules...