Your stateful firewall silently tracks every connection. Allowing “established, related” traffic to return requires remembering that you initiated the connection. That’s conntrack.
When conntrack table fills up, new connections fail mysteriously. No error, just dropped. The firewall has no room to track new connections, so it drops them.
Conntrack is the invisible stateful firewall engine. When it fails, everything fails.
What Conntrack Does
Client → Router → Server
1. Client sends SYN to server2. Router creates conntrack entry: NEW3. Server responds with SYN-ACK4. Router updates entry: ESTABLISHED5. Traffic flows, entry tracks state6. Connection closes7. Entry times out, removedWithout conntrack, the firewall can’t know that a packet from the server is a response to your request vs. unsolicited traffic.
Viewing Conntrack Table
Basic Commands
# Show all connectionsshow conntrack table
# Show IPv4 connections onlyshow conntrack table ipv4
# Show IPv6 connections onlyshow conntrack table ipv6
# Show connection countshow conntrack table statisticsFiltering Conntrack
# Show connections to specific IPshow conntrack table ipv4 | grep "192.168.1.100"
# Show connections by protocolshow conntrack table ipv4 | grep "tcp"show conntrack table ipv4 | grep "udp"
# Show connections in specific stateshow conntrack table ipv4 | grep "ESTABLISHED"show conntrack table ipv4 | grep "TIME_WAIT"Direct Conntrack Commands
# Using conntrack tool directlysudo conntrack -L # List allsudo conntrack -L -p tcp # TCP onlysudo conntrack -L -s 192.168.1.100 # Source IPsudo conntrack -L -d 8.8.8.8 # Destination IPsudo conntrack -C # Count entriesConntrack Statistics
# View statisticsshow conntrack table statistics
# Or directlysudo conntrack -S
# Output:# cpu=0 found=12345 invalid=0 ignore=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0# cpu=1 found=12340 invalid=2 ignore=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
# Key metrics:# drop: Packets dropped due to conntrack issues# early_drop: Entries dropped to make room for new ones# insert_failed: Failed to create new entry (table full)Conntrack Table Size
Check Current Settings
# Current maximum entriescat /proc/sys/net/netfilter/nf_conntrack_max
# Current countcat /proc/sys/net/netfilter/nf_conntrack_count
# Hash table sizecat /proc/sys/net/netfilter/nf_conntrack_bucketsIncrease Table Size
configure
# Increase max connectionsset system conntrack table-size 262144 # Default is often 65536
# Adjust hash table size (should be ~25% of table-size)set system conntrack hash-size 65536
commitCalculate Requirements
Rule of thumb:- Each connection uses ~350 bytes- 65536 entries ≈ 22 MB RAM- 262144 entries ≈ 90 MB RAM
# For NAT gateway with 1000 users:# Assume 100 connections per user# 1000 × 100 = 100,000 connections# Set table-size to at least 150,000 (with headroom)Conntrack Timeouts
View Current Timeouts
# TCP timeoutscat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_establishedcat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_waitcat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait
# UDP timeoutscat /proc/sys/net/netfilter/nf_conntrack_udp_timeoutcat /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream
# ICMP timeoutcat /proc/sys/net/netfilter/nf_conntrack_icmp_timeoutConfigure Timeouts in VyOS
configure
# TCP timeoutsset system conntrack timeout tcp established 7200 # 2 hours (default 5 days!)set system conntrack timeout tcp close 10set system conntrack timeout tcp close-wait 60set system conntrack timeout tcp fin-wait 120set system conntrack timeout tcp last-ack 30set system conntrack timeout tcp syn-recv 60set system conntrack timeout tcp syn-sent 120set system conntrack timeout tcp time-wait 120
# UDP timeoutsset system conntrack timeout udp other 30set system conntrack timeout udp stream 180
# ICMP timeoutset system conntrack timeout icmp 30
commitAggressive Timeouts (For Busy NAT)
# For high-traffic NAT gateways with limited table sizeset system conntrack timeout tcp established 3600 # 1 hourset system conntrack timeout tcp time-wait 30 # Clear quicklyset system conntrack timeout udp other 30set system conntrack timeout udp stream 60
# Warning: Too aggressive can break long-lived connectionsConntrack Problems
Problem 1: Table Full
Symptoms:
- New connections fail randomly
- Established connections work
- Log shows “nf_conntrack: table full”
# Check table statusshow conntrack table statistics
# Look for:# early_drop > 0# insert_failed > 0
# Check current vs maxcat /proc/sys/net/netfilter/nf_conntrack_countcat /proc/sys/net/netfilter/nf_conntrack_max
# Fix: Increase sizeset system conntrack table-size 524288Problem 2: Memory Exhaustion
Large conntrack tables consume RAM:
# Calculate memory needed# 262144 entries × 350 bytes ≈ 90 MB
# If short on memory, reduce table or add RAM# Or reduce timeouts to expire entries fasterProblem 3: Stale Entries
Connections closed but entries remain:
# Clear specific entrysudo conntrack -D -s 192.168.1.100 -d 8.8.8.8
# Clear all entries (dangerous in production!)sudo conntrack -F
# Clear entries by protocolsudo conntrack -D -p udpProblem 4: Conntrack Not Tracking
# Some traffic bypasses conntrack (NOTRACK)# Check if tracking is enabled
show firewall
# Look for notrack rules:# set firewall ipv4 name RAW rule 10 action notrackNOTRACK Rules
For high-bandwidth traffic that doesn’t need stateful inspection:
configure
# Skip tracking for specific trafficset firewall ipv4 name RAW default-action acceptset firewall ipv4 name RAW rule 10 action notrackset firewall ipv4 name RAW rule 10 destination address 224.0.0.0/4set firewall ipv4 name RAW rule 10 description "Skip tracking for multicast"
# Apply to raw tableset firewall ipv4 input filter raw RAW
commitWhen to Use NOTRACK
- Multicast/broadcast traffic
- High-bandwidth services that don’t need state
- Traffic between trusted internal segments
- When conntrack table is bottleneck
Risks of NOTRACK
- No stateful filtering for that traffic
- “Established, related” rules won’t work
- Must use stateless rules for that traffic
Conntrack Helpers
Conntrack helpers track multi-connection protocols (FTP, SIP):
# View loaded helperslsmod | grep nf_conntrack
# Configure FTP helperset system conntrack modules ftp
# Configure SIP helperset system conntrack modules sip
commitFTP Active Mode Fix
# FTP active mode requires helper to track data connectionset system conntrack modules ftp
# Helper allows firewall to recognize FTP data connections# as related to control connectionMonitoring Conntrack
Watch Table Fill
# Monitor in real-timewatch -n 1 'cat /proc/sys/net/netfilter/nf_conntrack_count'
# Alert script#!/bin/bashMAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max)CURRENT=$(cat /proc/sys/net/netfilter/nf_conntrack_count)THRESHOLD=80
USAGE=$((CURRENT * 100 / MAX))
if [ $USAGE -gt $THRESHOLD ]; then echo "Conntrack ${USAGE}% full (${CURRENT}/${MAX})"fiPrometheus Metrics
# Node exporter exposes conntrack metrics:# node_nf_conntrack_entries# node_nf_conntrack_entries_limit
# Alert when > 80% full# expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8Conntrack by Connection Type
Heavy NAT Users
# Find IPs with most connectionssudo conntrack -L | awk '{print $5}' | cut -d= -f2 | sort | uniq -c | sort -rn | head
# Output:# 5234 192.168.1.50# 3421 192.168.1.51# ...Connection State Distribution
# Count by statesudo conntrack -L | grep -o 'tcp .* [A-Z_]*' | awk '{print $NF}' | sort | uniq -c | sort -rn
# Output:# 45234 ESTABLISHED# 2341 TIME_WAIT# 123 SYN_SENTBest Practices
1. Size for Peak Load
# Calculate peak connections# Add 50% headroomset system conntrack table-size 262144 # More is safer2. Tune Timeouts for Traffic
# Long-lived connections (database, SSH)set system conntrack timeout tcp established 86400 # 24h
# Short-lived connections (HTTP)set system conntrack timeout tcp established 3600 # 1h3. Monitor Always
# Alert before table fills# Dashboard showing:# - Current entries# - Max entries# - Entries/second rate4. NOTRACK Where Safe
# Reduce load by not tracking:# - Internal trusted traffic# - High-bandwidth transfers# - MulticastThe Lesson
Conntrack is the invisible stateful firewall engine. When it fails, everything fails.
Every “allow established, related” rule depends on conntrack. Every NAT translation depends on conntrack. Without it, no stateful firewalling.
When conntrack table fills:
- New connections silently fail
- No error message to user
- Existing connections keep working
- Very confusing symptoms
Prevention:
- Size table for expected load + headroom
- Tune timeouts for your traffic patterns
- Monitor table usage constantly
- Alert before it fills, not after
The connection table is limited. Plan for it.