Table of Contents
- Understanding iptables: The Legacy Workhorse
- Enter nftables: The Modern Firewall
- Why Transition from iptables to nftables?
- Key Differences Between iptables and nftables
- Getting Started with nftables
- Migrating from iptables to nftables
- Advanced nftables Concepts
- Common Pitfalls and How to Avoid Them
- Conclusion
- References
1. Understanding iptables: The Legacy Workhorse
Before diving into nftables, it’s critical to understand iptables’ role and limitations.
How iptables Works
iptables is a user-space tool that interacts with the Linux kernel’s netfilter framework to manage packet filtering, network address translation (NAT), and port forwarding. It organizes rules into:
- Tables: Predefined categories of functionality (e.g.,
filterfor packet filtering,natfor NAT,manglefor packet modification). - Chains: Sequences of rules within a table (e.g.,
INPUTfor incoming traffic,OUTPUTfor outgoing traffic,FORWARDfor routed traffic). - Rules: Conditions (e.g., source IP, port) and actions (e.g.,
ACCEPT,DROP,MASQUERADE).
Example iptables Rule
# Allow incoming SSH (port 22) traffic
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Limitations of iptables
- Fragmented Syntax: Separate commands for tables/chains (e.g.,
iptables,ip6tables,iptables-nat). - Scalability Issues: Rule processing slows with large rule sets (linear traversal).
- No Built-in Data Structures: Lacks sets/maps for grouping IPs/ports, requiring repetitive rules.
- Static Rule Management: Updating rules often requires flushing and reloading the entire ruleset, causing downtime.
2. Enter nftables: The Modern Firewall
nftables, introduced in Linux kernel 3.13 (2014), is a complete rewrite of the netfilter user-space tooling. It retains netfilter’s core power but addresses iptables’ flaws with a unified, efficient design.
Design Goals of nftables
- Unified Syntax: A single
nftcommand replacesiptables,ip6tables,arptables, andebtables. - Flexible Structure: No predefined tables/chains—users define custom tables (with family support:
inet,ip,ip6, etc.) and chains. - Advanced Data Structures: Native support for sets, maps, and concatenations to simplify complex rules.
- Performance: Faster rule processing via kernel optimizations (hash tables, reduced overhead).
- Dynamic Updates: Modify rules without flushing the entire ruleset.
3. Why Transition from iptables to nftables?
The shift to nftables is driven by tangible benefits:
| Benefit | Description |
|---|---|
| Unified Tooling | Replace multiple tools (iptables, ip6tables, etc.) with a single nft command. |
| Better Performance | Rule lookups use hash tables (O(1) complexity) vs. iptables’ linear traversal (O(n)). |
| Simpler Rule Management | Sets/maps group IPs/ports (e.g., {192.168.1.0/24, 10.0.0.0/8}) to reduce repetitive rules. |
| Dynamic Updates | Add/remove rules without disrupting existing connections (no iptables -F). |
| Improved Logging | Native log action with configurable prefixes, rates, and severity levels. |
| Future-Proofing | iptables is deprecated in major distributions (e.g., RHEL 9, Ubuntu 22.04 uses nftables by default for iptables backend). |
4. Key Differences Between iptables and nftables
To transition effectively, understand these core distinctions:
Syntax
- iptables: Uses separate commands per table/chain with flags (e.g.,
-Ato append,-pfor protocol).iptables -t filter -A INPUT -s 192.168.1.100 -j ACCEPT - nftables: Uses a declarative syntax with subcommands (e.g.,
add rule,list ruleset).nft add rule inet filter INPUT ip saddr 192.168.1.100 accept
Structure
- iptables: Predefined tables (
filter,nat, etc.) and chains (INPUT,OUTPUT, etc.). - nftables: No predefined tables/chains. Users create tables (with address family:
ip,ip6,inetfor dual-stack) and chains (with hook points likeinput,output).
Data Structures
- iptables: No built-in sets; requires repetitive rules for multiple IPs/ports.
- nftables:
- Sets: Groups of values (e.g.,
{192.168.1.100, 192.168.1.101}) for efficient matching. - Maps: Key-value pairs (e.g., map port 8080 to 80, 8443 to 443).
- Sets: Groups of values (e.g.,
Performance
nftables reduces kernel-user space communication and uses hash tables for rule lookups, making it up to 10x faster than iptables with large rule sets (per kernel benchmarks).
5. Getting Started with nftables
Let’s walk through setting up a basic nftables firewall.
Step 1: Install nftables
Most Linux distributions include nftables by default. Install it if missing:
# Debian/Ubuntu
sudo apt update && sudo apt install nftables -y
# RHEL/CentOS/Fedora
sudo dnf install nftables -y
# Start and enable the service
sudo systemctl enable --now nftables
Step 2: Basic nftables Commands
| Command | Purpose |
|---|---|
nft list ruleset | Show all current rules. |
nft add table <family> <name> | Create a new table (e.g., inet filter for IPv4/IPv6). |
nft add chain <table> <name> { type <type> hook <hook> priority <prio> \; } | Create a chain (e.g., input hook for incoming traffic). |
nft add rule <table> <chain> <match> <action> | Add a rule to a chain. |
nft save ruleset | Save rules to /etc/nftables.conf. |
nft flush ruleset | Delete all rules (use with caution!). |
Step 3: Build a Basic Ruleset
Let’s create a firewall allowing SSH, HTTP, and HTTPS, while blocking all other incoming traffic.
1. Create a Table and Chains
# Create an "inet" table (supports IPv4/IPv6) named "filter"
sudo nft add table inet filter
# Add an INPUT chain (handles incoming traffic)
sudo nft add chain inet filter INPUT { type filter hook input priority 0 \; policy drop \; }
# Add an OUTPUT chain (handles outgoing traffic)
sudo nft add chain inet filter OUTPUT { type filter hook output priority 0 \; policy accept \; }
# Add a FORWARD chain (handles routed traffic)
sudo nft add chain inet filter FORWARD { type filter hook forward priority 0 \; policy drop \; }
policy drop: Default action if no rules match (deny all).
2. Add Rules to Allow Essential Traffic
# Allow loopback traffic (lo interface)
sudo nft add rule inet filter INPUT iif lo accept
# Allow established/related connections (e.g., HTTP responses)
sudo nft add rule inet filter INPUT ct state established,related accept
# Allow SSH (port 22)
sudo nft add rule inet filter INPUT tcp dport 22 accept
# Allow HTTP (port 80) and HTTPS (port 443)
sudo nft add rule inet filter INPUT tcp dport {80, 443} accept
3. Save the Ruleset
sudo nft save ruleset # Saves to /etc/nftables.conf by default
Verify with nft list ruleset:
table inet filter {
chain INPUT {
type filter hook input priority 0; policy drop;
iif "lo" accept;
ct state established,related accept;
tcp dport 22 accept;
tcp dport {80, 443} accept;
}
chain OUTPUT {
type filter hook output priority 0; policy accept;
}
chain FORWARD {
type filter hook forward priority 0; policy drop;
}
}
6. Migrating from iptables to nftables
Migrating involves auditing existing rules, translating them to nftables, and validating functionality.
Step 1: Audit Existing iptables Rules
First, export your iptables rules:
sudo iptables-save > iptables-rules.txt # IPv4
sudo ip6tables-save > ip6tables-rules.txt # IPv6 (if used)
Step 2: Use iptables-translate for Automated Conversion
The iptables-translate tool (included with iptables-nft) converts iptables rules to nftables syntax.
Example Conversion
# Convert an iptables rule to nftables
sudo iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
Output:
nft add rule ip filter INPUT tcp dport 22 accept
For bulk conversion, pipe iptables-save to iptables-translate:
sudo iptables-save | iptables-translate > nftables-rules.nft
Step 3: Manual Conversion Examples
Some rules require manual adjustment. Here are common scenarios:
Basic Allow/Deny
| iptables Rule | nftables Equivalent |
|---|---|
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT | nft add rule ip filter INPUT ip saddr 192.168.1.0/24 accept |
iptables -A INPUT -p udp --dport 53 -j DROP | nft add rule ip filter INPUT udp dport 53 drop |
NAT (Port Forwarding)
iptables:
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.10:80
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
nftables:
# Create a nat table
nft add table ip nat
nft add chain ip nat PREROUTING { type nat hook prerouting priority 0 \; }
nft add chain ip nat POSTROUTING { type nat hook postrouting priority 100 \; }
# Add DNAT rule
nft add rule ip nat PREROUTING tcp dport 8080 dnat to 10.0.0.10:80
# Add MASQUERADE rule
nft add rule ip nat POSTROUTING oif eth0 masquerade
Step 4: Test and Validate
- Load the new ruleset:
sudo nft -f nftables-rules.nft. - Test connectivity: Verify SSH, HTTP, and other critical services work.
- Monitor logs: Check
journalctl -u nftablesfor errors.
7. Advanced nftables Concepts
nftables’ power lies in advanced features like sets, maps, and concatenations.
Sets: Grouping Values
Sets simplify rules by grouping IPs, ports, or protocols.
Example: Allow Traffic from a List of IPs
# Create a set of trusted IPs
nft add set ip filter trusted_ips { type ipv4_addr \; elements = { 192.168.1.100, 10.0.0.5 } \; }
# Allow traffic from trusted IPs
nft add rule ip filter INPUT ip saddr @trusted_ips accept
Maps: Key-Value Pairs
Maps map keys (e.g., ports) to values (e.g., backend IPs) for dynamic port forwarding.
Example: Port Forwarding with a Map
# Create a map: { external_port : internal_ip:internal_port }
nft add map ip nat port_map { type inet_service : ipv4_addr_port \; elements = { 8080 : 10.0.0.10:80, 8443 : 10.0.0.10:443 } \; }
# Use the map in a DNAT rule
nft add rule ip nat PREROUTING tcp dport map @port_map dnat to ip daddr map @port_map
8. Common Pitfalls and How to Avoid Them
- Syntax Errors: nftables is strict with spacing (e.g.,
ip saddrnotip saddr). Usenft -c add rule ...to check syntax. - Missing Tables/Chains: Unlike iptables, nftables requires explicit table/chain creation.
- Overlooking IPv6: Use the
inetfamily to handle IPv4/IPv6 in one table, or separateip/ip6tables. - Forgetting to Save Rules:
nft save rulesetensures rules persist across reboots. - Legacy Dependencies: Some iptables modules (e.g.,
xt_recent) lack nftables equivalents—use native nftables features instead (e.g., sets).
9. Conclusion
nftables represents a significant leap forward in Linux firewall technology, offering simplicity, performance, and scalability that iptables cannot match. While transitioning requires learning new syntax and concepts, tools like iptables-translate ease the process, and the long-term benefits—faster rule processing, dynamic updates, and future-proofing—make it worthwhile.
By following this guide, you’ll be well-equipped to migrate your firewall rules and harness nftables’ full potential.