A Simple Linux Firewall – A brief tutorial in iptables.

It is good practice to install a firewall, regardless of the operating system you use.

Firestarter‘ is one of the firewall options available to a Linux user. To install Firestarter in Ubuntu, open up a terminal window and type:

$ sudo apt-get install firestarter

You have now installed a firewall. For most people this is sufficient, and they need not read any further. People with a genuine interest in computing may wish to investigate a little more deeply…

Actually, Firestarter is one of several graphical front ends for the firewall tool called ‘iptables‘. Iptables is a command line tool that allows the administrator to define a set of packet filtering rules, and these rules are enforced using a kernel framework called ‘netfilter’. Let’s take a look at iptables. Login as root/super-user and type in the following command to display your current iptables configuration:

$ iptables -L

If you have never configured iptables, you should see something like the following displayed on your terminal:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

If you have installed Firestarter, you will see a complicated set of firewall rules displayed. I also suspect that some distributions are pre-configured with an iptables firewall. This artical is written on the assumption that you can see the above.

In the above example taken from my laptop after I have cleared the firewall, you can see three ‘chains’ – the INPUT chain (for incoming traffic), the FORWARD chain (used for packet routing) and the OUTPUT chain (take a guess!).

We’re going to be focusing on protecting our computer from external attack, so we will be putting all of our effort into creating a set of rules in the INPUT chain. You will notice that the policy for the INPUT chain is ACCEPT – this is the default action to take when a packet arrives. This is not the setting we want, it would be preferable if we rejected (dropped) incoming traffic (that is the best way to fend off attack). To change the INPUT chain policy to DROP we would type:

$ iptables -P INPUT DROP
(remember, you need to be doing this as root/super-user)

You can then confirm this change by listing the iptables configuration, again with the command:

$ iptables -L

I bet you feel better already.

Unfortunately, our new firewall is far too powerful. Many processes on your computer communicate by sending network packets, but they stay inside your computer instead of being broadcasted across the net. We need to make sure that these processes can signal each other. We can do this by typing the following command:

$ iptables -A INPUT -j ACCEPT -s localhost -d localhost

As a packet is generated, iptables checks to see if the packet matches any rules, and if it does the rule is applied to that packet. Here, we are saying that packets made locally (the source, -s), that are destined to stay local (the desination, -d), can be allowed to go about their business without interference. Any other packets received that do not match this rule have the policy applied (they are dropped)

Things are still not quite right. Pull up your web browser and visit your favourite website. You’ll find that you can’t use the net. If you check your policy on the OUPUT chain you will find that this traffic is ACCEPTED.

As you typed your web address, your request WAS allowed past the firewall. The website received your request and replied, but this reply was blocked when it was received by your computer. We need to find a way to tell iptables the difference between good traffic and evil hacker-type traffic, ie. we need a way to tell iptables to allow incoming traffic that you specifically asked for. We can do this with the command:

$ iptables -A INPUT -j ACCEPT -m state –state RELATED,ESTABLISHED

Here we tell iptables that if a packet arrives that is part of a connection that already exists, it should be allowed to pass. This way, if you throw a packet out into the lawless wilderness of the internet, any returning data is accepted. Now try browsing the internet, it should work fine now…

It is good practice to add a final rule to a chain to reject any remaining un-matched packets. This prevents the POLICY from having to be applied. This is useful if you decide to implement some sort of clever logging rule set. Enter the command:

$ iptables -A INPUT -j DROP

Iptables starts with the first rule in the chain and works down. As soon as a rule match is identified, the specified action is performed and no further inspection occours. Therefore, you must make sure that this is the last rule in your INPUT chain (so enter this command last). If, for instance, this was the first rule in the input chain, all traffic would be rejected.

Just a few more loose ends.

Let’s take a look at the FORWARD chain. This is useful for things such as network routing. We won’t be using these types of network packets for a simple workstation, nor should we have any of these packets floating around. To block traffic of this type we will apply a global policy:

$ iptables -P FORWARD DROP

Now we have to consider outgoing traffic. Filtering outgoing traffic is a complex task. Here, I will suggest a simple ACCEPT policy, as most sensible Linux users are not likely to have installed any malware.

$ iptables -P OUTPUT ACCEPT

We have now built a simple and effective firewall policy. If you display you firewall tables (using ‘iptables -L’) you should see:

Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all — localhost localhost
ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
DROP all — anywhere anywhere

Chain FORWARD (policy DROP)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Rules in iptables can be inserted in any point in the chain (see the online manual) but at this stage it is easiest to just work top to bottom. If you screw up and need to start again, use the command ‘iptables -F’ to flush all rules from your chains and start again. It is useful to construct shell scripts instead of working directly with the terminal, as these can be edited and then re-applied quickly.

You can save the iptables configuration to a textfile with the command:

$ iptables-save > filename

and this file can be used to configure iptables with the command:

$ iptables-restore < filename

If you restart your computer you will lose you firewall configuration. The restore command (or the line by line instructions you have just entered) could be placed in a shell script, and your computer can be instructed to run this script when it starts (check the documentation for your linux distribution).

For a slightly more advanced solution, in Ubuntu (and probably most other distributions) browse to the directory ‘/etc/network’ and list the directories contents. You will see the following directories:

if-down.d if-post-down.d if-pre-up.d if-up.d

Just before the network adaptor comes ‘on-line’, all of the shell scripts inside the directory ‘if-pre-up.d’ are executed (the other directories are similarly self explanatory). So, either a shell script containing the steps to build your firewall, or a short shell script that executes the ‘iptables-restore’ command can be placed in this directory. As soon as the network adaptor comes on-line the firewall will be automatically restored. Make sure the resore file is somewhere safe with a sensible name, such as /etc/iptables.bak. You will need to make sure that your script is owned by root and has execute permissions,use the’chown’ and ‘chmod’ commands respectively.

Iptables has a complicated and useful set of features and the reader is encouraged to investigate further.
Disclaimer:

This article was written to provide the reader with an introduction to iptables, Linux and the configuration and deployment of this software. It is provided as an example and should not be interpreted as a complete, satisfactory or comprehensive security solution. I accept no responsibility for any loss or damage to data or hardware. I make no claim to the accuracy of this article. In a security critical application a computer security specialist should be consulted.

9 thoughts on “A Simple Linux Firewall – A brief tutorial in iptables.

  1. Hi, thanks for the tutorial. I'd like to ask a question about the INPUT chain described above. As we already have 'Chain INPUT (policy DROP)', is it necessary to have 'DROP all — anywhere anywhere' at the end? I can see it might be good practice to do so as a belt and braces approach.

    • Hi Mark,

      You are quite right. 'DROP all — anywhere anywhere' is not strictly needed, but I prefer to add this rule in case I inadvertently change the default policy.

      Whilst you would need to make a deliberate effort to change this at the command line, I am paranoid that the policy might get changed when I am playing with various GUI front-ends. As you suggest, it is probably better practice to include this rule.

      Regards,
      Rich

  2. i get an error :

    sudo iptables -A INPUT -j ACCEPT -m state –state RELATED,ESTABLISHED
    Bad argument `–state'
    Try `iptables -h' or 'iptables –help' for more information.

Leave a Reply