๐ conntrack Connection Tracking โ
What is Connection Tracking? โ
For a firewall to determine whether a packet belongs to a "new connection" or is a "subsequent packet of an existing connection," it relies on conntrack (Connection Tracking). It maintains a connection table that records the state of each connection.
This is why you often see -m state --state ESTABLISHED,RELATED -j ACCEPT โ it allows reply packets for established connections to pass through, saving you from writing rules for each direction.
๐ก Tip: ๐ก Three states: NEW โ the first packet, the start of a new connection. ESTABLISHED โ connection established, data flowing in both directions. RELATED โ related to an existing connection (e.g., FTP data channel, ICMP errors). There's also INVALID โ unrecognized packets, which are usually dropped directly.
Viewing the Connection Tracking Table โ
# View all tracked connections
conntrack -L
tcp 6 431999 ESTABLISHED src=192.168.1.100 dst=10.0.0.50 sport=54321 dport=80 src=10.0.0.50 dst=192.168.1.100 sport=80 dport=54321 [ASSURED] use=1
udp 17 29 src=192.168.1.100 dst=8.8.8.8 sport=12345 dport=53 src=8.8.8.8 dst=192.168.1.100 sport=53 dport=12345 use=1
# View only TCP connections
conntrack -L -p tcp
# View connections from a specific IP
conntrack -L -s 192.168.1.100
# Count connections
conntrack -C
247
# View the maximum tracking count allowed by the kernel
sysctl net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_max = 262144โ ๏ธ Warning: โ ๏ธ What happens when the connection limit is reached? If the tracking table is full (reaching nf_conntrack_max), new connections will be silently dropped! Your server will suddenly "lose connectivity" โ SSH disconnects, websites become inaccessible, but ping might still work. This is one of the most common "mysterious failures" in production environments.
Adjusting Connection Tracking Parameters โ
# View current values
sysctl net.netfilter.nf_conntrack_max
sysctl net.netfilter.nf_conntrack_tcp_timeout_established
# Temporary adjustment (lost on reboot)
sysctl -w net.netfilter.nf_conntrack_max=524288
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
# Make permanent โ write to /etc/sysctl.conf
cat >> /etc/sysctl.conf << 'EOF'
# conntrack optimization
net.netfilter.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_tcp_timeout_established = 3600
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
EOF
sysctl -p
# Monitor tracking table usage
watch -n 2 'conntrack -C && echo "/ $(sysctl -n net.netfilter.nf_conntrack_max)"'๐ก Tip: ๐ก Recommended values: Regular web server: 524288 (2x the default). High-traffic Nginx reverse proxy: 1048576. Database server: default is usually sufficient. Reducing TIME_WAIT timeout from the default 120s to 30s can reclaim many "zombie connections."
conntrack and Performance โ
conntrack isn't free โ every connection takes up a record in the kernel. Pay special attention in the following scenarios:
| Scenario | Problem | Solution |
|---|---|---|
| NAT gateway | All internal traffic goes through conntrack, table fills up quickly | Increase nf_conntrack_max + optimize timeouts |
| High-concurrency web | Massive short-lived connections put pressure on tracking table | Use NOTRACK to skip tracking + keepalive |
| DNS server | Many short UDP connections | Set short UDP timeout (15-30s) |
| FTP server | RELATED state tracking adds extra overhead | Load nf_conntrack_ftp module |
# Skip connection tracking for specific traffic (improve performance)
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport 80 -j NOTRACK
# Accordingly, this traffic cannot be matched with -m state
# Use -m conntrack --ctstate or just allow directly
iptables -A INPUT -p tcp --dport 80 -j ACCEPT