Skip to content

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:#a8e6cf

Tables and Chains Relationship

TablePurposeMain Chains
filterPacket filteringINPUT, OUTPUT, FORWARD
natAddress translationPREROUTING, POSTROUTING, OUTPUT
manglePacket modificationPREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
rawConnection tracking exclusionPREROUTING, 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 destination

Basic 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