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:

Install nftables using APT:

$ sudo apt install nftables -y

Fedora, CentOS, and RHEL

Update the DNF package index:

Install nftables using DNF:

$ sudo dnf install -y nftables

Arch Linux

Install nftables using Pacman:

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:

Example output:

table ip filter
table ip6 filter

View the default nftables configuration file:

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:

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:

Apply changes:

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:

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.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: