Start with these fundamental commands that form the backbone of firewall configuration:
# Display current rules with line numbers
iptables -L -n --line-numbers
# Flush all rules (careful!)
iptables -F
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
Modern firewalls should leverage connection tracking for better performance:
# Allow established/related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Drop invalid packets
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
Protect your services against brute force attacks:
# Limit SSH connections to 3 per minute
iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --set
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --update --seconds 60 --hitcount 4 -j DROP
Implement stealthy service access:
# Sequence: 1000,2000,3000
iptables -N KNOCKING
iptables -A INPUT -j KNOCKING
# First knock
iptables -A KNOCKING -p tcp --dport 1000 -m recent --name AUTH1 --set -j DROP
# Second knock
iptables -A KNOCKING -m recent --name AUTH1 --remove
iptables -A KNOCKING -p tcp --dport 2000 -m recent --name AUTH2 --set -j DROP
# Third knock opens SSH
iptables -A KNOCKING -m recent --name AUTH2 --remove
iptables -A KNOCKING -p tcp --dport 3000 -m recent --name AUTH3 --set -j DROP
iptables -A KNOCKING -m recent --name AUTH3 --remove
iptables -A KNOCKING -p tcp --dport 22 -j ACCEPT
Create detailed logging for troubleshooting:
# Create logging chain
iptables -N LOGGING
# Log and drop
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A LOGGING -j DROP
# Apply to unwanted traffic
iptables -A INPUT -p tcp --dport 23 -j LOGGING # Telnet
iptables -A INPUT -p tcp --dport 1433 -j LOGGING # MS SQL
Don't forget about IPv6 firewall rules:
# Basic IPv6 rules
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -P INPUT DROP
Save and restore your configuration:
# Save rules
iptables-save > /etc/iptables.rules
ip6tables-save > /etc/ip6tables.rules
# Restore at boot (add to rc.local)
iptables-restore < /etc/iptables.rules
ip6tables-restore < /etc/ip6tables.rules
Leverage powerful matching capabilities:
# Match by time
iptables -A INPUT -m time --timestart 09:00 --timestop 17:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
# Match by packet rate
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# Match by string content
iptables -A INPUT -p tcp --dport 80 -m string --string "cmd.exe" --algo bm -j DROP
Before diving into advanced techniques, let's recap essential iptables concepts:
# Basic syntax structure:
iptables -A CHAIN -p PROTOCOL --dport PORT -j TARGET
# Example - allowing SSH:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Modern firewalls should leverage connection tracking for better performance:
# Allow established/related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Drop invalid packets
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
Protect against brute force attacks with rate limiting:
# Limit SSH connections to 3 per minute
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
Add an extra security layer with port knocking:
# Sequence: 1000,2000,3000
iptables -N KNOCKING
iptables -A INPUT -j KNOCKING
# First knock
iptables -A KNOCKING -p tcp --dport 1000 -m recent --name KNOCK1 --set -j DROP
# Second knock (must come within 10 seconds)
iptables -A KNOCKING -m recent --name KNOCK1 --remove -p tcp --dport 2000 -m recent --name KNOCK2 --set -j DROP
# Final knock opens SSH for 30 seconds
iptables -A KNOCKING -m recent --name KNOCK2 --remove -p tcp --dport 3000 -m recent --name SSH --set --seconds 30 -j DROP
iptables -A INPUT -m recent --name SSH --rcheck -p tcp --dport 22 -j ACCEPT
Create a dedicated logging chain for better monitoring:
# Create LOGDROP chain
iptables -N LOGDROP
iptables -A LOGDROP -j LOG --log-prefix "[IPTABLES DROP] " --log-level 4
iptables -A LOGDROP -j DROP
# Example usage:
iptables -A INPUT -p tcp --dport 80 -m string --string "badbot" --algo bm -j LOGDROP
Don't forget about IPv6 (ip6tables) in your security setup:
# Basic IPv6 rules example
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Save and restore your rules across reboots:
# Debian/Ubuntu:
iptables-save > /etc/iptables.rules
ip6tables-save > /etc/ip6tables.rules
# RHEL/CentOS:
service iptables save