Table of Contents
- Understanding iptables Basics
- Chains, Tables, Rules, and Targets
- Packet Flow in iptables
- Prerequisites
- Viewing Current iptables Rules
- Configuring Basic Security Rules
- Setting Default Policies
- Allowing Loopback Traffic
- Allowing SSH Access
- Allowing HTTP/HTTPS (Web Servers)
- Allowing ICMP (Ping) (Optional)
- Advanced iptables Configurations
- Port Forwarding
- Rate Limiting to Prevent DoS Attacks
- Blocking Specific IP Addresses
- Saving Rules Permanently
- Testing Your Firewall Configuration
- Troubleshooting Common Issues
- References
1. Understanding iptables Basics
Before diving into commands, let’s clarify key concepts:
Chains, Tables, Rules, and Targets
-
Tables: iptables organizes rules into tables based on their purpose. The most common tables are:
filter: Default table for packet filtering (INPUT, OUTPUT, FORWARD chains).nat: Used for network address translation (e.g., port forwarding, masquerading).mangle: For modifying packet headers (e.g., TTL, DSCP marking).
-
Chains: Within each table, rules are grouped into chains—predefined paths packets follow:
INPUT: Packets destined for the local system.OUTPUT: Packets originating from the local system.FORWARD: Packets routed through the system (e.g., a router).PREROUTING(nat/mangle): Processes packets before routing (for port forwarding).POSTROUTING(nat/mangle): Processes packets after routing (for masquerading).
-
Rules: Conditions that match packets (e.g., source IP, port, protocol). Rules are processed top-to-bottom; the first matching rule is applied.
-
Targets: Actions taken when a rule matches. Common targets:
ACCEPT: Allow the packet.DROP: Silently discard the packet (no response sent).REJECT: Discard the packet and send an error response (e.g., “Connection refused”).LOG: Log the packet (useful for debugging).
Packet Flow in iptables
Packets enter the system and traverse chains in this order:
PREROUTING(nat/mangle tables) → Routing decision (local vs. forward).- If local:
INPUT(filter table) → Processed by the system. - If forwarded:
FORWARD(filter table) →POSTROUTING(nat/mangle tables) → Exit. - Outgoing packets:
OUTPUT(filter/nat/mangle tables) →POSTROUTING(nat/mangle tables) → Exit.
2. Prerequisites
- A Linux system (Debian/Ubuntu, RHEL/CentOS, etc.).
iptablesinstalled (check withiptables --version; install viasudo apt install iptablesorsudo yum install iptables).sudoprivileges (to modify rules).- Caution: If working remotely (e.g., SSH), avoid locking yourself out! Test rules in a non-production environment first.
3. Viewing Current iptables Rules
Before making changes, check existing rules to avoid conflicts:
# List rules (human-readable format)
sudo iptables -L
# List rules with line numbers and detailed info (recommended)
sudo iptables -L --line-numbers -v
# List rules in "save" format (for scripting/backup)
sudo iptables -S
Output Explanation (from iptables -L):
Chain: The chain (e.g., INPUT).target: Action if the rule matches (e.g., ACCEPT).prot: Protocol (tcp, udp, icmp, etc.).opt: Optional flags (e.g.,--dportfor destination port).source/destination: Source/destination IP or CIDR.
4. Configuring Basic Security Rules
Setting Default Policies
By default, iptables allows all traffic. For security, set default policies to DROP (deny all) and explicitly allow only necessary traffic:
# Set default policy for INPUT, FORWARD, and OUTPUT chains to DROP
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT DROP
Why DROP? DROP hides your system from attackers (no response), while REJECT reveals the system exists (use REJECT only if you want to signal “port closed”).
Allowing Loopback Traffic
The loopback interface (lo) is critical for local services (e.g., databases, APIs). Allow it explicitly:
# Allow all loopback traffic
sudo iptables -A INPUT -i lo -j ACCEPT # Incoming loopback
sudo iptables -A OUTPUT -o lo -j ACCEPT # Outgoing loopback
Allowing SSH Access
SSH is essential for remote management. Allow it for your IP (or all IPs, if needed):
# Allow SSH from a specific IP (replace 192.168.1.100 with your IP)
sudo iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT
# Allow SSH from any IP (less secure; use only if necessary)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow outgoing SSH (if your system initiates SSH connections)
sudo iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
Critical Note: If you lock yourself out (e.g., wrong IP), use physical/console access to reset rules with sudo iptables -F (flush all rules).
Allowing HTTP/HTTPS (Web Servers)
For web servers, allow ports 80 (HTTP) and 443 (HTTPS):
# Allow incoming HTTP (port 80)
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow incoming HTTPS (port 443)
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow outgoing HTTP/HTTPS (for system updates, etc.)
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
Allowing ICMP (Ping) (Optional)
ICMP (Internet Control Message Protocol) includes “ping” (echo requests). Allowing pings helps troubleshoot connectivity but exposes your system. To allow:
# Allow incoming ping (echo request)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Allow outgoing ping responses (echo reply)
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
To block pings, skip these rules (default DROP policy applies).
5. Advanced iptables Configurations
Port Forwarding
Use the nat table to forward traffic from a public port to a private IP/port (e.g., route port 8080 on your server to a local web app at 192.168.1.5:80):
# Enable IP forwarding (temporarily; persist with sysctl)
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
# Forward incoming traffic on port 8080 to 192.168.1.5:80
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.5:80
# Masquerade (hide) the private IP behind the server's public IP
sudo iptables -t nat -A POSTROUTING -d 192.168.1.5 -j MASQUERADE
# Allow forwarded traffic through the FORWARD chain
sudo iptables -A FORWARD -p tcp -d 192.168.1.5 --dport 80 -j ACCEPT
Rate Limiting to Prevent DoS Attacks
Limit repeated requests (e.g., SSH brute-forcing) with the limit module:
# Allow SSH but limit to 5 connections per minute (burst of 10)
sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min --limit-burst 10 -j ACCEPT
--limit 5/min: Max 5 connections per minute.--limit-burst 10: Allow 10 initial connections (to handle legitimate spikes).
Blocking Specific IP Addresses
Block malicious IPs (e.g., from logs or threat feeds):
# Block a single IP
sudo iptables -A INPUT -s 1.2.3.4 -j DROP
# Block a CIDR range (e.g., 192.168.2.0/24)
sudo iptables -A INPUT -s 192.168.2.0/24 -j DROP
To remove a blocked IP later:
# Find the rule line number (replace "INPUT" with the chain)
sudo iptables -L INPUT --line-numbers
# Delete the rule (e.g., line 5 in INPUT chain)
sudo iptables -D INPUT 5
6. Saving Rules Permanently
By default, iptables rules are temporary (lost on reboot). Save them to persist across restarts:
Debian/Ubuntu
Use iptables-persistent to auto-load rules on boot:
# Install iptables-persistent
sudo apt install iptables-persistent
# Save current rules (IPv4)
sudo iptables-save | sudo tee /etc/iptables/rules.v4
# For IPv6 (optional)
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
RHEL/CentOS
Use the iptables service to save rules:
# Save rules
sudo service iptables save
# Verify (rules stored in /etc/sysconfig/iptables)
cat /etc/sysconfig/iptables
7. Testing Your Firewall Configuration
After setup, validate rules to ensure critical services work:
- SSH: Test from a remote machine:
ssh user@your-server-ip. - Web Services: Use
curlor a browser to check HTTP/HTTPS:curl http://your-server-ip. - Blocked Ports: Verify blocked ports with
telnet your-server-ip 23(should fail if port 23 is blocked).
Debugging Tip: Add a LOG target to trace dropped packets:
# Log dropped INPUT packets (add at the END of the INPUT chain)
sudo iptables -A INPUT -j LOG --log-prefix "iptables-DROP: " --log-level 4
# View logs (Debian/Ubuntu: /var/log/syslog; RHEL/CentOS: /var/log/messages)
sudo tail -f /var/log/syslog | grep "iptables-DROP"
8. Troubleshooting Common Issues
- Locked Out via SSH: Reboot the server (rules reset if not saved) or use console access to flush rules:
sudo iptables -F && sudo iptables -P INPUT ACCEPT. - Rules Not Saving: Ensure
iptables-persistent(Debian) oriptablesservice (RHEL) is enabled. - Port Forwarding Not Working: Check
ip_forward(runsysctl net.ipv4.ip_forward; set to1permanently in/etc/sysctl.conf).
9. References
By following this guide, you’ve built a secure, tailored firewall with iptables. Regularly audit rules and update them to adapt to new threats—security is an ongoing process!