iptables vs nftables: Comparison and Migration Guide
Comprehensive comparison of iptables and nftables, nftables syntax, migration guide, common rule equivalents, and when to use which firewall tool.
Table of Contents
iptables vs nftables: Comparison and Migration Guide
For many years, iptables was the go-to tool for packet filtering on Linux. However, nftables has been included in the Linux kernel since 2014 and is replacing iptables in modern distributions. This guide compares the two tools, teaches nftables syntax, and walks you through migrating from iptables to nftables.
Comparison Table
| Feature | iptables | nftables |
|---|---|---|
| First release | 1998 | 2014 |
| Syntax | Complex, inconsistent | Consistent, readable |
| IPv4/IPv6 | Separate tools (iptables/ip6tables) | Single tool |
| Performance | Per-rule evaluation | Optimized |
| Atomic updates | No | Yes |
| Rule sets | Separate tables | Unified |
| Default (Ubuntu 20.04+) | No | Yes |
| Default (Debian 10+) | No | Yes |
iptables Basic Concepts
# View current iptables rules
sudo iptables -L -n -v
sudo iptables -L -n -v --line-numbers
# Tables: filter, nat, mangle, raw
sudo iptables -t nat -L -n -v
# Chains: INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING
# Basic rules
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -P INPUT DROP
# Save rules
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6
nftables Basic Concepts
In nftables, the structure is: table → chain → rule
# Install nftables
sudo apt install nftables -y
sudo systemctl enable nftables
sudo systemctl start nftables
# View current rules
sudo nft list ruleset
# List all tables
sudo nft list tables
# View specific table
sudo nft list table inet filter
nftables Configuration File
sudo nano /etc/nftables.conf
#!/usr/sbin/nft -f
# Clear existing rules
flush ruleset
# inet family covers both IPv4 and IPv6
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback interface
iif lo accept
# Allow established connections
ct state established,related accept
# ICMP (ping)
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# SSH
tcp dport 22 accept
# HTTP/HTTPS
tcp dport { 80, 443 } accept
# Log and drop
log prefix "nftables-drop: " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
# Apply configuration
sudo nft -f /etc/nftables.conf
# Check syntax (without applying)
sudo nft -c -f /etc/nftables.conf
Rule Equivalents
Basic Rules
| iptables | nftables |
|---|---|
iptables -A INPUT -p tcp --dport 22 -j ACCEPT | nft add rule inet filter input tcp dport 22 accept |
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT | nft add rule inet filter input ip saddr 192.168.1.0/24 accept |
iptables -A INPUT -j DROP | nft add rule inet filter input drop |
iptables -P INPUT DROP | type filter hook input priority 0; policy drop; |
NAT Rules
# iptables NAT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
# nftables NAT equivalent
table ip nat {
chain prerouting {
type nat hook prerouting priority -100;
# Port forwarding (DNAT)
tcp dport 80 dnat to 192.168.1.10:80
tcp dport 443 dnat to 192.168.1.10:443
}
chain postrouting {
type nat hook postrouting priority 100;
# Masquerade (NAT)
oif eth0 masquerade
}
}
Rate Limiting
# iptables rate limiting
sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min --limit-burst 5 -j ACCEPT
# nftables rate limiting
chain input {
# SSH rate limiting
tcp dport 22 limit rate 3/minute burst 5 packets accept
tcp dport 22 drop
# HTTP rate limiting
tcp dport 80 limit rate 100/second burst 200 packets accept
}
IP Sets
# iptables ipset
sudo apt install ipset -y
sudo ipset create blocked_ips hash:ip
sudo ipset add blocked_ips 1.2.3.4
sudo iptables -A INPUT -m set --match-set blocked_ips src -j DROP
# nftables sets (built-in)
table inet filter {
# Define IP set
set blocked_ips {
type ipv4_addr
elements = { 1.2.3.4, 5.6.7.8, 10.0.0.0/8 }
}
chain input {
type filter hook input priority 0; policy drop;
# Drop blocked IPs
ip saddr @blocked_ips drop
# Other rules...
tcp dport 22 accept
}
}
Migrating from iptables to nftables
Automatic Conversion
# Install conversion tool
sudo apt install iptables-nftables-compat -y
# Convert existing iptables rules to nftables format
iptables-save | iptables-restore-translate -f /etc/nftables.conf
# Also convert ip6tables rules
ip6tables-save | ip6tables-restore-translate >> /etc/nftables.conf
# Review generated file
cat /etc/nftables.conf
Manual Migration Steps
# 1. Backup existing iptables rules
sudo iptables-save > /root/iptables-backup.txt
sudo ip6tables-save > /root/ip6tables-backup.txt
# 2. Create nftables configuration
sudo nano /etc/nftables.conf
# 3. Test configuration
sudo nft -c -f /etc/nftables.conf
# 4. Enable nftables
sudo systemctl enable nftables
sudo nft -f /etc/nftables.conf
# 5. Disable iptables
sudo systemctl disable iptables
sudo systemctl stop iptables
# 6. Verify rules
sudo nft list ruleset
When to Use Which?
Use iptables:
- Legacy systems (CentOS 7, Ubuntu 18.04)
- Existing iptables scripts in place
- Team is familiar with iptables
- Third-party tools require iptables
Use nftables:
- New installations (Ubuntu 20.04+, Debian 10+)
- Want to manage IPv4 and IPv6 together
- Want cleaner syntax
- Need atomic rule updates
Since Ubuntu 20.04 and Debian 10, the iptables command actually runs the iptables-nft wrapper — meaning it uses nftables under the hood. Use iptables-legacy for real iptables.
Conclusion
nftables is replacing iptables in modern Linux systems. It offers more consistent syntax, unified IPv4/IPv6 management, and better performance. Choose nftables for new installations; plan a migration for existing iptables infrastructure.
Related Articles
Malware & Rootkit Scanning: rkhunter and ClamAV Guide
Protect your Linux server against malware and rootkits. rkhunter and ClamAV installation, scan configuration, result interpretation, scheduled scans, and incident response guide.
Fail2Ban Configuration: SSH Brute-Force Protection Guide
Protect your server against SSH brute-force attacks with Fail2Ban. Installation, jail.local configuration, Nginx/Apache jails, IP whitelisting, ban monitoring, and email alerts.
WireGuard VPN Server Setup: Step-by-Step Guide
Set up a WireGuard VPN server: key generation, server and client configuration, IP forwarding, firewall rules, and Windows/Linux/Android client setup guide.