IPTables

Netfilter

Since networks are the source of significant system security problems, there has long been an interest in finding some method to control access to a host at that level. The 2.2.x Linux kernel included a firewall support feature known as ipchains which is very popular. The more recent 2.4.x kernels included the netfilter capability which improves on ipchains in the areas of effectiveness and performance.

While ipchains is still popular, iptables has some significant advantages and will be discussed here. In order to use iptables, you need to have a kernel configured with the following:

After configuring and installing your kernel with netfiltering, you can check the existence with iptables -L. You should see an output indicating that all three default chains are empty.

The packet filtering process takes each incoming IP packet and adds to the processing a series of rules that allow packets to be dropped, forwarded or modified in different ways. A diagram of the process is shown below:

The process begins when any IP packet arrives in the system as Input, it has to undergo some error checking, a Checksum test and a Sanity test, and then it becomes part of the input chain. For the time being, ignore the Routing Decision blocks. From the input chain, a decision is made: does this packet belong here or should it be forwarded to another host. If the answer is the former, it is sent to the local process otherwise it is sent to the forward chain. A packet that is generated internally to the host, or which comes from the forward chain is processed by the output chain.

netfilter allows a system administrator to provide a set of rules that control each of the processing steps - input chain, forward chain and output chain. Routing will be discussed later.

Lets consider what all this means. If a packet reaches the input chain, rules can be formulated that allow the packet in, reject the packet or send it back to the originator. Similarly, packets reaching the output chain can be allowed out, or they can be stopped at that point. Finally, packets that pass through the system on the way somewhere else (this system is acting as a router) can be allowed, dropped or rerouted.

Obviously, this would allow you to protect your system from potential attackers, to hide data, to control the activities of your users and to act on behalf of other hosts to provide unique services.

IP Network Address Translation (NAT) is a process that allows IP addresses to be manipulated in several beneficial ways. It will be discussed later, but it is part of the netfilter process.

iptables

The control of netfilter is done through a utility named iptables. This rather simple program provides the only standard interface to controlling netfilter. In the future, there will likely be better tools. There are a few variants on the command itself:

Chains:

The predefined chains that are available for filtering are the INPUT, FORWARD and OUTPUT chains. There are two other predefined chains, PREROUTING and POSTROUTING that are related to network address translation and will be discussed in that section.

Policies:

The acceptable policies (or targets) for filtering are

Rule Specification:

A rule specification has a set of parameters, each of which must be supplied, or its default will be assumed. They are:

Parameter    Default    Meaning
-p [!] protocol     All protocols     The datagram protocol, tcp, udp, icmp or a number from the /etc/protocols file. The ! negates the protocol given.
-s [!] address[/mask]   All addresses     The source address as a DNS name, IP address or an address/mask pair. Presence of ! negates the specification.
-d [!] address[/mask]   All addresses     The destination address as a DNS name, IP address or an address/mask pair. Presence of ! negates the specification.
-j target   No action     Specifies what action to take - ACCEPT, DROP, QUEUE or RETURN, a user-defined chain or a target provided by an extension.
-i [!]interface-name   Any interface     The interface on which the datagram was received. ! negates. Ending the name with a + matches all that begin with the string; e.g. eth+ matches eth0, eth1 and eth-gb.
-o [!]interface-name   All interfaces     The outgoing interface which has the same syntax as the -i option.
[!]-f   All interfaces     Indicates that this rule applies only to the second or later fragments.

Options:

There are a few options that can be applied to iptables commands.

Option    Meaning
-v    Verbose output
-m ext    Enable match extensions for ext.
-n    Use IP addresses without attempting to resolve DNS names.
-x    Expand all counters without rounding to thousands (K's), millions (M's) or billions (B's).
--line-numbers    Causes line numbers to be supplied to show a rules position in the chain.

Extensions:

iptables is extensible, but there are a few standard extensions. These are related to the specific protocols that might be carried in an IP packet. The use of the extensions is indicated with the -m option or through the -p option.

TCP Extensions

These extensions are valid if -p tcp or --protocol tcp is specified or by using -m tcp.

Option    Default     Meaning
--sport[!][port[:port]]    All ports     Specify the source port or range of ports to match. For example, --sport 80, --sport 50:100 or --sport !23. The name of the service from /etc/services may also be used, as in --sport telnet.
--dport[!][port[:port]]    All ports     Specify the destination port or range of ports to match.
--tcp-flags [!] mask comp    Ignore flags    Specify the TCP flags that should match in the datagram. The format is a list of flags to be examined and the second is a list of flags which must be set. For example, --tcp-flags SYN,ACK,FIN   SYN indicates that the SYN flag must be set and the ACK and FIN flags must be unset
[!]--syn    Ignore    Match only connection initiation packets with the SYN bit set and ACK, FIN and RST bits unset.

UDP Extensions

These extensions are valid if -p udp or --protocol udp is specified.

Option    Default     Meaning
--sport[!][port[:port]]    All ports     Specify the source port or range of ports to match. For example, --sport 80, --sport 50:100 or --sport !23.
--dport[!][port[:port]]    All ports     Specify the destination port or range of ports to match.

ICMP Extensions

These extensions are valid if -p icmp or --protocol icmp is specified.

Option    Default     Meaning
--icmp-type [!] typename     All types    Specify the type of the icmp message to be matched. The legal types are: echo-request, echo-reply, source-quench, time-exceeded, destination-unreachable, network-unreachable, host-unreachable, protocol-unreachable and port-unreachable.

State Extensions

These extensions allow rules to be based on the state of a connection.

Option    Default     Meaning
--state state     All states     The state is a comma separated list of connection states
INVALID, not associated with a know connection,
NEW, this packet start a new connection,
ESTABLISHED, packet belongs a existing connection,
RELATED, a new connection, but related to an existing connection.

Whew! Now lets see how it works.

Simple Example

Suppose we want to do some simple firewalling on a system connected to the Internet. Assume that our IP address is 172.17.200.4 with an address mask of 255.255.248.0. We want to allow telnet out, but not in; http in both directions, but output is limited to a single site; ftp in, but not out.

Suppose that we want to make this more realistic by having a default OUTPUT policy of DROP. This creates a number of problems, because all traffic is stopped, including DNS, NFS and some other things that you would really like to have. You have to explictly open each service as needed. iptables does not have a bidirectional option, so you have to define the input and output rules individually.

So, if we might have to add the following rules to the above rule set.

Making Rules Permanent

The iptables that you create are a dynamic part of the kernel and disappear when you restart your system. To make them permanent, you need to save the rules and restore the them. You save the tables with:

and restore them with:

The -c option output all of the packet and byte counters as well as the tables.

You wouldn't want to do this manually, so you should probably set up some sort of start up script. In the new versions of iptables, the startup script is automatically installed. If it isn't, you will have to find a copy and install it. This script has the usual start, stop and restart options, but it also has a save option that saves the current tables in the configuration file (the default is /etc/sysconfig/iptables).