Skip to main content

iptables Troubleshooting

Comprehensive troubleshooting guide for iptables with detailed explanations of common issues and solutions.


Common Issues and Solutions

1. Connection Issues

Problem: Can't connect to SSH

# Check if SSH rule exists
iptables -L INPUT --line-numbers | grep 22

# Check if rule is being hit
iptables -L INPUT -v | grep 22

# Test SSH rule specifically
iptables -C INPUT -p tcp --dport 22 -j ACCEPT

Solution: Add SSH rule

# Allow SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Or insert at beginning for higher priority
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

Problem: Web server not accessible

# Check HTTP/HTTPS rules
iptables -L INPUT --line-numbers | grep -E "(80|443)"

# Check if established connections are allowed
iptables -L INPUT | grep ESTABLISHED

Solution: Add web server rules

# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

2. Rule Order Problems

Problem: Rules not working as expected

# Check rule order
iptables -L INPUT --line-numbers

# Check default policy
iptables -L INPUT | grep "policy"

Solution: Reorder rules

# Insert rule at specific position
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

# Delete rule by number
iptables -D INPUT 5

# Replace rule
iptables -R INPUT 3 -p tcp --dport 80 -j ACCEPT

3. NAT Issues

Problem: NAT not working

# Check if IP forwarding is enabled
cat /proc/sys/net/ipv4/ip_forward

# Check NAT rules
iptables -t nat -L -v

# Check FORWARD chain
iptables -L FORWARD -v

Solution: Enable IP forwarding and NAT

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Make permanent
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

# Add NAT rule
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

# Allow forwarding
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

4. Performance Issues

Problem: High CPU usage

# Check rule counts
iptables -L INPUT -v

# Check for inefficient rules
iptables -L INPUT --line-numbers

Solution: Optimize rule order

# Move common rules to top
iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT 2 -i lo -j ACCEPT

# Use ipset for large lists
ipset create blocked hash:ip
iptables -A INPUT -m set --match-set blocked src -j DROP

Debugging Techniques

1. Rule Testing

Test if rule exists

# Test specific rule
iptables -C INPUT -p tcp --dport 22 -j ACCEPT

# Check exit code
echo $?
# 0 = rule exists, 1 = rule doesn't exist

Test packet flow

# Simulate packet with iptables-save
iptables-save | grep -A 10 -B 10 "your-rule"

2. Packet Tracing

Enable packet logging

# Log all packets temporarily
iptables -I INPUT 1 -j LOG --log-prefix "DEBUG: "

# Log specific packets
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH: "

Monitor logs

# Watch logs in real-time
tail -f /var/log/messages | grep "DEBUG:"

# Check recent logs
grep "SSH:" /var/log/messages | tail -10

3. Connection Testing

Test connectivity

# Test basic connectivity
ping -c 3 8.8.8.8

# Test specific port
telnet localhost 22

# Test from remote
telnet your-server-ip 22

Check connection states

# Check current connections
netstat -tuln

# Check connection tracking
cat /proc/net/nf_conntrack | head -10

Diagnostic Commands

1. Rule Analysis

List all rules with details

# List with line numbers and packet counts
iptables -L INPUT --line-numbers -v

# List with numeric addresses
iptables -L INPUT -n

# Show rule specifications
iptables -L INPUT -x

Check specific chains

# Check INPUT chain
iptables -L INPUT -v

# Check NAT table
iptables -t nat -L -v

# Check mangle table
iptables -t mangle -L -v

2. Statistics and Counters

Reset counters

# Reset all counters
iptables -Z

# Reset specific chain
iptables -Z INPUT

Monitor packet flow

# Watch packet counts
watch -n 1 'iptables -L INPUT -v'

# Monitor specific rule
watch -n 1 'iptables -L INPUT -v | grep "your-rule"'

3. System Information

Check kernel modules

# Check if iptables modules are loaded
lsmod | grep -E "(iptable|nf_conntrack)"

# Load missing modules
modprobe iptable_filter
modprobe nf_conntrack

Check system limits

# Check connection tracking limits
cat /proc/sys/net/netfilter/nf_conntrack_max

# Check connection tracking table
cat /proc/net/nf_conntrack | wc -l

Common Error Messages

1. "No chain/target/match by that name"

# Problem: Module not loaded
# Solution: Load required module
modprobe iptable_nat
modprobe nf_conntrack

2. "Bad argument"

# Problem: Invalid syntax
# Solution: Check parameter format
# Correct: --dport 80
# Wrong: --dport 80:90 (use --dport 80:90 for ranges)

3. "Permission denied"

# Problem: Not running as root
# Solution: Use sudo
sudo iptables -L

4. "Table does not exist"

# Problem: Table not available
# Solution: Check if table is compiled in kernel
cat /proc/net/ip_tables_names

Recovery Procedures

1. Emergency Access

If locked out via SSH

# Connect via console or KVM
# Flush all rules
iptables -F
iptables -X

# Set permissive policies
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

If web server is blocked

# Temporarily allow all traffic
iptables -P INPUT ACCEPT

# Or add specific rule
iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT

2. Rule Recovery

Restore from backup

# Restore saved rules
iptables-restore < /etc/iptables/rules.v4

# Or restore from specific file
iptables-restore < /path/to/backup.rules

Rebuild rules step by step

# Start with basic rules
iptables -P INPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Monitoring Scripts

1. Basic Monitoring

#!/bin/bash
# Basic iptables monitoring

echo "=== iptables Status ==="
iptables -L INPUT --line-numbers -v

echo -e "\n=== Recent Logs ==="
tail -10 /var/log/messages | grep -E "(DROP|ACCEPT|LOG)"

echo -e "\n=== Connection Count ==="
netstat -an | grep ESTABLISHED | wc -l

2. Advanced Monitoring

#!/bin/bash
# Advanced monitoring with alerts

# Check for excessive drops
DROP_COUNT=$(iptables -L INPUT -v | grep DROP | awk '{sum+=$1} END {print sum}')
if [ "$DROP_COUNT" -gt 100 ]; then
echo "WARNING: High number of dropped packets: $DROP_COUNT"
fi

# Check for SSH brute force
SSH_ATTEMPTS=$(grep "SSH" /var/log/messages | wc -l)
if [ "$SSH_ATTEMPTS" -gt 50 ]; then
echo "WARNING: High number of SSH attempts: $SSH_ATTEMPTS"
fi

# Check connection tracking
CONN_COUNT=$(cat /proc/net/nf_conntrack | wc -l)
echo "Current connections: $CONN_COUNT"

3. Rule Testing Script

#!/bin/bash
# Test common rules

echo "Testing common iptables rules..."

# Test SSH rule
if iptables -C INPUT -p tcp --dport 22 -j ACCEPT 2>/dev/null; then
echo "✓ SSH rule exists"
else
echo "✗ SSH rule missing"
fi

# Test HTTP rule
if iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then
echo "✓ HTTP rule exists"
else
echo "✗ HTTP rule missing"
fi

# Test established connections rule
if iptables -C INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 2>/dev/null; then
echo "✓ Established connections rule exists"
else
echo "✗ Established connections rule missing"
fi

# Check default policies
echo "Default policies:"
iptables -L | grep "policy"

Best Practices for Troubleshooting

1. Always test in safe environment

# Use test machine or VM
# Have console access ready
# Test rules before applying to production

2. Use logging for debugging

# Add temporary logging
iptables -I INPUT 1 -j LOG --log-prefix "DEBUG: "

# Remove after debugging
iptables -D INPUT 1

3. Keep backups

# Save rules regularly
iptables-save > /etc/iptables/rules.v4.backup

# Version control your rules
git add /etc/iptables/rules.v4
git commit -m "Update iptables rules"

4. Document changes

# Comment your rules
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # SSH access

# Keep change log
echo "$(date): Added SSH rule" >> /var/log/iptables-changes.log

Note: Always have alternative access methods (console, KVM) before applying restrictive iptables rules to avoid being locked out.