Complete Guide to iptables Command¶
A detailed explanation of how to configure iptables, the standard Linux firewall functionality.
Key Points¶
Table & Chain Management
Detailed control with filter, nat, and mangle tables
Packet Processing Control
Fine-grained rule definitions in INPUT/OUTPUT/FORWARD
NAT & Forwarding Configuration
Port forwarding and masquerade settings
High Performance
Kernel-level high-speed packet processing
Basic Concepts of iptables¶
Packet Processing Flow¶
graph TD
A[Incoming Packet] --> B{Local destination?}
B -->|Yes| C[INPUT Chain]
B -->|No| D[FORWARD Chain]
E[Outgoing Packet] --> F[OUTPUT Chain]
C --> G[Local Process]
G --> F
D --> H[Forwarding Destination]
F --> I[Send]
subgraph "filter Table"
C
D
F
end
subgraph "nat Table"
J[PREROUTING]
K[POSTROUTING]
end
A --> J
I --> K
style C fill:#4ecdc4
style D fill:#ffeaa7
style F fill:#ff6b6b
style J fill:#a8e6cf
style K fill:#a8e6cfTables and Chains Relationship¶
| Table | Purpose | Main Chains |
|---|---|---|
| filter | Packet filtering | INPUT, OUTPUT, FORWARD |
| nat | Address translation | PREROUTING, POSTROUTING, OUTPUT |
| mangle | Packet modification | PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING |
| raw | Connection tracking exclusion | PREROUTING, OUTPUT |
Packet Flow and Inbound/Outbound¶
sequenceDiagram
participant E as External Network
participant F as Firewall
participant S as Server
Note over E,S: Inbound Traffic Flow
E->>F: 1. Receive packet
F->>F: 2. PREROUTING (nat)
F->>F: 3. Routing decision
F->>F: 4. INPUT (filter)
F->>S: 5. To local process
Note over E,S: Outbound Traffic Flow
S->>F: 1. From local process
F->>F: 2. OUTPUT (filter)
F->>F: 3. Routing
F->>F: 4. POSTROUTING (nat)
F->>E: 5. Send packet
Note over E,S: Forward Traffic Flow
E->>F: 1. Receive packet
F->>F: 2. PREROUTING (nat)
F->>F: 3. Routing decision
F->>F: 4. FORWARD (filter)
F->>F: 5. POSTROUTING (nat)
F->>E: 6. Send to destinationBasic Operation Commands¶
View Rules¶
# Display all rules
sudo iptables -L
# Display with detailed information
sudo iptables -L -v
# Display with line numbers
sudo iptables -L --line-numbers
# Display in numeric format (no name resolution)
sudo iptables -L -n
# Display specific table
sudo iptables -t nat -L
sudo iptables -t mangle -L
# Display specific chain
sudo iptables -L INPUT
sudo iptables -L OUTPUT
Default Chain Policy¶
# Check current policy
sudo iptables -L | head -n 10
# Set default policy
sudo iptables -P INPUT DROP # Deny all
sudo iptables -P OUTPUT ACCEPT # Allow all
sudo iptables -P FORWARD DROP # Deny forwarding
# Safe initial configuration example
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
Filtering Rules¶
INPUT Chain (Incoming Control)¶
# Allow loopback connections (required)
sudo iptables -A INPUT -i lo -j ACCEPT
# Allow continuation of established connections
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH connections
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow SSH only from specific IP
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 22 -j ACCEPT
# Allow web server
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow connections from specific network
sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
# Allow ICMP (ping)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Allow DNS
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
OUTPUT Chain (Outgoing Control)¶
# Generally allow all
sudo iptables -P OUTPUT ACCEPT
# Example of strict control
sudo iptables -P OUTPUT DROP
# Allow loopback
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow established connections
sudo iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow HTTP/HTTPS connections (for package updates, etc.)
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# Allow DNS queries
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
# Allow SSH connections
sudo iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
# Allow connections only to specific IP
sudo iptables -A OUTPUT -d 192.168.1.100 -j ACCEPT
Port Range Specification¶
# Specify port range
sudo iptables -A INPUT -p tcp --dport 8000:8100 -j ACCEPT
# Specify multiple ports
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT
# FTP data transfer (passive mode)
sudo iptables -A INPUT -p tcp --dport 21 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
NAT Configuration (Address Translation)¶
SNAT (Source NAT) and Masquerade¶
# Internet connection sharing (masquerade)
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# SNAT with specific IP
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.10
# Allow forwarding for internal network
sudo iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
DNAT (Destination NAT) and Port Forwarding¶
# Port forwarding to web server
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
# Forwarding to different port
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
# SSH forwarding (port change)
sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.100:22
# Load balancing across multiple IPs
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination 192.168.1.100:80
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.101:80
Advanced Rule Configuration¶
Connection Limiting and Rate Limiting¶
# Connection count limit
sudo iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
# Rate limiting (DDoS protection)
sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# SYN flood protection
sudo iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --syn -j DROP
# Ping limiting
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
Time-based Restrictions¶
# Time-based access control
sudo iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
# Allow web access only during specific hours
sudo iptables -A INPUT -p tcp --dport 80 -m time --timestart 08:00 --timestop 20:00 -j ACCEPT
MAC Address Control¶
# Allow connections from specific MAC address
sudo iptables -A INPUT -m mac --mac-source 00:11:22:33:44:55 -j ACCEPT
# Deny specific MAC address
sudo iptables -A INPUT -m mac --mac-source 00:AA:BB:CC:DD:EE -j DROP
Logging Configuration¶
# Log dropped packets
sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
# Log specific port access
sudo iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH-ACCESS: "
# Logging with rate limit
sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPTABLES-LIMIT: "
Rule Management¶
Adding and Deleting Rules¶
# Add rule (append to end)
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Insert rule (insert at beginning)
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
# Insert at specific position
sudo iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT
# Delete rule (by rule specification)
sudo iptables -D INPUT -p tcp --dport 443 -j ACCEPT
# Delete rule (by line number)
sudo iptables -D INPUT 3
# Flush entire chain
sudo iptables -F INPUT
sudo iptables -F OUTPUT
sudo iptables -F FORWARD
# Flush all tables and rules
sudo iptables -F
sudo iptables -t nat -F
sudo iptables -t mangle -F
Saving and Restoring Configuration¶
# Save configuration
sudo iptables-save > /etc/iptables/rules.v4
# or
sudo service iptables save # CentOS/RHEL
# Restore configuration
sudo iptables-restore < /etc/iptables/rules.v4
# Auto-save and restore setup
sudo apt install iptables-persistent # Debian/Ubuntu
sudo systemctl enable iptables # CentOS/RHEL
Security Hardening Configuration¶
Basic Attack Protection¶
# Drop invalid packets
sudo iptables -A INPUT -m state --state INVALID -j DROP
# SYN flood protection
sudo iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Fragmented packet control
sudo iptables -A INPUT -f -j DROP
# Drop private IP access from external interface
sudo iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
sudo iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
sudo iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
# Drop 127.0.0.0/8 on non-loopback interface
sudo iptables -A INPUT ! -i lo -s 127.0.0.0/8 -j DROP
Port Scan Protection¶
# Detect and drop port scans
sudo iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
sudo iptables -A INPUT -m recent --name portscan --remove
sudo iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "PORTSCAN-DETECTED: "
sudo iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
Practical Configuration Examples¶
Web Server Configuration¶
#!/bin/bash
# iptables configuration for web server
# Set basic policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH connections (management IP only)
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT
# Allow web server
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ICMP
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Rate limiting
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# Save configuration
iptables-save > /etc/iptables/rules.v4
Router/Gateway Configuration¶
#!/bin/bash
# iptables configuration for router
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# NAT table configuration
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Filter table configuration
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow internal network management
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
# Drop direct external access
iptables -A INPUT -i eth0 -j DROP
Troubleshooting¶
Configuration Verification and Diagnostics¶
# Detailed rule check
sudo iptables -L -v -n --line-numbers
sudo iptables -t nat -L -v -n --line-numbers
# Check packet counters
sudo iptables -L -v | grep "packets bytes"
# Check logs
sudo journalctl -k | grep "IPTABLES"
sudo tail -f /var/log/kern.log | grep "IPTABLES"
# Check connection status
sudo netstat -tuln
sudo ss -tuln
# Connection test
telnet server-IP port-number
nc -zv server-IP port-number
Common Issues and Solutions¶
1. SSH Connection Lost¶
# Emergency recovery via console access
sudo iptables -I INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -P INPUT ACCEPT
# Reset configuration
sudo iptables -F
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
2. Configuration Lost After Reboot¶
# Check persistence configuration
sudo systemctl status iptables # CentOS/RHEL
sudo systemctl status netfilter-persistent # Debian/Ubuntu
# Manual save
sudo iptables-save > /etc/iptables.rules
echo "iptables-restore < /etc/iptables.rules" >> /etc/rc.local
3. NAT Not Working¶
# Check IP forwarding
cat /proc/sys/net/ipv4/ip_forward
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# Check NAT configuration
sudo iptables -t nat -L -v
Performance Optimization¶
Efficient Rule Ordering¶
# Place frequently matched rules at the top
iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT 2 -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# ...other rules
# Place deny rules at the end
iptables -A INPUT -j DROP
Connection Tracking Optimization¶
# Adjust connection tracking table size
echo 262144 > /proc/sys/net/netfilter/nf_conntrack_max
# Adjust timeout
echo 600 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
Summary¶
iptables is a powerful tool that provides high-performance packet control at the Linux kernel level.
Key Points for Configuration: - ✅ Understand packet flow (INPUT/OUTPUT/FORWARD) - ✅ Always prepare backup and recovery methods before configuration - ✅ Consider rule order and arrange efficiently - ✅ Perform regular configuration reviews and log monitoring