funwithlinux guide

Real-World iptables Configurations: Study and Apply

In the realm of Linux network security, `iptables` stands as a cornerstone tool for managing firewall rules. As part of the **netfilter** framework, it enables granular control over incoming, outgoing, and forwarded network traffic. Whether you’re securing a personal server, a production web host, or even a home router, understanding `iptables` is critical to defending against unauthorized access, data breaches, and network attacks. This blog demystifies `iptables` by focusing on **practical, real-world configurations**. We’ll start with core concepts, then dive into step-by-step scenarios—from basic server hardening to advanced setups like NAT routing and brute-force protection. By the end, you’ll have the skills to design, implement, and maintain robust firewall rules tailored to your needs.

Table of Contents

  1. Understanding iptables Basics

    • 1.1 What is iptables?
    • 1.2 Key Concepts: Tables, Chains, and Targets
    • 1.3 Viewing and Managing Rules
  2. Real-World Scenario 1: Basic Linux Server Hardening

    • 2.1 Goal and Requirements
    • 2.2 Step-by-Step Configuration
    • 2.3 Verifying and Saving Rules
  3. Real-World Scenario 2: Web Server Protection

    • 3.1 Allowing HTTP/HTTPS and SSH
    • 3.2 Rate Limiting to Prevent Brute-Force Attacks
    • 3.3 Blocking Malicious IPs
  4. Real-World Scenario 3: Linux Router with NAT

    • 3.1 Enabling IP Forwarding
    • 3.2 Configuring Masquerading (NAT)
    • 3.3 Port Forwarding
  5. Real-World Scenario 4: Jump Host Security

    • 4.1 Restricting SSH Access by Source IP
    • 4.2 Logging and Auditing
  6. Best Practices for iptables Management

    • 6.1 Default Policies: Deny Everything First
    • 6.2 Comment Rules for Clarity
    • 6.3 Test Rules Before Persisting
  7. Troubleshooting Common iptables Issues

  8. References

1. Understanding iptables Basics

1.1 What is iptables?

iptables is a user-space utility that configures the Linux kernel’s netfilter framework—a set of hooks in the kernel that process network packets. It filters, modifies, or forwards packets based on predefined rules, making it indispensable for:

  • Blocking unauthorized access (e.g., closing unused ports).
  • Allowing legitimate traffic (e.g., SSH, HTTP).
  • Network Address Translation (NAT) for routing.
  • Logging suspicious activity.

1.2 Key Concepts: Tables, Chains, and Targets

To use iptables effectively, you need to grasp three core concepts:

Tables

Tables are collections of chains, organized by purpose:

  • filter: The default table for packet filtering (ACCEPT/DROP/REJECT).
  • nat: Used for network address translation (e.g., port forwarding, masquerading).
  • mangle: Modifies packet headers (e.g., TOS, TTL).
  • raw: Bypasses connection tracking for performance-critical traffic.

Chains

Chains are sequences of rules applied to packets at specific stages:

  • 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/raw): Processes packets before routing.
  • POSTROUTING (nat/mangle): Processes packets after routing.

Targets

Targets define what happens to a packet when it matches a rule:

  • ACCEPT: Allow the packet through.
  • DROP: Silently discard the packet (no response sent).
  • REJECT: Discard the packet and send an error (e.g., “Connection refused”).
  • LOG: Log the packet (use with --log-prefix for context).
  • MASQUERADE/SNAT: Rewrite source IPs (for NAT).

1.3 Viewing and Managing Rules

View Rules

List all rules in the filter table (default):

iptables -L -v  # -v for verbose (packet/byte counters)  
iptables -L -n  # -n for numeric IP/ports (faster, no DNS lookup)  

List rules in the nat table:

iptables -t nat -L -n  

Add/Delete Rules

Add a rule to allow SSH (port 22) in the INPUT chain:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT  
  • -A: Append to the chain (rules are processed top-to-bottom).
  • -p tcp: Match TCP protocol.
  • --dport 22: Target destination port 22.
  • -j ACCEPT: Jump to the ACCEPT target.

Delete a rule (by line number, e.g., delete the 3rd rule in INPUT):

iptables -D INPUT 3  

Flush Rules (Caution!)

Delete all rules in a chain (e.g., INPUT):

iptables -F INPUT  

Flush all rules in all tables:

iptables -t nat -F && iptables -F  

2. Real-World Scenario 1: Basic Linux Server Hardening

2.1 Goal and Requirements

Secure a Linux server by allowing only essential services (SSH, HTTP/HTTPS) and blocking all other inbound traffic.

Requirements:

  • Allow SSH (port 22) for remote management.
  • Allow HTTP (80) and HTTPS (443) for web services.
  • Block all other inbound traffic.
  • Allow outbound traffic (e.g., updates, DNS).

2.2 Step-by-Step Configuration

Step 1: Set Default Policies

Start with a “deny-by-default” stance to block all traffic unless explicitly allowed:

iptables -P INPUT DROP       # Drop all inbound traffic  
iptables -P FORWARD DROP     # Drop forwarded traffic (not a router)  
iptables -P OUTPUT ACCEPT    # Allow all outbound traffic (adjust if needed)  

Step 2: Allow Loopback Traffic

The loopback interface (lo) is critical for local services (e.g., databases, inter-process communication). Blocking it can break applications:

iptables -A INPUT -i lo -j ACCEPT  # Allow inbound loopback  
iptables -A OUTPUT -o lo -j ACCEPT # Allow outbound loopback  

Step 3: Allow Established/Related Connections

Allow traffic for existing connections (e.g., a client connecting to your web server):

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  
  • -m state: Use the state module to match connection states.
  • ESTABLISHED: Packets part of an existing connection.
  • RELATED: Packets related to an existing connection (e.g., FTP data transfer).

Step 4: Allow Essential Services

Allow SSH, HTTP, and HTTPS:

# Allow SSH (adjust --src to restrict to a specific IP, e.g., --src 192.168.1.100)  
iptables -A INPUT -p tcp --dport 22 -j ACCEPT  

# Allow HTTP (80) and HTTPS (443)  
iptables -A INPUT -p tcp --dport 80 -j ACCEPT  
iptables -A INPUT -p tcp --dport 443 -j ACCEPT  

Step 5: Block All Other Inbound Traffic

The default INPUT policy is already DROP, so no extra rule is needed.

2.3 Verifying and Saving Rules

Verify the rules:

iptables -L -n --line-numbers  

Sample Output:

Chain INPUT (policy DROP)  
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           interface lo  
2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED  
3    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22  
4    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80  
5    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443  

Save Rules Persistently

Rules are lost on reboot unless saved.

On Debian/Ubuntu:
Install iptables-persistent to auto-load rules:

apt install iptables-persistent  
# Save current rules (will auto-load on reboot)  
iptables-save > /etc/iptables/rules.v4  

On RHEL/CentOS:
Use iptables-save with systemd:

iptables-save > /etc/sysconfig/iptables  
systemctl enable iptables  # Load rules on boot  

3. Real-World Scenario 2: Web Server Protection

3.1 Allowing HTTP/HTTPS and SSH

Build on Scenario 1 by adding protection against common attacks like SSH brute-force and DDoS.

3.2 Rate Limiting to Prevent Brute-Force Attacks

Use the recent module to limit SSH connections from a single IP (e.g., 5 connections in 60 seconds) to block brute-force attempts:

# Allow SSH but limit to 5 connections/60s per IP  
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_brute --rcheck --seconds 60 --hitcount 5 -j DROP  
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_brute --set -j ACCEPT  
  • --name ssh_brute: Track connections in a list named ssh_brute.
  • --rcheck: Check if the IP is in the list and has exceeded --hitcount 5 in --seconds 60.
  • --set: Add the IP to the list if it matches.

3.3 Blocking Malicious IPs

Block known malicious IPs (e.g., from threat feeds like Spamhaus) using the ipset tool (more efficient than multiple iptables rules):

  1. Install ipset:

    apt install ipset  # Debian/Ubuntu  
    yum install ipset  # RHEL/CentOS  
  2. Create a set for malicious IPs:

    ipset create blacklist hash:ip  
  3. Add IPs to the set (e.g., 192.0.2.1):

    ipset add blacklist 192.0.2.1  
  4. Block the set in iptables:

    iptables -A INPUT -m set --match-set blacklist src -j DROP  

3. Real-World Scenario 3: Linux Router with NAT

3.1 Goal

Turn a Linux machine into a home router with:

  • NAT (share a single public IP with multiple devices).
  • Port forwarding (e.g., forward external port 8080 to a local server).

3.2 Prerequisites

  • Two network interfaces:
    • eth0: WAN (connected to ISP, public IP).
    • eth1: LAN (connected to home network, e.g., 192.168.1.1/24).

3.3 Step-by-Step Configuration

Step 1: Enable IP Forwarding

Linux disables IP forwarding by default. Enable it temporarily:

sysctl -w net.ipv4.ip_forward=1  

Make it permanent (persist after reboot):

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf  
sysctl -p  # Reload sysctl settings  

Step 2: Configure NAT (Masquerading)

Use MASQUERADE in the nat table to translate LAN private IPs to the WAN public IP:

# Allow LAN (eth1) to WAN (eth0) forwarding  
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT  

# Allow established/related traffic from WAN to LAN  
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT  

# Enable NAT (masquerade LAN IPs)  
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  

3.4 Port Forwarding

Forward external port 8080 (WAN) to a local server at 192.168.1.100:80:

iptables -t nat -A PREROUTING -i eth0 -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  

4. Real-World Scenario 4: Jump Host Security

4.1 Goal

Secure a jump host (a server used to access internal systems) by restricting SSH access to trusted IPs and logging all attempts.

4.2 Configuration

Step 1: Restrict SSH to Trusted IPs

Allow SSH only from your office IP (203.0.113.0/24):

iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT  

Step 2: Log SSH Attempts

Log failed SSH attempts for auditing:

iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH_FAILED: " --log-level 6  
  • --log-prefix: Add context to logs.
  • --log-level 6: Use INFO-level logging (check /var/log/syslog or /var/log/messages).

5. Best Practices for iptables Management

5.1 Start with Default Deny

Always set INPUT and FORWARD policies to DROP to avoid accidental exposure.

5.2 Comment Rules

Add comments to rules for clarity (use -m comment --comment):

iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -m comment --comment "Allow SSH from office" -j ACCEPT  

5.3 Test Rules Before Persisting

Use iptables-apply (Debian/Ubuntu) to test rules and auto-revert if you’re locked out:

iptables-save > /tmp/rules.test  
iptables-apply /tmp/rules.test  

6. Troubleshooting Common iptables Issues

Symptom: Can’t SSH into the Server

  • Check rules: Ensure ESTABLISHED,RELATED is allowed (required for return traffic).
  • Check line order: Rules are processed top-to-bottom. If a DROP rule precedes your SSH allow rule, it will block access.
  • Check counters: Use iptables -L -v to see if packets are hitting your SSH rule (non-zero counters mean it’s working).

Symptom: NAT Not Working

  • Verify IP forwarding: sysctl net.ipv4.ip_forward should return 1.
  • Check nat table: iptables -t nat -L -n to ensure MASQUERADE is configured on the WAN interface.

7. References


By mastering these configurations, you’ll be well-equipped to secure Linux systems in production. Remember: firewall rules should evolve with your needs—regularly audit and update them to stay protected!