iptables often gets confusing because the same tables may be called from different chains. This begs the question: Do different chains call the same commands from tables with the same name? This is why chain and filter names are specified (implicitly or explicitly) in each command. The combination allows netfilter to skip over irrelevant code not tagged with the current chain or table name.
Recall the network diagram in Network Routes shows the process flow of a packet and when the packet may be acted upon by iproute, iprule, or iptables. As previously described in Chains and Tables, by default all iptables commands are processed through five chains and five tables. Following the path of a network packet gets confusing because these concepts are intertwined with the Routing Policy DataBase (RPDB) process, and because it's so difficult to find literature that explains what these things are and how they are intertwined.
It's very important to follow the orderly logic of when each table's commands will be executed in each chain. While most documentation on this subject appears to reference tables in a way that gives the reader the impression tables are calling chains, I am convinced after studying iptables for some time that it is the other way around. Effectively, the chains dictate the path of a packet through netfilter and its handling by the kernel. The chains Input, Output, and Forward are the gatekeepers. No matter which table your rules are contained in, it is the chain the packet is associated with that determines which tables will be processed and when.
Another example supporting my point is the implementation of iptables rules doesn't steadfastly follow the concept where the table dictates which chains are called (and partly why I believe the reverse is actually true, as I've indicated above). For example, the multiport match extension protocol in iptables may be called during the PREROUTING chain. However, while the PREROUTING chain does not call the Filter table, the multiport command may also be used in the NAT table during processing of the PREROUTING chain.
I suspect much of the confusion - particularly of iptables neophytes - lies in the use of hidden or undeclared default values, such as the fact the filter table is the default location of new rules. Unless one knows to specify or declare certain characteristics of your rules and routes, iptables and even iproute2 will often position things in places that aren't always logical to the average human being.
With regards to iptables in particular, if a packet is following a chain such that it never has a chance to encounter a table where some particular rule is located, the rule will obviously never be executed. The problem is this fact is easily obscured from casual observation. One must either learn the default locations and values of various aspects of iptables and iproute, or be diligent in always making specific declarations when writing commands.
To wit, let's re-cap the order of chain processing logic. In the "old days" of ipchains, only the primary chains existed, and the process was a bit easier to follow.
Primary Chain | Actual Chain Path |
---|---|
INPUT | PREROUTING -> INPUT -> Local Process |
OUTPUT | Local Process -> OUTPUT -> POSTROUTING |
FORWARD | PREROUTING -> FORWARD -> POSTROUTING |
If you'd like a more visual description, review the charts in How Linux Routes Network Packets.
Here is the order of table processing within each iptables chain.
Chain | Table Processing Order |
---|---|
PREROUTING | Raw | CONNTRACK | Mangle | NAT (DNAT) |
INPUT | Mangle | Filter | Security | NAT (SNAT) |
OUTPUT | Raw | CONNTRACK | Mangle | NAT (DNAT) | Filter | Security |
FORWARD | Mangle | Filter | Security |
POSTROUTING | Mangle | NAT (SNAT) |
You can think of chains as maps to and from a destination, and tables as waypoints along a route. When you add a new iptables command, a portion of the command line instructs netfilter which chain the command should be added to, and which table it belongs in within that chain. You can also think of it the other way around. Regardless, the end result is the same; when any particular command gets called, it is driven by the intersection of a chain and a table. No matter how you view their relationship, they are intertwined.
When you create a new command, you must decide at what point in the packet processing sequence it should be executed. "When" is a combination of which chain and which table within that chain. If you are familiar with software programming, you may liken this to the chain as a program and each table as a subroutine within the program. For example, if you wish to modify the source or destination address of a packet, you'd want to be sure you did that prior to a command that tells netfilter you're done processing the packet. If you reversed that order, the address modification would never happen. Of course, that sounds simple and logical, but in practice rules don't always get executed as you expect, so make sure you pay close attention to the order-of-execution of chains and the tables within each chain.
There's one more process in the mix you should be aware of. It's neither a chain nor a table, though you may have noticed it in the aforementioned charts and wondered what it was: it's called CONNTRACK.
CONNTRACK
CONNTRACK is an abbreviation for CONNection TRACKing. Recall the discussion of fwmark in Routing Marked Packets with fwmark. FWMark means FireWall Mark and relates to the action of "marking" or tagging packets. When a packet is marked, an internal value is assigned by netfilter creating an association with that particular packet. If the packet leaves the server and comes back, the mark will remain and netfilter will know it's seen the packet previously.
CONNTRACK tagging and inspection operands present an unusual scenario. They share all the netfilter hooks with chains except FORWARD, yet are processed independently of the chains and tables. The order-of-execution is always after the RAW table and before the MANGLE table in each chain respectively.
The iptables CONNTRACK function is discussed in greater detail under Match Extensions, part of the discussion on iptables command parameters.
conntrack vs. CONNTRACK Confusion
There is a netfilter process called CONNTRACK and an iptables match extension function called conntrack. The CONNTRACK module (within netfilter) and the conntrack match extension within iptables are independent of one another. However, their identical names can and do create considerable confusion! The key difference is the iptables conntrack reference is a match extension and read-only, while the CONNTRACK module in netfilter is responsible for tracking and maintaining the current state of network connections.
Custom Chains
Custom chains must be created first. Then you may add rules to them. In order to utilize them, you must point to them from one of the five built-in chains. The chain commands above are used to create and delete custom chains. Pointing to a custom chain is handled via Parameters. If you want to know more about Custom Chains, you may wish to review How To Create Custom Chains.
Chain Policies
You may have noticed there is a command related to chains called Policy. What is a chain policy? A policy is simply a chain's default behavior. A chain's policy becomes relevant when the kernel reaches the end of a chain and there has been no matching rule that triggered an action or jump, or for whatever reason the packet was processed through a chain without making a determination of the packet's ultimate fate.
Chain policies can only be ACCEPT or REJECT. See Actions and Targets for more information.