iptables is the userspace software generally associated with the Linux kernel based netfilter firewall. iptables is a tool by which the kernel based firewall (netfilter) can be configured.
There are a lot of iptables howto pages on the web, but most concentrate on the subtleties of netfilter and iptables. Unfortunately this leaves the average user, looking to gain a foothold in adding some security to their Linux system, a bit out in the cold. The learning curve is a little too steep so most users tend to just run without a firewall.
Most SOHO (Small Office Home Office) users tend to run a dedicated router with inbuilt ADSL modem and hub. These devices normally come with a firewall that does NAT (Network Address Translation) allowing for the internal LAN to be on a subnet. This setup tends to work ok, and most of the firewalls are setup to block service requests from the net whilst allowing requests that originate from the LAN to connect to hosts that offer services on the net.

This style of setup has been around for a while now, and it is not inconceivable that there exists exploitations for old hardware routers. So, it is prudent to move some protection to the hosts on the LAN as well.
This primer page deals with the basic setup of an iptables / netfilter firewall. I won't be discussing how to configure the kernel or ensure that iptables runs on a reboot, for those issues please check documents from your distribution. I will be dealing with how a netfilter firewall is configured with iptables, and hopefully demystifying some of the more confusing conventions.
If you want a secure firewall setup for a business then your best bet is to get in a security consultant, but if you want to learn how to do it yourself, or just get some quick added protection this page should give you the first steps in achieving this.
If you after just a quick way to configure netfilter then the GUI Firestarter may be what you want.
If you answer no to the first two assumptions, then please check your distribution iptables howto.
If your host is not connected to a dedicated router please be aware that I do not deal with NAT in this howto, though you may still find this primer useful as a step before understanding NAT.
If you don't know how to get iptables to restore the rules upon reinitializing the system, please check your distribution iptables documentation. You can still do the howto, but of course you may have to run it each time you restart the system.

netfilter is configured using iptables from the command line or by restoring rules.
The above is the first point of confusion for most, there are two ways to configure netfilter. Either through iptables commands or to write / alter a config file that iptables-restore can load into netfilter.
Most tend to use the 'iptables from command line' method by writing a shell script. This is quite a flexible method and allows shell scripting techniques to be used, but this is the major reason why people find netfilter configuration confusing; you have to know shell scripting as well.
netfilter firewall rules are normally debugged and discussed by looking at the configuration output of the iptables-save command and there exists the iptables --list command which gives a summary of the rules.
The multiple ways of accessing the same rules, and the many ways that these rules can be expressed, also tends to add to initial confusion a bit. Standard response to this is firewalls are complicated beasts. And that is true, but people still need that foothold to help in understanding further.
I will be using the script method of rule configuration. To restore the firewall though I will be using the iptables-save method, after applying the script to generate a rules file that iptables-restore will use.
Well, if you are still here good. I could have just started here, but the above is there to let you know you are not alone.
When I first looked into ipchains (predecessor to iptables) I scratched my noggin a bit, trying to grasp the way it worked.
ipchains example scripts were full of odd sed and awk commands, and then the format would suddenly change. Whilst it was well written, the temptation to copy verbatim without understanding was considerable.
I wanted the embryo of a firewall, I wanted just the basic bits to give some protection. I was intrigued by things such as rate detection, queues, netlinks. I didn't need a NAT, I already had one but of course I could setup a subnet within a subnet. In short I was overwhelmed by all the sparkling trinkets of netfilter but had no foundation to get to these elusive oddities short of a yank, a put and a prayer.
A firewall has to be there to protect; configure the firewall incorrectly and you lessen your security and/or usability; the foundation of the firewall is an important thing.So, I set about getting to the basics, within a short time I had them, and from there firewall configuration was a joy. I even started constructing elaborate script based libraries; unfortunately these seemed to have been erased from an old system, though I probably have a backup somewhere.
Recently though a lot of folks have been coming over to the Linux camp, and I have noticed their confusion when it comes to iptables. They want some protection, and rightly so, but most of the howtos are just going over their heads. So, I searched the web, and yes in fact the netfilter howtos are probably more confusing for someone new to netfilter then they were in the past. Hopefully this primer is here to redress the balance a bit.
When the penny does drop, iptables becomes a great way to configure your firewall, and you really start to appreciate what a powerful firewall Linux comes bundled with.
It is a good idea to outline in words what you want from the firewall.
SSH is the only service to be allowed access to from external machines. Must be able to access services on external machines. Any services running on the host should only be accessible by the host (apart from ssh).
This policy allows the user access to services offered on the net and their local box. In the eventuality of a host on the LAN being compromised only SSH will be available.
SSH is offered as an example of a service, though SSH is also a good administration tool for a LAN. If you have only one host behind the router, dropping SSH requirement will increase security levels.
#!/bin/sh
# variables
IPT=/sbin/iptables
LOC=lo
IF0=eth0
#-----------------------------------------------------------
# policies set to drop
$IPT -P OUTPUT DROP
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
#-----------------------------------------------------------
# flush iptables and clear chains
$IPT -F
$IPT -X
#-----------------------------------------------------------
# default policies
$IPT -P OUTPUT ACCEPT
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
#-----------------------------------------------------------
# input
# localhost allow
$IPT -A INPUT -i $LOC -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
# ssh allow
$IPT -A INPUT --protocol tcp -s 192.168.0.0/24 --dport 22 \
-j ACCEPT
# established connections allow
$IPT -A INPUT -i $IF0 \
-m state --state ESTABLISHED -j ACCEPT
#-----------------------------------------------------------
# clearup
IPT=
IF0=
LOC=
#-----------------------------------------------------------
... and that is it really, but you don't just want to yank, put and pray that script in as your firewall, so let's step through the script.
#!/bin/sh
This is the shebang line, it could have been #!/bin/bash as sh is normally symlinked to bash on Linux systems. This line tells us that the following code is shell script and if the file is made executable that the shell will be used to interpret the code.
# variables IPT=/sbin/iptables LOC=lo IF0=eth0 #-----------------------------------------------------------
Variables are used for flexibility, and or conciseness. It is good form to address an executable directly using the full path name, especially when dealing with any security matter, put the command into a variable helps keep things a little shorter and of course if the command name or location changes there is only one place to change it. IF0 refers to the interface you normally use to route off your system, please check this is the correct one for your system, wifi users could get caught out.
# policies set to drop $IPT -P OUTPUT DROP $IPT -P INPUT DROP $IPT -P FORWARD DROP #-----------------------------------------------------------
The above sets netfilter into a very restrictive set of policies, ie it drops everything, whilst we make alterations to the firewall.
-P stands for policy and it is applied to a chain (hook), of a table. In the case of the filtering table the default chains are OUTPUT, INPUT and FORWARD hooks. Only the builtin in targets ACCEPT and DROP can be used for the builtin chains when defining policy.
Policy is what to do when a packet reaches the end of a chain without being assigned a specific target. In this case we are going to drop them.
There is something important to realise about INPUT and OUTPUT, they refer to actual traffic not the concept of who called who. So, any given request generally involves both INPUT and OUTPUT traffic. If you wish it may make it simpler to think of OUTPUT as a mouth and INPUT as ears, the process can be a mind. So, the above policies basically stick your fingers in your ears and keep your mouth zipped.
We are not really interested in FORWARD at the moment so DROP is more secure to us than ACCEPT.
# flush iptables and clear chains $IPT -F $IPT -X #-----------------------------------------------------------
The above two commands clear out netfilter chain rules and deletes any user-defined chains.
-F (--flush) flushes out the rules deleting them one by one.
-X (--delete-chain) deletes all the user defined chains.
At this point the firewall is dropping everything, this is quite secure but of course not very usable.
# default policies $IPT -P OUTPUT ACCEPT $IPT -P INPUT DROP $IPT -P FORWARD DROP #-----------------------------------------------------------
These commands set the default policies of the firewall.
We are unzipping our mouth and will ACCEPT anything we OUTPUT unless a rule states otherwise.
We will keep our fingers in our ears and will DROP anything that is INPUT to us unless a rule states otherwise.
FORWARD we will keep DROPing.
# input
# localhost allow
$IPT -A INPUT -i $LOC -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
# ssh allow
$IPT -A INPUT --protocol tcp -s 192.168.0.0/24 --dport 22 \
-j ACCEPT
# established connections allow
$IPT -A INPUT -i $IF0 \
-m state --state ESTABLISHED -j ACCEPT
#-----------------------------------------------------------
These are three rules which are applied to the INPUT chain.
The \ is just a line continuation character, ie it allows for a command that would normally be on one line to be extended to another line.
-A (--append) adds a rule to the defined chain. In this case it is the INPUT chain.
-i (--in-interface) refers to the interface which a packet was received.
-s (--source) is a source address, it is a builtin match for packets which have a source address of what is specified.
-d (--destination) is a destination address, it is a builtin builtin match for packets which has a destination of what is specified.
-j (--jump) this specifies the target of the rule. As DROP is the default for INPUT will be ACCEPTing here.
--protocol (-p) matches a protocol.
--dport this is include by the ddcp module and enables a match by port number.
-m (--match) loads a matching module which is used to match some condition.
--state this is included by the state (called in by -m parameter). State refers to the type of connection status a pacakge has.
# localhost allow $IPT -A INPUT -i $LOC -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
This rule allows localhost services to be accessed, as long as the source is the localloopback and the interface in is lo.
# ssh allow
$IPT -A INPUT --protocol tcp -s 192.168.0.0/24 --dport 22 \
-j ACCEPT
This rule allows sshd (port 22) to be accessed from other hosts. NB ssh just happens to run on port 22 and it is port 22 that we open. The source address has to come from the LAN ie 192.168.0.0 - 255. If you are running a different LAN subnet be sure to change the ip address and the range given by the \24.
# established connections allow
$IPT -A INPUT -i $IF0 \
-m state --state ESTABLISHED -j ACCEPT
#-----------------------------------------------------------
This rule allows servers to communicate back after a request has been made to them. This is the who called who part of the firewall, only if traffic has been established, ie the host contacted the server first, will packets from an external source be allowed (apart from ssh).
# clearup IPT= IF0= LOC= #-----------------------------------------------------------
This just cleans up the variables used, it is not necessary but it is good practice.
Once the script is written follow the instructions below to load them into the firewall. I will assume the file used was named standardfw.sh and was placed in the user's home directory.
$ su - # cp ~user/standardfw.sh ~/ # cd # chmod 700 standardfw.sh # ./standardfw.sh
As long as no errors were shown, the rules should have been loaded into the firewall now.
# iptables -L Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- localhost localhost ACCEPT tcp -- 192.168.0.0/24 anywhere tcp dpt:ssh ACCEPT all -- anywhere anywhere state ESTABLISHED Chain FORWARD (policy DROP) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
The listing of the chain rules should look like the above.
The next step is to save the rules then restart iptables and ensure that the rules load correctly, this step is distro specific, though I will show the Gentoo method.
# /etc/init.d/iptables save # /etc/init.d/iptables stop # /etc/init.d/iptables start # iptables -L
To test the rules out you need another host to test from and a web server (perhaps apache or lighttpd) running on the firewall host.
I am using elinks as the browser but of course you could use Firefox, Opera or links etc.

# exit $ elinks 127.0.0.1 # should work localhost service $ elinks 192.168.0.2 # should be blocked (nic ip number) $ ssh user@192.168.0.3 # should work ssh to another host $ elinks 192.168.0.2 # should be blocked $ ssh 192.168.0.2 # should work ssh into firewall host $ exit # return back to firewall host $ elinks http://www.poisedsolutions.com # should work check an external site $ exit
If all works you should now have a good foothold in the understanding of how iptables and netfilter works.
Whilst the firewall rules are quite basic, the process of building a firewall is quite involved, the real understanding happens when testing the firewall and tweaking the rule set to work or to try out different ideas. I hope that I have piqued your interest a bit, but at the very least turned the security dial up a notch on your system.
There are a lot of good firewall and security books now available, the real art of building firewalls is balancing usability and security, but it can go much deeper as well.
To build a good firewall you really have to know about penetration techniques, and realize monitoring is the key to detection - the firewall buys you time.
The books below form a good basis for understanding modern computer security and how it pertains to firewalls. I have included a few others which also take on the bigger picture of computer security, it is important to remember that security does not start and end with a firewall.
Copyright Poised Solutions 2007 All Rights Reserved ©