Installing and Configuring nftables on Linux
nftables is a modern Linux packet filtering framework designed to replace iptables. It delivers a unified and efficient approach to managing firewall rules across multiple protocols such as IPv4, IPv6, and ARP. By installing and configuring nftables, you can benefit from improved performance and a simpler, consolidated interface compared to the multiple tables approach used in iptables.
This guide describes how to install and set up nftables on Linux, configure basic firewall rules, control network traffic, and apply common security policies.
Prerequisites
- Access to a Linux-based system as a non-root sudo user.
- Basic knowledge of network protocols and firewall rule management.
nftables vs. iptables
iptables has long been the standard firewall tool on Linux, but it comes with drawbacks such as a complex rule structure, lower efficiency, and the need for multiple tools to manage various protocols (IPv4, IPv6, ARP, etc.). nftables was introduced to overcome these issues, offering better functionality, performance, and ease of use.
The table below outlines key differences in functionality, performance, and usability, highlighting why nftables is the preferred choice.
Feature | iptables | nftables |
---|---|---|
Packet Filtering | Requires multiple tools to handle different protocols (iptables, ip6tables, arptables) | Uses a single, unified approach with named tables and chains |
Rule Syntax | Requires complex chain-based rules with multiple entries | Uses a modern, table-based syntax for simpler rule creation |
Performance | Processes rules sequentially, which slows down large sets | Uses optimized evaluation to reduce processing overhead |
Atomic Rule Changes | Needs flushing and reloading of entire rule sets | Supports atomic updates without disruption |
Logging | Uses older LOG and ULOG frameworks | Includes built-in logging with advanced tracing (meta nftrace, log) |
Connection Tracking | Requires external conntrack modules | Integrates connection tracking directly |
Multi-protocol Support | Uses separate commands for each protocol | Handles all protocols with one command set |
Resource Usage | Duplicates rules, consuming more memory | Uses a unified ruleset for efficient memory usage |
Scripting & Automation | Depends on shell scripts and manual rule handling | Supports JSON-based rules and direct scripting |
Compatibility | Runs on all distributions but uses a legacy design | Works natively on modern systems with iptables compatibility |
Install nftables on Linux
Follow the instructions below according to your Linux distribution.
Ubuntu and Debian
Update the package index:
$ sudo apt update
Install nftables using APT:
$ sudo apt install nftables -y
Fedora, CentOS, and RHEL
Update the DNF package index:
$ sudo dnf update
Install nftables using DNF:
$ sudo dnf install -y nftables
Arch Linux
Install nftables using Pacman:
$ sudo pacman -S nftables
nft Command Syntax
The basic syntax is:
nft [ -nNscaeSupyjtT ] [ -I directory ] [ -f filename | -i | cmd ... ]
- -n: Display rule numbers.
- -N: Show detailed rule output.
- -s: Show statistics.
- -c: Show chain names.
- -a: Display address family and protocol.
- -e: Expand rule details.
- -S: Print the ruleset.
- -u: Enable update mode.
- -p: Show ruleset in parsable format.
- -y: Show detailed object types.
- -j: Output in JSON.
- -t: Output in table format.
- -T: Show tokenized output.
- -I directory: Specify config directory.
- -f filename: Load from file.
- -i: Interactive mode.
- cmd …: Command arguments to manage nftables rules.
Managing the nftables System Service
The nftables service maintains your firewall rules and ensures they persist after reboots. To enable and start the service:
Enable the service at boot:
$ sudo systemctl enable nftables
Start the service:
$ sudo systemctl start nftables
Check the service status:
$ sudo systemctl status nftables
Example output:
● nftables.service - Netfilter Tables
Loaded: loaded (/usr/lib/systemd/system/nftables.service; enabled; preset: disabled)
Active: active (exited) since Mon 2025-03-31 17:52:35 UTC; 5s ago
Docs: man:nft(8)
Process: 1838 ExecStart=/sbin/nft -f /etc/sysconfig/nftables.conf (code=exited, status=0/SUCCESS)
Main PID: 1838 (code=exited, status=0/SUCCESS)
CPU: 11ms
Mar 31 17:52:35 nftables-03 systemd[1]: Starting Netfilter Tables...
Mar 31 17:52:35 nftables-03 systemd[1]: Finished Netfilter Tables.
Tables, Chains, and Policies in nftables
In nftables, rules are grouped into tables, which contain chains defining how traffic is processed. Each chain is linked to a hook (INPUT, OUTPUT, FORWARD) that determines when it runs. Chains also have policies specifying the default action if no rule matches a packet.
nftables supports multiple address families for different network protocols:
- inet: Unified for both IPv4 and IPv6.
- ip: IPv4-only filtering.
- ip6: IPv6-only filtering.
- arp: ARP packet filtering.
- bridge: Ethernet bridge packet filtering.
- netdev: Filtering at the network device level.
Chain Hooks
- input: Controls packets directed to the local machine.
- output: Manages packets leaving the machine.
- forward: Handles packets routed through the machine.
Policy
Policies define the default action when no rule matches:
- policy accept: Allows all unmatched traffic (useful for testing).
- policy drop: Discards unmatched packets (secure, common in production).
- policy reject: Sends a rejection notice (reveals server presence).
Warning: Avoid using accept
as the default policy in production, as it allows all traffic unless blocked by rules.
Manage the Default nftables Configuration
View existing nftables tables:
$ sudo nft list tables
Example output:
table ip filter
table ip6 filter
View the default nftables configuration file:
$ cat /etc/nftables.conf
Example content:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy accept;
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Configure Basic nftables Firewall Rules
Create Initial Table and Chains
Create a table for IPv4 and IPv6 traffic:
$ sudo nft add table inet my_table
Add an input chain with default accept policy:
$ sudo nft add chain inet my_table input { type filter hook input priority 0 \; }
Add a forward chain with default accept policy:
$ sudo nft add chain inet my_table forward { type filter hook forward priority 0\; }
Allow established connections:
$ sudo nft add rule inet my_table input ct state established,related accept
Add, List, and Delete Rules
Block a specific IP address:
$ sudo nft add rule inet my_table input ip saddr 192.0.2.10 drop
List all rules:
$ sudo nft list ruleset
List rules in the input chain:
$ sudo nft list chain inet my_table input
Example output:
table inet my_table {
chain input {
type filter hook input priority filter; policy accept;
ct state established,related accept
ip saddr 192.0.2.10 drop
}
}
Delete a rule by handle number:
$ sudo nft delete rule inet my_table input handle 0
Implement Essential Security Rules
Allow SSH (port 22):
$ sudo nft add rule inet my_table input tcp dport 22 accept
Allow HTTP (port 80):
$ sudo nft add rule inet my_table input tcp dport 80 accept
Allow HTTPS (port 443):
$ sudo nft add rule inet my_table input tcp dport 443 accept
Drop all other incoming traffic:
$ sudo nft add rule inet my_table input ip daddr 0.0.0.0/0 counter drop
Enable NAT and Port Forwarding
Edit /etc/sysctl.conf
to enable IPv4 forwarding:
net.ipv4.ip_forward=1
Apply changes:
$ sudo sysctl -p
Create NAT table and postrouting chain:
$ sudo nft add table nat
$ sudo nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
Add masquerade rule:
$ sudo nft add rule nat postrouting ip saddr 192.0.2.0/24 oif enp1s0 masquerade
Save Rules Persistently Across Reboots
Save current rules to config:
$ sudo nft list ruleset | sudo tee /etc/nftables.conf
Apply saved rules:
$ sudo nft -f /etc/nftables.conf
Restart nftables service:
$ sudo systemctl restart nftables
Advanced Rule Configuration
Limit SSH connections:
$ sudo nft add rule inet my_table input tcp dport 22 limit rate 3/minute accept
Port forwarding:
$ sudo nft add chain ip nat prerouting { type nat hook prerouting priority 0 \; }
$ sudo nft add rule nat prerouting tcp dport 80 dnat to 192.0.2.10
Enable logging for dropped packets:
$ sudo nft 'add rule inet my_table input log prefix "nftables-drop: " drop'
Flush all rules:
$ sudo nft flush ruleset
Warning: Flushing removes all rules and resets your firewall.
Conclusion
You have installed and configured nftables on Linux, created tables, set policies, and managed rules. nftables modernizes packet filtering with unified IPv4/IPv6 handling, atomic updates, and better performance. With built-in connection tracking and logging, it simplifies network security management. For more details and advanced configurations, see the official nftables wiki.