Automating iptables on Debian Linux

Posted by & filed under , .

It’s interesting to dwell occasionally into researching how people are reaching my blog and what are they looking for when they do so. As you have seen so recently I have brought back a few old articles that seem to have triggered the attention of some people on the net — at least that’s what I could tell looking at the searches performed by various in search engines which directed people on my site. One such phrase was “iptables linux” — I completely forgot that at some point I had a post about this, so here it is again:

If you are using a Linux server to control access to your network from the outside (or even from the inside), you are probably implementing some firewalling rules. While there are a few ways to implement such a facility, I have decided for iptables — purely because I thought it simple to manage and it also has various kernel module one can load and make use of. However, I am sure that this approach can be used for the likes of iproute, iproute2 and so on.

I am not going to go into details about how to compile your kernel to include support for iptables as there are loads of resources on the net about this. But it needs to be said that the modules have to be compiled in the kernel in order for iptables to work. Also, I will assume that you are already familiar with the way iptables operates and how to use the commands associated with it (iptables, iptables-restore and iptables-save).

Last but not least, as the title of this article states it, this article targets the Debian distribution of Linux, however, simply changing a few paths would render it useable on your own distribution of Linux.

So, you have set up your iptables rules using the command line, you have tested it and made sure they work and your network is protected and then you saved them using iptables-save. I guess the next thing you might think of implementing is an automated way to have them applied after your computer boots up. To do so is trivial, and all you need is a simple script placed in /etc/init.d which you can then link to the runlevel of your need (/etc/rc2.d for instance) which would just automatically load the rules at start-up. And since most of the scripts in /etc/init.d support the “classic” start, stop, restart parameters, let’s make our script do the same. So here it is — save it in /etc/init.d/iptables:

#! /bin/sh
# /etc/init.d/iptables: load and save the iptables
IPTABLES_CONF=/etc/default/iptables.conf
IPTABLES_BAK=/etc/default/iptables.bak
SAVE_CMD=/sbin/iptables-save
LOAD_CMD=/sbin/iptables-restore
check_config() {
   if [ ! -r $IPTABLES_CONF ]; then
      echo "Cannot find saved iptable!"
      exit 1
   fi
}
 
case "$1" in
   start|load)
      check_config
      $0 flush
      echo -n "Loading iptables..."
      $LOAD_CMD < $IPTABLES_CONF
      echo "done"
   ;;
 
   stop|flush)
      echo -n "Stopping iptables..."
      iptables -F
      echo "done"
   ;;
 
   save)
      echo -n "Saving iptables..."
      cp $IPTABLES_CONF $IPTABLES_BAK
      $SAVE_CMD > $IPTABLES_CONF
      echo "done"
   ;;
 
   *)
      echo "Usage: /etc/init.d/iptables {start|stop|load|save}"
      exit 1
esac
exit 0

As you can see, we went an extra mile and implemented some other functionality as well (save, backup). This is in order to prevent testing with iptables to test some new rules and accidentally overwriting the configuration file (via iptables save) — so if this ever happens at least you have a backup file which you can restore. Simply test your rules until you are happy with them and then issue an iptables save followed by iptables backup — this would ensure that if by any chance you overwrite the main configuration file with some wrong data, you will still be able to restore the “last known to work” configuration file.

Having saved the above file as /etc/init.d/iptables then simply create a link to it in say /etc/rc2.d (the standard multi-user runlevel in Debian Linux) specifying also a start priority — in my case I start this with a priority of 15 (before apache and all the other server components), so in this case simply issue:

cd /etc/rc2.d
ln -s ../init.d/iptables S15iptables

Also, it’s a good idea to stop them during reboot/shutdown (runlevel 6) — in my case, again, I’ve created a link in /etc/rc6.d/ named K99iptables — so it’s pretty much the last service stopped — after all the other services have been stopped. (So when I turn off the iptables firewall there’s no services that a hacker can get to.)

As a last note, the format of the file /etc/default/iptables.conf is the standard format that you would get when issuing an iptables-save command — here’s an example:

#
*filter
 
:INPUT DROP [210:22505]
:FORWARD DROP [134:20792]
:OUTPUT DROP [197:14914]
 
# Deny Samba connections from outside the network
-A INPUT -p tcp -s ! a.b.c.d -d a.b.c.d -m multiport --dports 137,138,139 -j DROP
-A FORWARD -p tcp -s ! a.b.c.d -d a.b.c.d -m multiport --dports 137,138,139 -j DROP
-A OUTPUT -p tcp -s ! a.b.c.d -d a.b.c.d -m multiport --dports 137,138,139 -j DROP
...

Obviously, the comments are added by hand — and not by iptables-save 🙂 And also if you edit the file by hand and add such comments, please be aware that when you use iptables save (or iptables-save /etc/default/iptables.conf) the comments will be lost.

Download the shell script and a sample configuration here.