funwithlinux guide

Configuring Linux Firewall with Iptables: Basics and Beyond

In today’s interconnected world, securing your Linux system is paramount. At the heart of Linux network security lies `iptables`—a powerful, user-space utility for configuring the Linux kernel’s built-in firewall, **netfilter**. Iptables allows you to define rules that filter, modify, or forward network packets based on criteria like source/destination IP, port, protocol, and more. Whether you’re securing a home server, a cloud instance, or a production environment, understanding iptables is essential for controlling network traffic and mitigating threats. This blog will take you from the basics of iptables—how it works, key concepts like tables and chains—to advanced configurations like stateful rules, logging, and rate limiting. By the end, you’ll be able to set up a robust firewall, troubleshoot issues, and implement best practices to protect your system.

Table of Contents

  1. Understanding Iptables: Core Concepts
    • 1.1 What is Iptables?
    • 1.2 Tables, Chains, and Rules
    • 1.3 Packet Flow in Iptables
  2. Getting Started: Installing and Enabling Iptables
    • 2.1 Installing Iptables
    • 2.2 Starting and Enabling the Service
  3. Basic Iptables Configuration
    • 3.1 Viewing Current Rules
    • 3.2 Flushing (Clearing) Rules
    • 3.3 Setting Default Policies
  4. Managing Rules: Adding, Deleting, and Modifying
    • 4.1 Adding Rules
    • 4.2 Deleting Rules
    • 4.3 Replacing Rules
  5. Beyond the Basics: Advanced Rule Configuration
    • 5.1 Stateful Packet Inspection
    • 5.2 Filtering by IP, Port, and Protocol
    • 5.3 Logging Traffic
    • 5.4 Rate Limiting (DDoS/Brute-Force Protection)
  6. Saving Rules Permanently
    • 6.1 Using iptables-save and iptables-restore
    • 6.2 Distro-Specific Methods (Debian/Ubuntu, RHEL/CentOS)
  7. Practical Examples
    • 7.1 Allow SSH Access
    • 7.2 Block a Malicious IP
    • 7.3 Allow Web Traffic (HTTP/HTTPS)
    • 7.4 Allow ICMP (Ping)
  8. Troubleshooting Iptables
  9. Best Practices
  10. References

1. Understanding Iptables: Core Concepts

1.1 What is Iptables?

Iptables is not a firewall itself but a user-space tool that interacts with the Linux kernel’s netfilter framework—a set of hooks in the kernel that process network packets. Iptables lets you define rules to:

  • Filter packets (allow/block traffic).
  • Modify packets (e.g., change source/destination IPs via NAT).
  • Forward packets between networks.

1.2 Tables, Chains, and Rules

Iptables organizes rules into tables (categories of functionality) and chains (predefined sequences of rules within a table).

Tables

There are 5 built-in tables (we’ll focus on the most common):

  • filter: The default table for packet filtering (allow/block). Contains chains: INPUT (incoming packets), OUTPUT (outgoing packets), FORWARD (packets routed through the system).
  • nat: For Network Address Translation (e.g., port forwarding, masquerading).
  • mangle: For modifying packet headers (e.g., TTL, QoS).
  • raw: Bypasses connection tracking (rarely used).
  • security: For Mandatory Access Control (MAC) rules (e.g., SELinux).

Chains

Chains are predefined paths packets follow. For the filter table:

  • INPUT: Packets destined for the local system.
  • OUTPUT: Packets originating from the local system.
  • FORWARD: Packets routed through the system (e.g., a router).

Rules

Rules are conditions applied to packets. Each rule has:

  • Matching criteria: e.g., source IP (--src), destination port (--dport), protocol (-p tcp).
  • Target: Action if the packet matches (e.g., ACCEPT, DROP, LOG).

1.3 Packet Flow in Iptables

Packets traverse chains in a specific order:

  1. A packet enters the system.
  2. It is processed by the PREROUTING chain (for nat/mangle tables).
  3. If destined for the local system, it moves to the INPUT chain (filter table).
  4. If generated locally, it starts at the OUTPUT chain (filter table).
  5. If routed through the system, it goes to the FORWARD chain (filter table).

Rules in a chain are processed top-to-bottom. The first matching rule determines the packet’s fate (no further rules are checked).

2. Getting Started: Installing and Enabling Iptables

Iptables is preinstalled on most Linux distributions, but if not, install it via your package manager:

2.1 Installing Iptables

  • Debian/Ubuntu:
    sudo apt update && sudo apt install iptables  
  • RHEL/CentOS/Fedora:
    sudo dnf install iptables  

2.2 Starting and Enabling the Service

Iptables rules are not persistent by default (they reset on reboot). To manage the service:

  • Check status:
    sudo systemctl status iptables  
  • Start the service:
    sudo systemctl start iptables  
  • Enable on boot (to load rules after reboot):
    sudo systemctl enable iptables  

3. Basic Iptables Configuration

3.1 Viewing Current Rules

List all rules in the default filter table:

sudo iptables -L  

For verbose output (including packet/byte counts and interfaces):

sudo iptables -L -v  

To view rules with line numbers (useful for deleting rules):

sudo iptables -L --line-numbers  

3.2 Flushing (Clearing) Rules

To reset all rules in the filter table (use with caution!):

sudo iptables -F  # Flush all chains  
sudo iptables -X  # Delete custom chains (if any)  

3.3 Setting Default Policies

Default policies define the action for packets that don’t match any rule. By default, policies are ACCEPT, but for security, set them to DROP (block all unmatched traffic):

sudo iptables -P INPUT DROP    # Block all incoming traffic  
sudo iptables -P OUTPUT ACCEPT # Allow all outgoing traffic  
sudo iptables -P FORWARD DROP  # Block forwarded traffic (if not a router)  

⚠️ Warning: Setting INPUT to DROP without adding allow rules will lock you out of remote servers (e.g., SSH). Always allow critical services first!

4. Managing Rules: Adding, Deleting, and Modifying

4.1 Adding Rules

Use -A (append) to add a rule to the end of a chain, or -I (insert) to add it at a specific position (e.g., -I INPUT 1 for the top).

Example 1: Allow Loopback Traffic

The loopback interface (lo) is critical for local services (e.g., databases). Always allow it:

sudo iptables -A INPUT -i lo -j ACCEPT  

4.2 Deleting Rules

Delete a rule by line number (use iptables -L --line-numbers to find the number):

sudo iptables -D INPUT 3  # Delete the 3rd rule in the INPUT chain  

Or delete by matching criteria (e.g., delete a rule allowing SSH from 192.168.1.100):

sudo iptables -D INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT  

4.3 Replacing Rules

Replace a rule at a specific line number with -R:

sudo iptables -R INPUT 2 -s 10.0.0.0/24 -p tcp --dport 80 -j ACCEPT  

5. Beyond the Basics: Advanced Rule Configuration

5.1 Stateful Packet Inspection

Use the --state flag to track connection states (critical for allowing return traffic):

  • NEW: A new connection (e.g., first packet of an SSH handshake).
  • ESTABLISHED: A connection already in progress.
  • RELATED: A new connection related to an existing one (e.g., FTP data transfer).

Example: Allow incoming traffic for existing connections:

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  

5.2 Filtering by IP, Port, and Protocol

Allow SSH from a Specific IP

sudo iptables -A INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT  

Block All Traffic from a Malicious IP

sudo iptables -A INPUT -s 203.0.113.45 -j DROP  

Allow HTTP/HTTPS (Web Traffic)

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT   # HTTP  
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT  # HTTPS  

5.3 Logging Traffic

Log packets before dropping them for debugging:

sudo iptables -A INPUT -j LOG --log-prefix "IPT: DROPPED: " --log-level 4  
sudo iptables -A INPUT -j DROP  # Drop after logging  

Logs appear in /var/log/kern.log (Debian/Ubuntu) or /var/log/messages (RHEL/CentOS).

5.4 Rate Limiting (DDoS/Brute-Force Protection)

Use the recent module to limit repeated connections (e.g., SSH brute-force attacks):

# Allow 5 SSH attempts per minute from a single IP  
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --set  
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --rcheck --seconds 60 --hitcount 5 -j DROP  

6. Saving Rules Permanently

Iptables rules are volatile (lost on reboot). To save them permanently:

6.1 Using iptables-save and iptables-restore

Save rules to a file:

sudo iptables-save > /etc/iptables/rules.v4  # IPv4  
sudo ip6tables-save > /etc/iptables/rules.v6  # IPv6 (if needed)  

Restore rules from the file:

sudo iptables-restore < /etc/iptables/rules.v4  

6.2 Distro-Specific Methods

  • Debian/Ubuntu: Use iptables-persistent to auto-save/restore rules:
    sudo apt install iptables-persistent  
    sudo netfilter-persistent save  # Save current rules  
  • RHEL/CentOS: Save rules to /etc/sysconfig/iptables:
    sudo iptables-save > /etc/sysconfig/iptables  

7. Practical Examples

7.1 Secure Firewall for a Web Server

Goal: Allow SSH, HTTP, HTTPS; block everything else.

  1. Flush existing rules and set default policies:

    sudo iptables -F  
    sudo iptables -X  
    sudo iptables -P INPUT DROP  
    sudo iptables -P OUTPUT ACCEPT  
    sudo iptables -P FORWARD DROP  
  2. Allow loopback and established connections:

    sudo iptables -A INPUT -i lo -j ACCEPT  
    sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  
  3. Allow SSH, HTTP, HTTPS:

    sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT  
    sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT  
    sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT  
  4. Save rules permanently:

    sudo netfilter-persistent save  # Debian/Ubuntu  
    # OR  
    sudo iptables-save > /etc/sysconfig/iptables  # RHEL/CentOS  

7.2 Allow Ping (ICMP)

By default, ICMP (ping) is blocked. Allow it with:

sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT  

7.3 Block a Port Temporarily

Block outgoing SMTP (port 25) to stop spam:

sudo iptables -A OUTPUT -p tcp --dport 25 -j DROP  

8. Troubleshooting Iptables

  • Check rule hit counts: Use iptables -L -v to see if rules are matching traffic (look for non-zero pkts/bytes).
  • Test connectivity: Use telnet <IP> <port> or nc -zv <IP> <port> to verify if a port is open.
  • Check logs: Look for dropped packets in /var/log/kern.log (use grep "IPT: DROPPED" /var/log/kern.log).
  • Temporarily allow all traffic: For debugging, set INPUT policy to ACCEPT (reset afterward!):
    sudo iptables -P INPUT ACCEPT  

9. Best Practices

  • Start with a default deny policy: Block all traffic unless explicitly allowed.
  • Order rules carefully: Place specific rules (e.g., allow SSH) before general rules (e.g., drop all).
  • Save rules permanently: Always save after making changes to avoid losing them on reboot.
  • Limit SSH access: Restrict SSH to trusted IPs (e.g., --src 192.168.1.0/24).
  • Use logging sparingly: Excessive logging can fill disks; target critical traffic only.

10. References

By mastering iptables, you gain granular control over your Linux system’s network security. Start with the basics, experiment with rules in a safe environment, and gradually implement advanced configurations to protect against evolving threats.