How to Debug Packet Drops in iptables: Rule Tracking and Logging Techniques


2 views

When debugging iptables rules, it's crucial to understand the packet traversal order through the chains:


INPUT → PREROUTING → FORWARD → POSTROUTING → OUTPUT

Each packet is evaluated against rules sequentially until it matches a terminating target (ACCEPT/DROP/REJECT).

The simplest way to track dropped packets is using iptables' built-in counters:


# List all rules with packet/byte counters
sudo iptables -L -n -v

# Example output:
Chain INPUT (policy DROP 12 packets, 1204 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   15  1344 ACCEPT     all  --  eth0   *       192.168.1.0/24       0.0.0.0/0           
    2   144 DROP       all  --  *      *       10.0.0.0/8           0.0.0.0/0

For more detailed debugging, insert logging rules before critical targets:


# Log dropped packets in INPUT chain
sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4

# Log accepted packets in OUTPUT chain
sudo iptables -I OUTPUT 1 -j LOG --log-prefix "IPTABLES-ACCEPT: " --log-level 6

View logs using:


sudo tail -f /var/log/syslog | grep IPTABLES

For kernel-level tracing (requires kernel 2.6.24+):


# Load the trace module
sudo modprobe nf_log_ipv4

# Enable tracing for specific rule
sudo iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE

# Monitor trace output
sudo dmesg -w | grep TRACE

This bash script helps verify rule effectiveness:


#!/bin/bash
RULES=$(sudo iptables -L -n --line-numbers)
echo "Current iptables rules:"
echo "$RULES"

echo -e "\nTesting rule effectiveness..."
for chain in INPUT FORWARD OUTPUT; do
  echo "Chain $chain packet counts:"
  sudo iptables -L $chain -n -v | grep -E 'ACCEPT|DROP|REJECT'
done

Case 1: Port blocking mystery


# Add logging before your port rule
sudo iptables -I INPUT -p tcp --dport 8080 -j LOG --log-prefix "8080-Access: "

# Then check which process might be interfering
sudo netstat -tulnp | grep 8080

Case 2: Tracking NAT issues


# Enable logging for NAT table
sudo iptables -t nat -L -v -n

# Add trace for NAT operations
sudo iptables -t nat -A PREROUTING -j TRACE

When debugging iptables behavior, it's crucial to understand the rule evaluation flow. Packets traverse chains sequentially until they match a rule with terminating target (ACCEPT/DROP/REJECT). The key debugging commands are:

# View all rules with packet/byte counters
iptables -L -n -v

# Check specific chain (e.g., INPUT)
iptables -L INPUT -n -v --line-numbers

# Reset counters to zero for fresh monitoring
iptables -Z

For real-time debugging, insert LOG rules before critical rules:

# Log UDP packets on port 53 before processing
iptables -I INPUT -p udp --dport 53 -j LOG --log-prefix "[DNS-INPUT] "

# View logs (systemd)
journalctl -k -f | grep DNS-INPUT

Modern kernels support packet tracing:

# Enable tracing module
modprobe nf_log_ipv4
sysctl net.netfilter.nf_log.2=nf_log_ipv4

# Add trace rule
iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE

# View trace (requires debugfs)
mount -t debugfs none /sys/kernel/debug
tail -f /sys/kernel/debug/tracing/trace_pipe

For complex rule sets, create a dedicated debug chain:

# Create chain
iptables -N DEBUG

# Redirect specific traffic
iptables -A INPUT -s 192.168.1.100 -j DEBUG

# Add debug rules
iptables -A DEBUG -j LOG --log-prefix "DEBUG-IN: "
iptables -A DEBUG -j RETURN

This Bash script monitors dropped packets hourly:

#!/bin/bash
LOG_FILE="/var/log/iptables_drops.log"

while true; do
    date >> $LOG_FILE
    iptables -L INPUT -n -v | grep DROP >> $LOG_FILE
    iptables -L OUTPUT -n -v | grep DROP >> $LOG_FILE
    sleep 3600
done