Table of Contents
- Understanding iptables Fundamentals
- Installing and Enabling iptables
- Basic iptables Commands
- Advanced Rule Management
- Common Use Cases
- Saving and Persisting Rules
- Troubleshooting iptables
- Best Practices
- Conclusion
- References
Understanding iptables Fundamentals
At its core, iptables operates by processing network packets through a series of tables, chains, and rules. Let’s break these down:
Tables: The Organizational Backbone
iptables uses tables to group rules by function. The most commonly used tables are:
| Table | Purpose |
|---|---|
filter | Default table for packet filtering (allow/block traffic). |
nat | Network Address Translation (e.g., port forwarding, masquerading). |
mangle | Modify packet headers (e.g., TOS, TTL values). |
raw | Bypass connection tracking for specific packets. |
security | Mandatory Access Control (MAC) rules (e.g., SELinux integration). |
Chains: Pathways for Packet Flow
Each table contains chains—predefined pathways that packets traverse. Chains are processed in a specific order:
| Chain | Table(s) | When It’s Triggered |
|---|---|---|
PREROUTING | nat, mangle, raw | Before a packet is routed (for incoming traffic). |
INPUT | filter, mangle | For packets destined for the local system. |
FORWARD | filter, mangle | For packets routed through the system (e.g., routers). |
OUTPUT | All tables | For packets originating from the local system. |
POSTROUTING | nat, mangle | After routing (for outgoing traffic). |
Rules and Targets: The Decision-Makers
Rules are conditions applied to packets as they traverse chains. Each rule defines:
- Matching criteria (e.g., source IP, destination port).
- Target: Action to take if the packet matches (e.g., allow, block).
Common targets:
ACCEPT: Let the packet through.DROP: Silently discard the packet (no response sent).REJECT: Discard the packet and send an error response (e.g., “Connection refused”).LOG: Log packet details to the kernel log (use with--log-prefixfor context).MASQUERADE: Rewrite source IP (for NAT, e.g., home routers).DNAT: Rewrite destination IP/port (for port forwarding).
Installing and Enabling iptables
iptables is preinstalled on most Linux distributions, but you may need to install utilities for persistence.
On Debian/Ubuntu:
# Install iptables and persistence tool
sudo apt update && sudo apt install iptables iptables-persistent
# Enable and start the service (optional, for legacy systems)
sudo systemctl enable iptables
sudo systemctl start iptables
On RHEL/CentOS (Disable firewalld first):
# Stop and disable firewalld
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# Install iptables services
sudo yum install iptables-services
# Enable and start iptables
sudo systemctl enable iptables
sudo systemctl start iptables
Verify installation with:
sudo iptables --version
Basic iptables Commands
Viewing Rules
To list rules (default filter table):
sudo iptables -L
For verbose output (with packet counts and interfaces):
sudo iptables -L -v
To avoid DNS lookups (faster, numeric IPs/ports):
sudo iptables -L -n
To specify a table (e.g., nat):
sudo iptables -t nat -L -v -n
Adding/Removing Rules
-
Append a rule to the end of a chain:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Allow SSH -
Insert a rule at a specific position (e.g., top of the chain):
sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT # Allow HTTP (first rule) -
Delete a rule by line number (check line numbers with
-L --line-numbers):sudo iptables -L --line-numbers # List rules with line numbers sudo iptables -D INPUT 3 # Delete rule 3 in INPUT chain -
Flush all rules in a chain (use
-tto specify a table):sudo iptables -F INPUT # Flush INPUT chain (filter table) sudo iptables -t nat -F # Flush all nat table chains
Setting Default Policies
Default policies dictate what happens to packets that don’t match any rule. Use -P (policy):
sudo iptables -P INPUT DROP # Block all unmatched incoming traffic
sudo iptables -P FORWARD DROP # Block forwarded traffic (default for non-routers)
sudo iptables -P OUTPUT ACCEPT # Allow all outgoing traffic
⚠️ Warning: Always set INPUT to DROP after allowing critical services (e.g., SSH), or you’ll lock yourself out!
Advanced Rule Management
Matching Criteria: IPs, Ports, and Protocols
Refine rules with source/destination IPs, ports, and protocols:
- Source IP:
-s 192.168.1.100(allow only 192.168.1.100) - Destination IP:
-d 203.0.113.5 - Protocol:
-p tcp(TCP),-p udp(UDP),-p icmp(ping) - Ports:
--dport 80(destination port),--sport 1024:65535(source port range)
Example: Allow HTTP from a specific IP:
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 80 -j ACCEPT
Using Modules for Enhanced Matching
iptables uses kernel modules for advanced matching. Common modules:
-
state: Match connection state (e.g.,NEW,ESTABLISHED).
Example: Allow existing SSH connections:sudo iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED -j ACCEPT -
multiport: Match multiple ports.
Example: Allow HTTP (80), HTTPS (443), and SSH (22):sudo iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT -
comment: Add notes to rules (critical for documentation).sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT -m comment --comment "Allow SSH from office"
Logging and Rate Limiting
-
Log packets before dropping them (use
LOGtarget):sudo iptables -A INPUT -j LOG --log-prefix "UNAUTHORIZED ACCESS: " --log-level 4 sudo iptables -A INPUT -j DROPLogs appear in
/var/log/kern.log(Debian/Ubuntu) or/var/log/messages(RHEL/CentOS). -
Rate limit to prevent DoS attacks (e.g., limit ping requests):
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 10/min -j ACCEPT sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
Common Use Cases
Allowing SSH Access
Restrict SSH to a trusted IP range:
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP # Block all other SSH attempts
Permitting HTTP/HTTPS Traffic
Allow web traffic (port 80 for HTTP, 443 for HTTPS):
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT # HTTP
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT # HTTPS
Blocking Malicious IPs
Drop traffic from a known bad IP:
sudo iptables -A INPUT -s 198.51.100.10 -j DROP
For multiple IPs, use a loop or ipset (more efficient for large lists).
Port Forwarding (NAT)
Forward external port 8080 to internal port 80 on 10.0.0.5:
# Enable IP forwarding (persist in /etc/sysctl.conf with net.ipv4.ip_forward=1)
sudo sysctl -w net.ipv4.ip_forward=1
# Add DNAT rule in nat table
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80
# Allow forwarded traffic in filter table
sudo iptables -A FORWARD -p tcp -d 10.0.0.5 --dport 80 -j ACCEPT
Saving and Persisting Rules
iptables rules are temporary (lost on reboot). To persist them:
On Debian/Ubuntu (using iptables-persistent):
# Save rules to /etc/iptables/rules.v4
sudo iptables-save | sudo tee /etc/iptables/rules.v4
# Load rules on boot (handled by iptables-persistent service)
On RHEL/CentOS:
# Save rules to /etc/sysconfig/iptables
sudo service iptables save
Manual Save/Load:
# Save
sudo iptables-save > /path/to/rules.txt
# Load
sudo iptables-restore < /path/to/rules.txt
Troubleshooting iptables
Check Logs
If using LOG targets, inspect kernel logs:
sudo tail -f /var/log/kern.log | grep "UNAUTHORIZED ACCESS"
Test Rules
Use telnet or nc (netcat) to test port access:
telnet 203.0.113.5 22 # Test SSH port
nc -zv 203.0.113.5 80 # Test HTTP port
Verify Packet Counts
Check if rules are matching traffic with -v (verbose) output:
sudo iptables -L -v -n # Look for "pkts" and "bytes" columns
Best Practices
- Start with Default Deny: Set
INPUTandFORWARDpolicies toDROPto block all unmatched traffic. - Allow Only What’s Needed: Avoid overly permissive rules (e.g.,
-s 0.0.0.0/0for SSH). - Log Critical Events: Use
LOGtargets to monitor blocked traffic for anomalies. - Document Rules: Add comments with
-m commentto explain rule purpose. - Backup Rules: Save rules before making changes (e.g.,
iptables-save > backup.rules). - Test in Staging: Validate rules in a non-production environment first.
- Use
iptables-apply: A tool that reverts changes if you get locked out (install viaiptables-persistent).
Conclusion
iptables is a powerful tool for securing Linux systems, but it requires careful planning and testing. By mastering tables, chains, and rules, you can enforce granular network policies to protect against threats. Remember to persist rules, document changes, and follow best practices to maintain a robust firewall.