Understanding iptables conntrack State Tracking: When and How Packet States Are Managed


13 views

Unlike traditional firewalls like IPFW that require explicit state tracking rules, Linux's conntrack module in iptables operates automatically at the kernel level. The module begins tracking connection states the moment the first packet of a new connection hits the network stack - before any iptables rules are processed.

The state table gets populated through these automatic mechanisms:

1. When SYN packet initiates TCP connection
2. When first packet of UDP "connection" arrives
3. When ICMP request is detected
4. For other protocol's initial packets

Rules such as:

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

are not enabling tracking, but rather querying the existing state table that was populated automatically. This rule means: "Accept packets that belong to already established connections or related connections (like FTP data channels)."

A typical stateful firewall setup would look like:

# Allow established/related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow new outgoing connections (tracking happens automatically)
iptables -A OUTPUT -j ACCEPT

# Allow specific new incoming connections (e.g., SSH)
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Default deny
iptables -P INPUT DROP
iptables -P FORWARD DROP

1. No need for explicit "keep state" rules - tracking is automatic
2. State table is shared between all chains (INPUT/OUTPUT/FORWARD)
3. States persist for some time even after connection closes (adjustable via sysctl)

To inspect the current connection tracking table:

conntrack -L
# Or for continuous monitoring:
conntrack -E

You can tune conntrack behavior through sysctl parameters:

# Increase maximum connections
sysctl -w net.netfilter.nf_conntrack_max=262144

# Adjust timeout for established TCP connections
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400

The Linux conntrack (connection tracking) module operates at a lower level than iptables rules and maintains connection states independently. Unlike BSD's IPFW where state tracking requires explicit rules, conntrack automatically tracks all connections passing through the system by default.

conntrack begins tracking packets as soon as they hit the network stack, before any iptables processing occurs. The module maintains a connection tracking table (/proc/net/nf_conntrack) with entries for each observed connection. This happens automatically for:

  • TCP connections (with full state tracking)
  • UDP "connections" (tracked as pseudo-connections)
  • ICMP (for error messages related to connections)

The example rule you mentioned:

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Does NOT initiate state tracking. Instead, it:

  1. References the existing connection state information maintained by conntrack
  2. Matches packets that are part of established connections or related to them
  3. Accepts these packets to bypass further processing

Here are some common scenarios with corresponding iptables rules:

# Basic stateful firewall allowing outgoing connections
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

To inspect current connections being tracked:

cat /proc/net/nf_conntrack
# Or using conntrack-tools:
conntrack -L

To remove specific entries:

conntrack -D -s 192.168.1.100

You can tune conntrack parameters via sysctl:

# Increase maximum connections
sysctl -w net.netfilter.nf_conntrack_max=65536

# Set timeout for TCP connections
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400

When troubleshooting:

# View conntrack table with timestamps
conntrack -L -o extended

# Monitor connection events in real-time
conntrack -E