Linux firewalls use the netfilter kernel framework. iptables is the classic userspace tool. nftables is the modern replacement. ufw (Ubuntu) and firewalld (RHEL) provide friendlier interfaces.
| Item | Syntax / Value | Description |
|---|---|---|
| iptables -L | iptables -L -n -v | List all rules with counters |
| iptables -A INPUT | iptables -A INPUT -p tcp --dport 22 -j ACCEPT | Append rule to INPUT chain |
| iptables -I | iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT | Insert rule at position 1 |
| iptables -D | iptables -D INPUT -p tcp --dport 80 -j ACCEPT | Delete specific rule |
| iptables -F | iptables -F | Flush (delete) all rules in all chains |
| iptables -P | iptables -P INPUT DROP | Set default policy for chain |
| ACCEPT | iptables -A INPUT -j ACCEPT | Allow packet |
| DROP | iptables -A INPUT -j DROP | Silently discard packet |
| REJECT | iptables -A INPUT -j REJECT | Discard and send error to sender |
| -p tcp/udp | iptables -A INPUT -p tcp | Protocol filter |
| --dport | iptables -A INPUT -p tcp --dport 443 | Destination port |
| --sport | iptables -A INPUT -p tcp --sport 1024:65535 | Source port range |
| -s source | -s 192.168.1.0/24 | Source IP/range filter |
| -d dest | -d 10.0.0.5 | Destination IP filter |
| -i interface | -i eth0 | Input interface filter |
| -o interface | -o eth0 | Output interface filter |
| -m state | --state ESTABLISHED,RELATED | Connection state matching |
| iptables-save | iptables-save > /etc/iptables/rules.v4 | Save rules to file |
| iptables-restore | iptables-restore < /etc/iptables/rules.v4 | Restore rules from file |
| ufw enable | sudo ufw enable | Enable Ubuntu firewall |
| ufw allow | sudo ufw allow 22/tcp | Allow port |
| ufw deny | sudo ufw deny 3306/tcp | Deny port |
| ufw status | sudo ufw status verbose | Show all rules |
| ufw delete | sudo ufw delete allow 80/tcp | Delete rule |
| ufw limit | sudo ufw limit 22/tcp | Rate limit — blocks brute force |
| firewalld | sudo firewall-cmd --permanent --add-service=https | RHEL/CentOS firewall |
| nftables | nft list ruleset | Modern iptables replacement |
| nft add rule | nft add rule inet filter input tcp dport 22 accept | nftables rule syntax |
# ── iptables — complete server setup ─────────────────────────
#!/bin/bash
# Basic web server firewall rules
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
# Default policies — deny everything
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT # allow all outbound
# Allow loopback (localhost) traffic
iptables -A INPUT -i lo -j ACCEPT
# Allow established and related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow SSH (port 22) — from specific IP only
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.50 -j ACCEPT # office IP
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 3/min --limit-burst 10 -j ACCEPT # rate-limited for others
# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ICMP ping
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 10 -j ACCEPT
# Log and drop everything else
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 7
iptables -A INPUT -j DROP
# Save rules (Ubuntu)
iptables-save > /etc/iptables/rules.v4
# Make persistent: apt install iptables-persistent
# ── ufw — Ubuntu Uncomplicated Firewall ──────────────────────
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw limit 22/tcp # rate limit SSH brute force
sudo ufw allow from 203.0.113.0/24 to any port 5432 # PostgreSQL from office
sudo ufw deny 3306/tcp # block MySQL from internet
sudo ufw --force enable
sudo ufw status verbose
sudo ufw status numbered # show with numbers for deletion
sudo ufw delete 4 # delete rule number 4
# ── nftables — modern replacement ────────────────────────────
# /etc/nftables.conf
cat > /tmp/nftables.conf << 'EOF'
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept comment "loopback"
ct state established,related accept comment "established"
ct state invalid drop comment "invalid packets"
ip protocol icmp icmp type echo-request limit rate 1/second accept
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 1/second accept
tcp dport 22 ct state new limit rate 3/minute accept comment "SSH"
tcp dport {80, 443} accept comment "HTTP/S"
limit rate 5/minute log prefix "nft-drop: " drop
}
chain forward { type filter hook forward priority 0; policy drop; }
chain output { type filter hook output priority 0; policy accept; }
}
EOF
sudo nft -f /tmp/nftables.conf
sudo nft list ruleset
sudo systemctl enable nftables # persist across reboots