Skip to content

📋 Rule Management

Viewing Rules

bash
# View all rules in the filter table (default table)
sudo iptables -L -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target   prot opt in   out   source       destination
    0     0 ACCEPT   tcp  --  *    *     0.0.0.0/0    0.0.0.0/0   tcp dpt:22
    0     0 ACCEPT   tcp  --  *    *     0.0.0.0/0    0.0.0.0/0   tcp dpt:80
    0     0 ACCEPT   tcp  --  *    *     0.0.0.0/0    0.0.0.0/0   tcp dpt:443
    0     0 DROP     all  --  *    *     0.0.0.0/0    0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)

# View nat table rules
sudo iptables -t nat -L -n -v

# View rules with line numbers (convenient for deletion)
sudo iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num  target   prot opt in   out   source       destination
1    ACCEPT   tcp  --  *    *     0.0.0.0/0    0.0.0.0/0   tcp dpt:22
2    ACCEPT   tcp  --  *    *     0.0.0.0/0    0.0.0.0/0   tcp dpt:80
3    DROP     all  --  *    *     0.0.0.0/0    0.0.0.0/0

Adding and Inserting Rules

bash
# Append a rule (add to the end of the chain)
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# Insert a rule (add at position 1)
sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

# Common parameter reference:
# -A  Append
# -I  Insert
# -D  Delete
# -p  Protocol: tcp, udp, icmp, all
# --dport  Destination port
# --sport  Source port
# -s  Source IP
# -d  Destination IP
# -j  Action (jump): ACCEPT, DROP, REJECT, LOG
# -i  Input interface: e.g. eth0
# -o  Output interface: e.g. eth0

Matching Rules by Conditions

bash
# Allow SSH (port 22)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP and HTTPS
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# Allow access from a specific IP
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT

# Allow an entire subnet
sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

# Block access from a specific IP
sudo iptables -A INPUT -s 10.0.0.50 -j DROP

# Allow established connections (very important! Otherwise reply packets will be blocked)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow loopback interface (internal local communication)
sudo iptables -A INPUT -i lo -j ACCEPT

# Allow ICMP (ping)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Log dropped packets (for debugging)
sudo iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4

# Drop all other inbound traffic (default policy)
sudo iptables -P INPUT DROP

⚠️ Warning: ⚠️ Order matters! Add allow rules first, then set the DROP policy last. Otherwise you'll lock yourself out. If you're working on a remote server, make sure SSH port is allowed first!

Deleting and Modifying Rules

bash
# Delete by rule content
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT

# Delete by line number (check line numbers first)
sudo iptables -L INPUT -n --line-numbers
sudo iptables -D INPUT 3    # Delete rule #3

# Flush all rules in a specific chain
sudo iptables -F INPUT

# Flush all rules (⚠️ Use with caution!)
sudo iptables -F

# Set default policy
sudo iptables -P INPUT ACCEPT    # Allow inbound (open)
sudo iptables -P INPUT DROP      # Deny inbound (strict)

Saving and Restoring Rules

iptables rules are lost after a reboot by default! You must save them manually.

bash
# Ubuntu/Debian: Save rules
sudo apt install iptables-persistent
sudo netfilter-persistent save
Saving rules to /etc/iptables/rules.v4
Saving rules to /etc/iptables/rules.v6

# Restore rules
sudo netfilter-persistent reload

# CentOS/RHEL: Save rules
sudo service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables

# Manually export rules to a file
sudo iptables-save > /home/user/iptables-backup.rules

# Restore from file
sudo iptables-restore < /home/user/iptables-backup.rules