โ† All cheat sheets

IPTABLES

Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.

Iptables is the traditional Linux firewall tool for packet filtering.
Note: nftables is the successor, but iptables remains widely used.

BASIC CONCEPTS#

Tables:     filter, nat, mangle, raw, security
Chains:     INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING
Targets:    ACCEPT, DROP, REJECT, LOG, MASQUERADE, SNAT, DNAT

Default table is 'filter' with chains:
- INPUT:    Incoming packets destined for local
- OUTPUT:   Outgoing packets from local
- FORWARD:  Packets routed through

VIEW RULES#

iptables -L                     # List filter rules
iptables -L -v                  # Verbose (packets/bytes)
iptables -L -n                  # Numeric (no DNS lookup)
iptables -L -v -n               # Verbose + numeric
iptables -L --line-numbers      # Show rule numbers
iptables -L INPUT               # Specific chain
iptables -S                     # Show rules as commands
iptables -t nat -L              # List NAT rules
iptables -t mangle -L           # List mangle rules

BASIC RULE SYNTAX#

iptables -A CHAIN -j TARGET             # Append rule
iptables -I CHAIN -j TARGET             # Insert at top
iptables -I CHAIN 3 -j TARGET           # Insert at position 3
iptables -D CHAIN -j TARGET             # Delete by specification
iptables -D CHAIN 3                     # Delete by number
iptables -R CHAIN 3 -j TARGET           # Replace rule 3
iptables -F                             # Flush all rules
iptables -F CHAIN                       # Flush specific chain
iptables -X                             # Delete user chains
iptables -Z                             # Zero counters

MATCH OPTIONS#

-p protocol     # tcp, udp, icmp, all
-s source       # Source IP/network
-d destination  # Destination IP/network
-i interface    # Input interface
-o interface    # Output interface
--sport port    # Source port
--dport port    # Destination port
-m module       # Load match module

BASIC FILTERING#

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

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

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

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

# Allow ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Drop all other incoming
iptables -A INPUT -j DROP

# Allow all outgoing
iptables -A OUTPUT -j ACCEPT

ALLOW BY SOURCE#

# Allow from specific IP
iptables -A INPUT -s 192.168.1.100 -j ACCEPT

# Allow from network
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

# Allow SSH from specific network
iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 22 -j ACCEPT

BLOCK TRAFFIC#

# Block IP
iptables -A INPUT -s 192.168.1.100 -j DROP

# Block network
iptables -A INPUT -s 10.10.10.0/24 -j DROP

# Block port
iptables -A INPUT -p tcp --dport 23 -j DROP

# Reject (sends response) vs Drop (silent)
iptables -A INPUT -p tcp --dport 23 -j REJECT
iptables -A INPUT -p tcp --dport 23 -j DROP

PORT RANGES#

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

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

# Source port range
iptables -A OUTPUT -p tcp --sport 1024:65535 -j ACCEPT

STATE MATCHING#

# Connection states
iptables -A INPUT -m state --state NEW -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP

# Or using conntrack (newer)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

RATE LIMITING#

# Limit SSH connections
iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT

# Limit ICMP
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT

# Hashlimit per source IP
iptables -A INPUT -p tcp --dport 80 -m hashlimit \
    --hashlimit 50/second --hashlimit-burst 100 \
    --hashlimit-mode srcip --hashlimit-name http -j ACCEPT

LOGGING#

# Log before dropping
iptables -A INPUT -j LOG --log-prefix "DROPPED: " --log-level 4
iptables -A INPUT -j DROP

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

# Limit logging
iptables -A INPUT -m limit --limit 5/minute -j LOG --log-prefix "LIMIT: "

NAT - NETWORK ADDRESS TRANSLATION#

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

# MASQUERADE (dynamic source NAT)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# SNAT (static source NAT)
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.1

# DNAT (port forwarding)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

# Redirect (local port redirect)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

PORT FORWARDING EXAMPLE#

# Forward external port 8080 to internal 192.168.1.100:80
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT

SET DEFAULT POLICIES#

iptables -P INPUT DROP          # Default drop incoming
iptables -P FORWARD DROP        # Default drop forwarded
iptables -P OUTPUT ACCEPT       # Default allow outgoing

SAVE AND RESTORE#

# Save rules
iptables-save > /etc/iptables.rules
iptables-save > /etc/iptables/rules.v4     # Debian/Ubuntu

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

# Persistent (Debian/Ubuntu)
apt install iptables-persistent
netfilter-persistent save
netfilter-persistent reload

# Persistent (RHEL/CentOS)
service iptables save
systemctl enable iptables

CUSTOM CHAINS#

# Create chain
iptables -N MYCHAIN

# Add rules to chain
iptables -A MYCHAIN -s 192.168.1.0/24 -j ACCEPT
iptables -A MYCHAIN -j DROP

# Jump to chain
iptables -A INPUT -p tcp --dport 22 -j MYCHAIN

# Delete chain (must be empty and unused)
iptables -F MYCHAIN
iptables -X MYCHAIN

COMPLETE FIREWALL EXAMPLE#

#!/bin/bash
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F

# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

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

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

# Allow SSH (with rate limit)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
    -m limit --limit 3/min --limit-burst 3 -j ACCEPT

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

# Allow ping (limited)
iptables -A INPUT -p icmp --icmp-type echo-request \
    -m limit --limit 1/second -j ACCEPT

# Log dropped packets
iptables -A INPUT -m limit --limit 5/min -j LOG \
    --log-prefix "iptables dropped: " --log-level 7

# Drop everything else (already default, but explicit)
iptables -A INPUT -j DROP

BRUTE FORCE PROTECTION#

# SSH brute force protection using recent module
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 --name SSH -j DROP

BLOCK INVALID PACKETS#

iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

IP6TABLES (IPv6)#

# Same syntax, use ip6tables
ip6tables -L
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT

DEBUGGING#

# Watch rules in action
watch -n 1 'iptables -L -v -n'

# Trace packet (requires raw table)
iptables -t raw -A PREROUTING -p tcp --dport 22 -j TRACE
# View in: dmesg or /var/log/kern.log

# Test rule without saving
iptables -A INPUT -s 1.2.3.4 -j DROP
# Then: iptables -D INPUT -s 1.2.3.4 -j DROP

QUICK REFERENCE#

iptables -L -v -n              # List rules
iptables -A INPUT -j ACCEPT    # Append rule
iptables -I INPUT -j ACCEPT    # Insert at top
iptables -D INPUT 3            # Delete rule 3
iptables -F                    # Flush all
iptables -P INPUT DROP         # Set policy
iptables-save > rules          # Save
iptables-restore < rules       # Restore