Iptables
netfilter and iptables are building blocks of a framework inside the Linux 2.4.x and 2.6.x kernel. This framework enables packet filtering, network addresss [and port] translation (NA[P]T) and other packet mangling. It is the re-designed and heavily improved successor of the previous Linux 2.2.x ipchains and Linux 2.0.x ipfwadm systems.

Iptables has 4 components:
Packet Filtering
A packet filter is a piece of software which looks at the header of packets as they pass through, and decides the fate of the entire packet. It might decide to DROP the packet (i.e., discard the packet as if it had never received it), ACCEPT the packet (i.e., let the packet go through), or something more complicated.

Why would you want packet filtering?
Control:
When using a linux box to connect your internal network to another network (say, the Internet), you have the opportunity to allow certain types of traffic and disallow others.  For example, the header of a packet contains the destination address of the packet.  This means you can prevent packets going to a certain part of the outside network.  For example, you can tell a packet filter not to allow any packets to or from certain addresses on the internet (say, those owned by doubleclick.net).

Security:
Packet Filtering allows you to separate your network from the chaos of the Internet by restricting what you allow in and out of it.  For example, maybe you want to protect your internal network windows web servers against trojans on the internet that affect otherwise unused services (like DCOM).  Perhaps also you don't want outsiders telnetting into your Linux box, even though all your accounts have passwords.  Maybe you want to make absolutely sure that your machine is an observer on the Internet and not a server (willing or otherwise), and thus you simply don't allow anyone in by having the packet filter reject incoming packets used to set up connections.

Watchfullness:
 Sometimes a poorly configured (or hacked) machine on a local network will behave strangely.  The packet filter can let you know if anything abnormal occurs.

iptables subsystems:
The 'iptables' binary is used to set up, maintain, and inspect the tables of ip packet filter rules in the Linux kernel.

The iptables system consists of  (currently) 3 tables of rules, each containing several default chains as well as user supplied chains of rules.

There are three independant tables in the iptables system, 2 of which we will cover today:
Each rule in a chain specifies a set of conditions a packet must meet, and what to do if it meets them (a 'target').  If a packet does not match, then the next rule in the chain is examined;  if it does match, then the next rule is specified by the value of the target, which can be either the name of a user-defined chain or one of the special values ACCEPT, DROP, QUEUE, OR RETURN.  If a packet is not matched by any rule, the chains default policy is applied to the packet (DROP, for example).
Packet filtering with iptables:
(From the linux 2.4 packet filtering howto)

There are several different things you can do with iptables. You start with three built-in chains INPUT, OUTPUT and FORWARD which you can't delete. Let's look at the operations to manage whole chains:

  1. Create a new chain (-N).
  2. Delete an empty chain (-X).
  3. Change the policy for a built-in chain. (-P).
  4. List the rules in a chain (-L).
  5. Flush the rules out of a chain (-F).
  6. Zero the packet and byte counters on all rules in a chain (-Z).

There are several ways to manipulate rules inside a chain:

  1. Append a new rule to a chain (-A).
  2. Insert a new rule at some position in a chain (-I).
  3. Replace a rule at some position in a chain (-R).
  4. Delete a rule at some position in a chain, or the first that matches (-D).
(endquote)

Most of what one does with iptables is manipulating rules.  Most commonly, you would use the append (-A) and delete (-D) commands.

As was said before, each rule specifies a set of conditions that the packet must meet, and then what to do if it meets them.  For example, suppose you want to drop all ICMP packets coming from the loopback ip.  We would use this command:

iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP

We need to append (-A) to the 'INPUT' chain, a rule specifying that for packets coming from 127.0.0.1 ('-s 127.0.0.1') with protocol ICMP ('-p icmp') we should jump to the special rule DROP ('-j DROP').

We can delete the rule in one of two ways:
    iptables -D INPUT 1
This command says to delte rule number 1 in the INPUT chain.  We can also...
    iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
The second way is to mirror the -A command, but instead use -D.

Filtering Specifications:

We have already seen the use of '-p' to specify protocol, and '-s' to specify source address, but there are other options we can use to specify packet characteristics:
State based filtering:
This is the most useful match criterion.  It is provided by the 'state' extension, which interprets the connection-tracking analysis of the `ip_conntrack' module.

Specifying '-m state' allows an additional '--state' option, which is a comma-separated list of states to match (can be inverted with '!'). These states are:
NEW

A packet which creates a new connection.

ESTABLISHED

A packet which belongs to an existing connection (i.e., a reply packet, or outgoing packet on a connection which has seen replies).

RELATED

A packet which is related to, but not part of, an existing connection, such as an ICMP error, or (with the FTP module inserted), a packet establishing an ftp data connection.

INVALID

A packet which could not be identified for some reason: this includes running out of memory and ICMP errors which don't correspond to any known connection. Generally these packets should be dropped.

A powerful example of this rule might be to allow only outgoing connections from a linux box (such as for dekstop use, and thus should not ever act as a server).

iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth0 -j DROP
iptables -A OUTPUT -j ACCEPT
iptables -A FORWARD -j DROP

There are also several other targets (such as ACCEPT and DROP) that we did not cover.  These include LOG (which logs the packet, obviously) and REJECT (which has the same affect as 'DROP", except that the sender is sent an ICMP 'port unreachable' error message.  Information on these and others can be found in the iptables manpage.

NAT (Network Address Translation) with iptables:

 As I said before, there are two types of NAT, source nat and destination nat:

Source NAT is when you alter the source address of the first packet: i.e. you are changing where the connection is coming from. Source NAT is always done post-routing, just before the packet goes out onto the wire. Masquerading is a specialized form of SNAT.

Destination NAT is when you alter the destination address of the first packet: i.e. you are changing where the connection is going to. Destination NAT is always done before routing, when the packet first comes off the wire. Port forwarding, load sharing, and transparent proxying are all forms of DNAT.

The most useful form of NAT is ip masquerading.  This allows one box (a router/firewall) to act as a gateway for a local network with one special caveat:  The local network need not have real internet ip addresses to connect to the internet; non-routable addresses may be used. 

Suppose we have a gateway linux box acting as a masquerading box to the local network 192.168.0.0/24.  The interface eth0 is used as the gateway interface with the address 192.168.0.1, and eth1 as the interface to the outside world.  Suppose we want the machines on the internal network to have access to the internet.  This can be accomplished using the MASQUERADE target as follows:

iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

The -t flag specifies that we are acting on the NAT table, we append the rule to the POSTROUTING chain (SNAT is always done on postrouting), the output interface is eth1, and the target is MASQUERADE.  Actually, we would also need to turn on packet forwarding via the proc interface as fololows:

echo 1 > /proc/sys/net/ipv4/ip_forward

But there are other types of NAT besides masquerading.  Suppose, using our previous example, that we wanted to forward all web traffic to an internal webserver on 192.168.0.2.  The following command would suffice:

iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -i eth0 -j DNAT --to 192.168.0.2

Here, the only unfamiliar flags are -j DNAT and the --to flag.  The -j DNAT is another special target that tells iptables to perform destination NAT on the packet.  The special --to flag (short for --to-destination) is used, obviously, to tell the destination ip for the packet.  It can be an ip address, an ip address with a port (such as 192.168.0.2:8080), or even an ip address range and/or port range.

I will provide examples of an iptables gateway/firewall system using my own home network