Every Linux server exposed to the internet needs a properly configured firewall. Whether you're using the battle-tested iptables or the modern nftables, understanding packet filtering is non-negotiable for any sysadmin.
This guide covers both tools in depth — from basic rules to advanced NAT configurations — so you can protect your servers regardless of which distribution you run.
iptables Fundamentals
iptables has been the standard Linux firewall since 2001. It uses tables (filter, nat, mangle) and chains (INPUT, OUTPUT, FORWARD) to process packets.
Essential iptables Rules
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow SSH (rate limited)
iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min -j ACCEPT
# Allow HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Drop everything else
iptables -A INPUT -j DROP
# Save rules
iptables-save > /etc/iptables/rules.v4
NAT and Port Forwarding
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# SNAT (masquerade outgoing traffic)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# DNAT (port forward 8080 to internal server)
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80
iptables -A FORWARD -p tcp -d 10.0.0.5 --dport 80 -j ACCEPT
nftables — The Modern Replacement
nftables replaces iptables with a cleaner syntax, better performance, and unified handling of IPv4/IPv6. It's the default on Debian 10+, RHEL 8+, and Ubuntu 20.04+.
Basic nftables Configuration
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 limit rate 3/minute accept
tcp dport { 80, 443 } accept
counter drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Why Migrate to nftables?
- Unified IPv4/IPv6 — One ruleset for both protocols
- Atomic rule replacement — Load entire rulesets at once
- Sets and maps — Group IPs, ports, interfaces efficiently
- Better performance — Optimized packet classification
- Cleaner syntax — More readable and maintainable rules
Production Hardening Checklist
- Default policy: DROP on INPUT and FORWARD
- Rate limit SSH connections (prevent brute force)
- Block invalid packets early in the chain
- Log dropped packets for analysis
- Use connection tracking for stateful inspection
- Implement geo-blocking for regions you don't serve
- Set up fail2ban alongside your firewall
- Test rules with
iptables -Cbefore applying - Always keep a console/IPMI access as backup
- Document every rule with comments
📥 Download the Linux Firewall Cheat Sheet
Get our free PDF with all iptables and nftables commands in one place — perfect for quick reference during server setup.
Browse All Cheat Sheets →Common Scenarios
Block an IP Address
# iptables
iptables -I INPUT -s 192.168.1.100 -j DROP
# nftables
nft add rule inet filter input ip saddr 192.168.1.100 drop
Allow Only Specific Countries
# Using ipset with iptables
ipset create allowed_countries hash:net
ipset add allowed_countries 1.0.0.0/8 # Example range
iptables -A INPUT -m set ! --match-set allowed_countries src -j DROP
Rate Limiting with nftables
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
tcp dport 80 meter http_meter { ip saddr limit rate 25/second } accept
tcp dport 80 drop
}
}
Whether you choose iptables or nftables, the key is to start with a deny-all policy and explicitly allow only the traffic your services need. Combined with proper logging and monitoring, your Linux servers will be well-protected against network-based attacks.