iptables is the traditional Linux firewall tool that filters network packets based on rules. While UFW provides a simpler interface, understanding iptables directly gives you maximum control over your server firewall.
iptables Concepts
# Three default chains:
# INPUT — Packets destined for this server
# OUTPUT — Packets originating from this server
# FORWARD — Packets passing through (routing)
# Actions (targets):
# ACCEPT — Allow the packet
# DROP — Silently discard the packet
# REJECT — Discard and send error to sender
# LOG — Log the packet and continue processingViewing Current Rules
# List all rules with line numbers
sudo iptables -L -n -v --line-numbers
# List rules in iptables-save format (easier to read)
sudo iptables -SBasic Server Firewall
# Set default policies
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# Allow established connections
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
sudo iptables -A INPUT -i lo -j ACCEPT
# Allow SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow HTTP and HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ping
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPTAdvanced Rules
# Allow SSH only from specific IP
sudo iptables -A INPUT -p tcp -s 203.0.113.50 --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
# Rate limit connections
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --set --name SSH
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# Block a specific IP
sudo iptables -I INPUT -s 192.168.1.100 -j DROP
# Allow a subnet
sudo iptables -A INPUT -s 10.0.0.0/24 -j ACCEPTManaging Rules
# Delete a rule by line number
sudo iptables -D INPUT 3
# Delete a rule by specification
sudo iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
# Insert a rule at a specific position
sudo iptables -I INPUT 1 -s 203.0.113.50 -j ACCEPT
# Flush all rules (careful!)
sudo iptables -FSaving Rules
# Install iptables-persistent
sudo apt install iptables-persistent
# Save current rules
sudo netfilter-persistent save
# Rules saved to:
# /etc/iptables/rules.v4
# /etc/iptables/rules.v6
# Reload saved rules
sudo netfilter-persistent reloadIPv6 Rules
# Use ip6tables for IPv6 (same syntax)
sudo ip6tables -P INPUT DROP
sudo ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A INPUT -i lo -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo ip6tables -A INPUT -p ipv6-icmp -j ACCEPT