iptables tutorial: how to configure the filter tables of Linux kernels

Packet filtering is a critical component in the security concept of all computer systems on a network. Controlling and managing incoming and outgoing traffic ­– often as part of a firewall – is designed to ensure that only data packets free of malware and spam are sent and received. In a Linux kernel, a packet filter is integrated by default, since it’s provided by modules of the software packet, Netfilter. However, an additional program is needed to configure it. For the Linux kernels 2.4 and 2.6, the free software iptables is required, which was also developed by the Netfilter project team.

As an administrator, iptables is used to set up, modify, or delete rules, while settings will be lost during the system reboot. The program’s tools, iptables-save and iptables-restore, are used to save and restore rule sets that have previously been set up. With a so-called init script this is done automatically even during the boot process. iptables is limited to the protocol IPv4, while for other protocols there are corresponding variants, such as ip6tables for IPv6, or ebtables for Ethernet packets, which are also contained in the kernel module.

In the following iptables tutorial, we present the basic functions and options of the packet filter software. We then explain the configuration of the tables by using different examples.

How iptables works

iptables usually comes pre-installed on Linux. If this is not the case, or if you want to make sure that you are using the current software version, you can also use your distribution’s packet manager to update or install it. Just enter the following command into the terminal:

sudo apt-get install iptables

There are various graphic interfaces for iptables, e.g. FirewallBuilder or Webmin, while operating the program via command lines is relatively uncomplicated and quick to learn.

iptables requires extended system privileges and can therefore be executed only as root or with appropriate administrator rights. The tables, which are loaded with the program and previously generated by the kernel, contain chains and rules that specify how incoming and outgoing data packets should be dealt with. These packets are handed down from rule to rule within a chain, whereby each rule can cause an action (jump target) or a change to another chain (goto chain).

The actions that can occur when a rule applies to the particular data packet are:

  • ACCEPT: the packet is accepted
  • DROP: the packet is rejected
  • QUEUE: moves the packet into the user processes; requires a queue handler that forwards the packet to an application
  • RETURN: the packet is returned to the previous chain if it is a user-defined chain. In standard chains, the policy of the chain is executed (without configuration by default: ACCEPT)

The standard chains mentioned in the RETURN action are specified in the iptables filter table. The three chains are INPUT, FORWARD, and OUTPUT. The former takes care of packets that are to be delivered to the system, whereas the second chain processes incoming data packets that are intended for forwarding. The OUTPUT chain, on the other hand, controls the data traffic generated by your computer. In addition to the filter table, there is a NAT table for translating network addresses as well as a MANGLE table for manipulating packets. You can obtain a detailed overview of the packet filter software’s functions from the man page, which you can access at any time using the command:

man iptables

Alternatively, you can find many iptables how-tos in different languages on netfilter.org.

How to create and manage your own filter rules

At this point in the iptables tutorial, we will cover the filter table and its rule sets. The table below shows the individual commands for creating and managing chains. To regulate data traffic, you can either create your own chain or access the three standard chains INPUT, OUTPUT, and FORWARD. These are the most important configuration options:

Iptables commands Example Explanation
-N "name of chain" sudo iptables -N test Creates a new chain with the name "test".
-X "name of chain" sudo iptables -X test Deletes the empty chain with the name "test"; doesn’t work with the standard chains INPUT, OUTPUT, and FORWARD.
-L ""name of chain" sudo iptables -L test Lists the rules of the chain named "test".
-F "name of chain" sudo iptables -F test Deletes the rules of the chain named "test".
-P "name of chain""action" sudo iptables -P INPUT ACCEPT Sets the policy for the chain. In the example, the packet is automatically accepted if the filter rules of the INPUT chain do not take effect.
-A "name of chain" "rule" sudo iptables -A test -s 127.0.0.1 -j DROP Attaches a new rule to the selected chain. In the example, the new rule added to the "test" chain shows that data packets from IP address 127.0.0.1 should be rejected.
-D "name of chain" "rule" sudo iptables -D test -s 127.0.0.1 -j DROP Deletes the specified rule of the selected chain.
-I "name of chain" "position" "Regel" sudo iptables -I test 1 -s 127.0.0.1 -j DROP Adds the new rule to the selected position in the chain. In the example, this is position 1.
-D "name of chain" "position" sudo iptables -D test 1 Deletes the rule of the selected chain, specifying the position of this rule; this example also uses position 1.

How iptables with filter rules contributes to system protection

Now we will show you the possibilities of iptables by setting up a rudimentary firewall. Since the three standard chains INPUT, OUTPUT, and FORWARD already have predefined rules, you first have to delete them, depending on the distribution:

sudo iptables -F

For the second step, add the DROP policy for each of the three chains to ensure that data packets are blocked in every case so that none of the filter rules that have been set up lead to a positive result:

sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP

For the next step, activate (ACCEPT) the local host (lo) for incoming (-i) and outgoing (-o) data traffic by extending both the INPUT and OUTPUT chains using the appropriate rule (-A):

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT

Subsequently, enable outgoing HTTP and HTTPS connections (port 80 and port 443) for common TCP ports 1024 until 65535:

sudo iptables -A OUTPUT -o eth0 -p tcp --dport 80 --sport 1024:65535 -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p tcp --dport 443 --sport 1024:65535 -j ACCEPT

In the last step, accept all incoming and outgoing data packets belonging to an existing connection (--state ESTABLISHED) or relate to an existing connection (--state RELATED):

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

Since the rules created with iptables are volatile and are only retained until the computer is turned off, you should use iptables-save to ensure the .rules file is saved in the respective iptables directory. The appropriate command for Ubuntu systems is:

sudo iptables-save > /etc/iptables/iptables.rules

By entering the command,

sudo iptables-restore < /etc/iptables/iptables.rules

Manually load this file every time you restart your system. Alternatively, create a corresponding script so that the packet filter application runs automatically.

For more information on network filters and iptables, we recommend taking a look at the iptables tutorial 'Linux Firewall Tutorial: IPTables Tables, Chains, Rules Fundamentals'.