I have been lately working with networks and had to use iptables at several instances. During the
process I dug into iptables a little bit and so documenting my learnings here.
iptables is a userland tool to interact with netfilter in kernel. IPTables and netfilter together
facilitate in enforcing different packet-filtering rules and setting up a basic firewall.
There are primarily 3 different tables which allow you to define rules and where those rules get
applied depends on the chain.
1. PREROUTING: A packet goes through this chain before any routing decision is made.
2. FORWARD: If the message is not intended for local machine; it can be either dropped
or routed to other machine based on the policy.
3. INPUT: If the packet is targeted for local machine, it passes through the INPUT chain.
4. OUTPUT: Any packet originating from local machine goes through the OUTPUT chain.
5. POSTROUTING: All outbound packet goes through post routing state.
It first goes through the PREROUTING chain; where you can change the TCP headers,
setup nat rules, etc; before passing it on for the Routing. Routing decides if the packet is
targeted for current system based on IP headers.
If it is not meant for the current system, packet passes through the FORWARD chain
where one can decide to either forward the packet or drop it based on the set policy. If the
forwarding is allowed, the packet is passed on to the POSTROUTING chain, otherwise
its dropped or rejected.
If the packet is meant for the current system, it is passed to the INPUT chain where
packets can be filtered, header can be modified, etc and once rules in this chain are
applied, packet is passed on to the local machine for processing.
Any new packet from local machine passes through OUTPUT chain, where packet can
be modified before the routing decision is made. Once the routing decision is made,
packet goes through the POSTROUTING chain.
POSTROUTING change can modify the headers, filter the packets before packet is
finally put onto the network.
I loosely talked about filters, modifying headers during the traversal flow of packet. To make it
more concrete, lets look at what tables are available and how can they be used. As mentioned
above, there are primarily 3 tables available where you can define you rules and these rules are
executed at different chains. These three tables are: nat, mangle and filter.
Not all tables are available in all chains, as you can see filter table is not available in
PREROUTING and POSTROUTING chains.
So a rules needs to have a chain and a table. For example, an iptable rule looks something like
this:
1. filter: This table, as the name suggests, filters the packets based on the rules. This is the
default table and will be used if a table is not specified. It is only present in INPUT,
OUTPUT and FORWARD chain. Based on target value, packets can be dropped,
accepted, and returned.
2. nat: This allows altering the packets destination or source address. This is normally used
to modify source and destination headers to allow internal ips to talk to outside networks.
Normal use-case involves changing the destination IP address of the packet, also known
as DNAT, in the PREROUTING chain to that of local machine so that routing can route
it to INPUT chain. And conversely, changing the source address of the packet, also
known as SNAT, in the POSTROUTING chain to that of the router or an ip known to
destination routing.
3. mangle: Mangle can be used to modify certain properties of the packet like TOS, TTL,
MTU, etc.
1. ACCEPT: This can be used to allow traffic based on the other specifications in the rule.
2. DROP: This can be used to drop the messages. No further processing is done; and no
further information will be sent back to sender.
3. REJECT: This is similar to DROP but it also sends back an error message back to host
sending the packet.
4. SNAT: It allows one to modify source ip address in the packet. Its only valid in
POSTROUTING chain and nat table.
5. DNAT: It allows one to modify destination ip address in the packet. Its only valid in
PREROUTING chaing and nat table.
6. MASQUERADE: This is same as SNAT but it doesnt require a --to-source option.
I.e., this is preferable if you dont know the external ip during the rule creation, as it may
be retrieved later using DHCP.
We can use filter table (which is the default) and add the rule in the INPUT chain.
We can use filter table (which is the default) and add the following rule in the OUTPUT chain.
References:
[1] Taming the Wild Netfilter - linuxjournal.com
[2] Netfilter Architecture - netfilter.org