It first needs to store states. With some old BSD firewall that I used, I guess was named IPFW, I used to put a rule that sated "keep track of the state of the leaving packet", and this was placed on the outbound direction of interfaces. Then, another rule on the inbound direction that checked them against those states that were created by the rule on the outbound direction. So there used to be 2 rules: (1) to populate the states table, this was on the outbound direction, and (2) to lookup the states table, this was on the inbound direction.
But with connntrack, I see it applied on the INPUT chain, such as this rule:
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
This makes me wonder, what is that statement actually doing?
- Is it saying that it will start tracking packets that match that rule by putting their information in the states table?
- Or is it saying that it already has the states information, and it is going to act against inbound messages based on it? (e.g. accept if they belonged to a previously accepted connection?). But, in this case, where did the states table get populated? Which rule does it? Or is it rule-less and implicit?
Introductory presentation of Netfilter and conntrack
First the mandatory schematic about Packet flow in Netfilter and General Networking:
Netfilter is the packet filtering framework inserting itself over the rest of the network stack (represented by "routing decision" and other white round-edged box parts). Netfilter provides hooks and APIs for other subsystems and "clients". Among these parts are conntrack (the connection tracker) and iptables (or nftables). The separation between Netfilter and conntrack is quite fuzzy. You can just consider conntrack as an integrated part of Netfilter.
In the schematic describing the various steps a packet traverses you can see that at some point (between raw/PREROUTING and mangle/PREROUTING, or between raw/OUTPUT and mangle/OUTPUT) the packet traverses conntrack.
At this point, conntrack will search in its own lookup tables (a mini lookup database kept in kernel memory):
nf_conntrack_ftp
, which is a plugin to the conntrack subsystem, detects that a packet is part of the separate data flow associated with the FTP commands PASV/EPSV or PORT/EPRT done on the command flow (on port 21).Addressing the question
All this being said, here are the answers to your two bullets:
in the main network namespace conntrack starts tracking connections as soon as its modules (including possible relevant protocol-specific sub-modules) are loaded. For non-initial network namespaces (containers...) this also requires that some other subsystem references it (such as OP's iptables's conntrack module or using once the command
conntrack
described later). This is the default and a packet must be specifically marked as UNTRACKED before the conntrack subsystem sees it for this packet to not be tracked. On Linux there are only a few cases where not tracking would be needed, but then of course stateful firewalling and stateful/dynamic NAT won't be available anymore (steless NAT which might even require to use UNTRACKED in the first place, can still be done, but not with iptables. tc or nftables can). To avoid conntrack handling some packets, this kind of iptables rule can be used (eg: port 80/tcp):When the packet traverses filter/INPUT and reaches this rule:
The iptables's specific kernel module
xt_conntrack
queries the conntrack subsystem (handled by the various relevant kernel modulesnf_conntrack*
) and asks about the state of this packet in its lookup database. If the answer isRELATED
orESTABLISHED
the packet matches and proceeds to the ACCEPT verdict. Actually the result is already cached in the packet the first time the lookup was done (usually by conntrack) so this is a cheap "lookup". This is thus a generic rule to handle flows already accepted before. Those flows can be initially accepted in rules explicitly mentioning-m conntrack --ctstate NEW
or simply rules not mentioning it but placed after this generic rule (but keep in mind the INVALID state, which should usually be DROPed before doing so).adding a bullet: the handling of incoming packets and outgoing packets is quite symmetrical between PREROUTING and OUTPUT (even if those don't look symmetrical): conntrack interfaces in PREROUTING as well as in OUTPUT (and in a few other places, considering NAT is working with conntrack, except for its first packet in state NEW traversing iptables's nat table). This might be slightly different from the description you wrote about IPFW. If a server running applications is also restricting outgoing flows, then it most likely needs this same generic iptables rule both in filter/OUTPUT and in filter/INPUT, to allow outgoing reply packets of already accepted incoming traffic to pass.
Additional informations
There are dedicated tools to interact with the conntrack subsystem's lookup tables from conntrack-tools.
conntrack
: to query, delete or update the contents of the lookup tables handled by conntrack.Some examples.
You can list all tracked entries (which can be big without additional filter) with:
If your system is doing NAT (eg a router in front of a private LAN, or running VMs and containers) you can use
--any-nat
,--src-nat
or--dst-nat
to only display resp. all NAT, all source NAT (masquerade), or all destination NAT (typically for forwarded ports):Real-time monitoring of conntrack events:
conntrackd
: a daemon whose two main purposes are (conntrack) flow accounting and statistics, or high-availability stateful firewall cluster state synchronization.Connection tracking is a separate function of Netfilter, and it is not configured with IPTables.
In the picture, there are two
conntrack
steps in INPUT path and one in OUTPUT path. These steps associate individual packets with existing connections tracked in the connection tracking table, or create new connection tracking entries in the table.Conntrack functionality is a Linux kernel module, and it is often included in the kernel in default configuration.
Conntrack operation can be tuned by adjusting
net.netfilter.nf_conntrack
sysctl values.Your second alternative is what happens. The state information is recorded by the Conntrack function, and the IPTables rule simply consults the Conntrack table for information.