nftables Firewall
nftables is the modern replacement for iptables with cleaner syntax and better performance.
Installation
# Debian/Ubuntu
sudo apt install nftables
# RHEL/CentOS
sudo dnf install nftables
# Enable service
sudo systemctl enable nftables
sudo systemctl start nftablesKey Differences from iptables
| Feature | iptables | nftables |
|---|---|---|
| Tables | Predefined | User-defined |
| Syntax | Multiple tools | Single nft command |
| Atomic | No | Yes |
| Performance | Good | Better |
| IPv4/IPv6 | Separate | Unified |
Basic Commands
# List all rules
sudo nft list ruleset
# List specific table
sudo nft list table inet filter
# Flush all rules
sudo nft flush ruleset
# Delete table
sudo nft delete table inet filterConfiguration Structure
table family name {
chain name {
type filter hook input priority 0;
# rules here
}
}Families
- inet - IPv4 and IPv6
- ip - IPv4 only
- ip6 - IPv6 only
- arp - ARP
- bridge - Bridging
Complete Example
/etc/nftables.conf
#!/usr/sbin/nft -f
# Flush existing rules
flush ruleset
# Define inet filter table
table inet filter {
# Input chain
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback
iif lo accept
# Allow established connections
ct state established,related accept
# Allow ICMP
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# Allow SSH
tcp dport 22 accept
# Allow HTTP/HTTPS
tcp dport { 80, 443 } accept
# Log dropped packets
log prefix "nftables-drop: " counter drop
}
# Forward chain
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
}
# Output chain
chain output {
type filter hook output priority 0; policy accept;
}
}
# NAT table
table ip nat {
chain prerouting {
type nat hook prerouting priority -100;
}
chain postrouting {
type nat hook postrouting priority 100;
# Masquerade for outbound
oifname "eth0" masquerade
}
}Rule Syntax
# Add rule to chain
sudo nft add rule inet filter input tcp dport 3306 accept
# Insert at position
sudo nft insert rule inet filter input position 2 tcp dport 8080 accept
# Delete rule by handle
sudo nft -a list chain inet filter input
sudo nft delete rule inet filter input handle 5
# Add with comment
sudo nft add rule inet filter input tcp dport 22 accept comment "SSH access"Sets and Maps
IP Sets
table inet filter {
set allowed_ips {
type ipv4_addr
elements = { 192.168.1.0/24, 10.0.0.1 }
}
chain input {
ip saddr @allowed_ips accept
}
}Port Sets
set web_ports {
type inet_service
elements = { 80, 443, 8080-8090 }
}Dictionaries (Maps)
map port_redirect {
type inet_service : inet_service
elements = { 80 : 8080, 443 : 8443 }
}Rate Limiting
chain input {
# Limit SSH to 3 per minute
tcp dport 22 limit rate 3/minute accept
# Limit ICMP
icmp type echo-request limit rate 10/second accept
}Apply and Save
# Apply configuration
sudo nft -f /etc/nftables.conf
# Validate syntax
sudo nft -c -f /etc/nftables.conf
# Save current rules
sudo nft list ruleset > /etc/nftables.conf
# Reload service
sudo systemctl reload nftablesMigrate from iptables
# Export iptables rules
sudo iptables-save > iptables.rules
# Convert to nftables
sudo iptables-restore-translate -f iptables.rules > nftables.confBest Practices
- Use inet family - Handle both IPv4 and IPv6
- Use sets - For multiple IPs/ports
- Validate first - Use -c flag
- Comment rules - For documentation
- Test in stages - Don't lock yourself out
- nftables
- firewall
- linux
- netfilter
- packet filtering
- iptables replacement