Skip to content

iptables Cheatsheet

iptables is a user-space utility program that allows system administrators to configure the IP packet filter rules of the Linux kernel firewall. It is the most widely used firewall solution on Linux systems, providing powerful packet filtering, network address translation (NAT), and packet mangling capabilities.

Basic Concepts

Tables and Chains

bash
# Tables
filter    # Default table for packet filtering
nat       # Network Address Translation
mangle    # Packet alteration
raw       # Connection tracking exemption
security  # Mandatory Access Control rules

# Built-in Chains
INPUT     # Incoming packets to local system
OUTPUT    # Outgoing packets from local system
FORWARD   # Packets routed through the system
PREROUTING   # Packets before routing decision
POSTROUTING  # Packets after routing decision

Rule Structure

bash
# Basic syntax
iptables -t table -A chain -m match --match-options -j target

# Components
-t table     # Specify table (default: filter)
-A chain     # Append rule to chain
-I chain     # Insert rule at beginning
-D chain     # Delete rule from chain
-m match     # Match module
-j target    # Jump target (action)

Basic Commands

Viewing Rules

bash
# List all rules
iptables -L

# List rules with line numbers
iptables -L --line-numbers

# List rules in specific table
iptables -t nat -L

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

# List rules in numeric format
iptables -L -n

# List rules with detailed output
iptables -L -v -n --line-numbers

# Show rules as commands
iptables-save

Basic Rule Management

bash
# Append rule to chain
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

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

# Delete rule by specification
iptables -D INPUT -p tcp --dport 22 -j ACCEPT

# Delete rule by line number
iptables -D INPUT 3

# Replace rule at line number
iptables -R INPUT 1 -p tcp --dport 443 -j ACCEPT

# Flush all rules in chain
iptables -F INPUT

# Flush all rules in all chains
iptables -F

Chain Management

bash
# Create new chain
iptables -N CUSTOM_CHAIN

# Delete empty chain
iptables -X CUSTOM_CHAIN

# Rename chain
iptables -E OLD_CHAIN NEW_CHAIN

# Set default policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Zero packet counters
iptables -Z
iptables -Z INPUT

Filtering Rules

Protocol-based Filtering

bash
# TCP traffic
iptables -A INPUT -p tcp -j ACCEPT

# UDP traffic
iptables -A INPUT -p udp -j ACCEPT

# ICMP traffic
iptables -A INPUT -p icmp -j ACCEPT

# All protocols
iptables -A INPUT -p all -j ACCEPT

# Specific protocol by number
iptables -A INPUT -p 6 -j ACCEPT  # TCP

Port-based Filtering

bash
# Single port
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --sport 80 -j ACCEPT

# Port range
iptables -A INPUT -p tcp --dport 1000:2000 -j ACCEPT

# Multiple ports
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --sports 80,443 -j ACCEPT

# Exclude port
iptables -A INPUT -p tcp ! --dport 22 -j DROP

IP Address Filtering

bash
# Single IP address
iptables -A INPUT -s 192.168.1.100 -j ACCEPT
iptables -A INPUT -d 192.168.1.100 -j ACCEPT

# IP range (CIDR notation)
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

# IP range (explicit)
iptables -A INPUT -m iprange --src-range 192.168.1.10-192.168.1.20 -j ACCEPT

# Multiple IP addresses
iptables -A INPUT -s 192.168.1.100,192.168.1.101,192.168.1.102 -j ACCEPT

# Exclude IP address
iptables -A INPUT -s ! 192.168.1.100 -j ACCEPT

Interface-based Filtering

bash
# Specific interface
iptables -A INPUT -i eth0 -j ACCEPT
iptables -A OUTPUT -o eth0 -j ACCEPT

# Interface pattern
iptables -A INPUT -i eth+ -j ACCEPT
iptables -A INPUT -i wlan+ -j ACCEPT

# Loopback interface
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Advanced Matching

Connection State

bash
# Connection tracking
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP

# Connection tracking (newer syntax)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Time-based Rules

bash
# Time range
iptables -A INPUT -m time --timestart 09:00 --timestop 17:00 -j ACCEPT

# Specific days
iptables -A INPUT -m time --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT

# Date range
iptables -A INPUT -m time --datestart 2023-01-01 --datestop 2023-12-31 -j ACCEPT

# Combined time restrictions
iptables -A INPUT -m time --timestart 09:00 --timestop 17:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT

Rate Limiting

bash
# Limit connection rate
iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT

# Limit by recent connections
iptables -A INPUT -p tcp --dport 22 -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

# Hashlimit (per-source limiting)
iptables -A INPUT -p tcp --dport 80 -m hashlimit --hashlimit-above 10/min --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name http -j DROP

String Matching

bash
# Match string in packet payload
iptables -A INPUT -p tcp --dport 80 -m string --string "GET /admin" --algo bm -j DROP

# Case-insensitive string matching
iptables -A INPUT -p tcp --dport 80 -m string --string "admin" --algo bm --icase -j DROP

# Hex string matching
iptables -A INPUT -p tcp -m string --hex-string "|47 45 54|" --algo bm -j DROP

Packet Length

bash
# Packet length matching
iptables -A INPUT -m length --length 64 -j ACCEPT
iptables -A INPUT -m length --length 64:128 -j ACCEPT
iptables -A INPUT -m length --length :64 -j ACCEPT
iptables -A INPUT -m length --length 1500: -j DROP

NAT Configuration

Source NAT (SNAT)

bash
# Basic SNAT
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.1

# SNAT with port range
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.1:1024-65535

# SNAT for specific source
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.1

# Masquerading (dynamic SNAT)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Masquerading with port range
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE --to-ports 1024-65535

Destination NAT (DNAT)

bash
# Basic DNAT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100

# DNAT with port change
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80

# DNAT with port range
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100-192.168.1.110

# Load balancing DNAT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination 192.168.1.100
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination 192.168.1.101
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.102

Port Redirection

bash
# Redirect to local port
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8080

# Redirect incoming traffic
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

# Transparent proxy
iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner ! --uid-owner proxy -j REDIRECT --to-port 8080

Security Rules

Basic Security

bash
# Drop invalid packets
iptables -A INPUT -m state --state INVALID -j DROP

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

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

# Drop all other input
iptables -P INPUT DROP

Anti-DDoS Rules

bash
# SYN flood protection
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# Ping flood protection
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 2 -j ACCEPT

# Port scan protection
iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A INPUT -m recent --name portscan --remove
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

# Connection limit per IP
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT

Brute Force Protection

bash
# SSH brute force protection
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j LOG --log-prefix "SSH_brute_force: "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP

# HTTP brute force protection
iptables -A INPUT -p tcp --dport 80 -m string --string "POST /login" --algo bm -m recent --set --name HTTP_LOGIN
iptables -A INPUT -p tcp --dport 80 -m string --string "POST /login" --algo bm -m recent --update --seconds 300 --hitcount 5 --name HTTP_LOGIN -j DROP

Geo-blocking

bash
# Block specific countries (requires geoip module)
iptables -A INPUT -m geoip --src-cc CN,RU -j DROP

# Allow only specific countries
iptables -A INPUT -m geoip ! --src-cc US,CA,GB -j DROP

# Log blocked countries
iptables -A INPUT -m geoip --src-cc CN,RU -j LOG --log-prefix "GeoBlock: "
iptables -A INPUT -m geoip --src-cc CN,RU -j DROP

Logging and Monitoring

Logging Configuration

bash
# Basic logging
iptables -A INPUT -j LOG --log-prefix "INPUT: "

# Detailed logging
iptables -A INPUT -j LOG --log-prefix "INPUT_DROP: " --log-level 4 --log-tcp-options --log-ip-options

# Log with rate limiting
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "INPUT_LIMITED: "

# Custom log target
iptables -A INPUT -j ULOG --ulog-nlgroup 1 --ulog-prefix "FIREWALL: "

Monitoring Rules

bash
# Monitor specific ports
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH_ACCESS: "
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Monitor failed connections
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j LOG --log-prefix "CONNECTION_RESET: "

# Monitor port scans
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "NULL_SCAN: "
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "XMAS_SCAN: "

Statistics and Counters

bash
# View packet counters
iptables -L -v -n

# Reset counters
iptables -Z

# Per-rule statistics
iptables -L INPUT -v -n --line-numbers

# Export statistics
iptables -L -v -n -x > /tmp/iptables_stats.txt

Persistence and Management

Saving Rules

bash
# Debian/Ubuntu
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

# Red Hat/CentOS
service iptables save
systemctl enable iptables

# Manual save/restore
iptables-save > /etc/iptables.rules
iptables-restore < /etc/iptables.rules

Automatic Loading

bash
# Systemd service
cat > /etc/systemd/system/iptables-restore.service << EOF
[Unit]
Description=Restore iptables rules
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables.rules
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl enable iptables-restore

# Network interface script
cat > /etc/network/if-up.d/iptables << EOF
#!/bin/bash
iptables-restore < /etc/iptables.rules
EOF
chmod +x /etc/network/if-up.d/iptables

Configuration Management

bash
# Backup current rules
iptables-save > /backup/iptables-$(date +%Y%m%d).rules

# Test rules temporarily
iptables-restore < /tmp/test-rules.txt
# Rules will be lost on reboot if not saved

# Atomic rule replacement
iptables-restore --test < new-rules.txt && iptables-restore < new-rules.txt

Troubleshooting

Common Issues

bash
# Check if iptables is running
systemctl status iptables
systemctl status netfilter-persistent

# Verify kernel modules
lsmod | grep ip_tables
lsmod | grep iptable_filter
lsmod | grep iptable_nat

# Load required modules
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack

# Check for rule conflicts
iptables -L -v -n --line-numbers

Debugging Rules

bash
# Trace packet path
iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE
iptables -t raw -A OUTPUT -p tcp --dport 80 -j TRACE

# Monitor logs
tail -f /var/log/kern.log | grep iptables
tail -f /var/log/messages | grep kernel

# Test connectivity
nc -zv target_ip port
telnet target_ip port
nmap -p port target_ip

# Packet capture
tcpdump -i any -n port 80
tcpdump -i any -n host 192.168.1.100

Performance Issues

bash
# Check connection tracking
cat /proc/net/nf_conntrack | wc -l
cat /proc/sys/net/netfilter/nf_conntrack_max

# Optimize connection tracking
echo 65536 > /proc/sys/net/netfilter/nf_conntrack_max
echo 300 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established

# Monitor rule performance
iptables -L -v -n | grep -E "pkts|Chain"

Advanced Features

Custom Chains

bash
# Create custom chain
iptables -N CUSTOM_INPUT

# Add rules to custom chain
iptables -A CUSTOM_INPUT -p tcp --dport 22 -j ACCEPT
iptables -A CUSTOM_INPUT -p tcp --dport 80 -j ACCEPT
iptables -A CUSTOM_INPUT -j DROP

# Jump to custom chain
iptables -A INPUT -j CUSTOM_INPUT

# Return from custom chain
iptables -A CUSTOM_INPUT -p tcp --dport 443 -j RETURN

Packet Marking

bash
# Mark packets
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j MARK --set-mark 1

# Match marked packets
iptables -A FORWARD -m mark --mark 1 -j ACCEPT

# Copy marks
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

Traffic Shaping Integration

bash
# Mark traffic for QoS
iptables -t mangle -A POSTROUTING -p tcp --sport 22 -j MARK --set-mark 1
iptables -t mangle -A POSTROUTING -p tcp --sport 80 -j MARK --set-mark 2
iptables -t mangle -A POSTROUTING -p tcp --sport 443 -j MARK --set-mark 2

# Classify traffic
iptables -t mangle -A POSTROUTING -p tcp --sport 22 -j CLASSIFY --set-class 1:10
iptables -t mangle -A POSTROUTING -p tcp --sport 80 -j CLASSIFY --set-class 1:20

Best Practices

Security Best Practices

bash
# Default deny policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# Allow only necessary traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT

# Log dropped packets
iptables -A INPUT -j LOG --log-prefix "INPUT_DROP: "
iptables -A INPUT -j DROP

# Regular rule review
# Document all rules
# Remove unused rules
# Test rule changes

Performance Best Practices

bash
# Order rules by frequency
# Most common rules first
# Specific rules before general rules

# Use connection tracking
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Minimize rule complexity
# Use custom chains for complex logic
# Avoid unnecessary string matching

# Optimize connection tracking
echo 'net.netfilter.nf_conntrack_max = 131072' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_established = 300' >> /etc/sysctl.conf

Management Best Practices

bash
# Version control
git init /etc/iptables
git add /etc/iptables/rules.v4
git commit -m "Initial iptables configuration"

# Testing procedures
# Test in staging environment
# Use iptables-restore --test
# Have rollback plan ready

# Documentation
# Document rule purposes
# Maintain change log
# Include contact information

# Monitoring
# Set up log monitoring
# Monitor rule hit counts
# Alert on policy violations

Resources