nftables isn’t just a firewall; it’s a fundamental networking packet-processing framework where rules are expressed as a language, not just a collection of black boxes.

Let’s see it in action. Imagine we want to allow SSH traffic from a specific IP address.

# First, create a table named 'inet filter'
sudo nft add table inet filter

# Then, add a chain named 'input' within that table, set to process packets destined for the system (type filter, hook input, priority 0)
sudo nft add chain inet filter input { type filter hook input priority 0 \; }

# Now, add a rule to the 'input' chain: accept TCP packets on port 22 (SSH) from source IP 192.168.1.100
sudo nft add rule inet filter input ip saddr 192.168.1.100 tcp dport 22 accept

This isn’t just iptables -A INPUT ...; it’s building a structured set of rules. nftables operates with tables, chains, and rules. Tables are containers for chains. Chains are ordered lists of rules that packets traverse. Rules contain expressions that match packet characteristics and specify actions. The inet family means it handles both IPv4 and IPv6. filter is the table name. input is the chain name, and type filter hook input priority 0 tells nftables to insert this chain into the kernel’s packet traversal path just before the system decides whether to accept, drop, or reject incoming packets. The rule itself specifies ip saddr 192.168.1.100 to match packets originating from that IP, tcp dport 22 to match TCP packets destined for port 22 (SSH), and accept to allow them.

The core of nftables is its declarative language. You define what you want the network to do, and nftables figures out how to implement it efficiently. This is a significant departure from the procedural, command-by-command nature of iptables. The nft command-line utility is your interface to this language.

Here’s a breakdown of the primary nft subcommands:

  • nft add ...: This is your primary tool for creating new objects. You’ll use nft add table, nft add chain, and nft add rule. When adding a rule, you specify the table, chain, and then the rule’s conditions and action. For example, nft add rule ip filter forward ip daddr 10.0.0.0/8 accept adds a rule to the forward chain in the ip filter table that accepts packets destined for the 10.0.0.0/8 network.

  • nft list ...: Essential for inspection. nft list tables shows all tables. nft list chains lists all chains in all tables. nft list ruleset displays the entire active configuration. You can also be more specific: nft list table inet filter shows all chains and rules within that table. This is how you verify your changes and understand the current state.

  • nft delete ...: Used to remove objects. You can delete rules by their handle (a unique number assigned by nftables) or by specifying the exact rule to match. For instance, nft delete rule inet filter input handle 42 removes the rule with handle 42. If you omit the handle, you must provide the full rule specification, which is less common for deletion: nft delete rule inet filter input ip saddr 192.168.1.100 tcp dport 22 accept. You can also delete chains (nft delete chain inet filter input) and tables (nft delete table inet filter).

  • nft replace ...: This is powerful for modifying existing objects without deleting and re-adding. You can replace an entire chain or a specific rule. Replacing a rule by its handle is common: nft replace rule inet filter input handle 42 ip saddr 192.168.1.101 tcp dport 22 accept. This replaces the rule identified by handle 42 with a new one, changing the source IP to 192.168.1.101. You can also replace a chain with a new one, effectively updating its entire configuration.

  • nft flush ...: Clears out objects. nft flush ruleset removes all tables, chains, and rules. nft flush chain inet filter input empties a specific chain. nft flush ruleset is often used when applying a new configuration from a file.

  • nft create ...: Similar to add, but create will fail if the object already exists, whereas add will often implicitly replace or add if possible. It’s generally safer for scripting when you want to ensure idempotency. nft create table ip nat will only succeed if no ip nat table exists.

  • nft move ...: Changes the position of a rule within a chain or a chain within a table. For example, nft move rule inet filter input handle 42 position prior moves rule 42 to be just before the current rule. This is crucial for ordering, as rules are evaluated sequentially.

  • nft pipe ...: This is for advanced use cases involving packet sampling and telemetry. It allows you to define "pipes" that capture and process packet data for monitoring.

  • nft monitor ...: This subcommand streams nftables events in real-time. Running nft monitor events will show you every add, delete, replace, and flush operation as it happens, which is invaluable for debugging and understanding dynamic rule changes.

  • nft get ...: Retrieves specific attributes of nftables objects. For example, nft get table inet filter handle might show you the internal handle for that table.

  • nft set ...: Manages nftables sets. Sets are efficient ways to group multiple IP addresses, ports, or other values for matching. You can create sets (nft add set ...), add elements to them (nft add element ...), list them (nft list sets), and delete them (nft delete set ... or nft delete element ...). For example, nft add set inet filter blocked_ips { type ipv4_addr \} creates an empty set for IPv4 addresses. Then, nft add element inet filter blocked_ips { 192.168.1.50, 192.168.1.51 } adds two IPs to it. A rule could then be nft add rule inet filter input ip saddr @blocked_ips drop.

The nft command syntax is structured and consistent. You always specify the address family (ip, ip6, inet, arp, bridge, netdev), then the table name, then the chain name (if applicable), and finally the rule or object details.

The most surprising thing about nftables sets is that they are not just for matching; they can also perform actions. While typically used with accept, drop, or reject, you can also use sets to define destination addresses for forwarding rules or to group ports for connection tracking.

If you try to add a rule that references a set that doesn’t exist, nftables will typically give you an error about an "unknown object," which can be confusing if you’re expecting a rule-specific error.

The next concept you’ll likely encounter is the nftables expression syntax and its various statement types beyond simple accept/drop, such as logging, masquerading, and connection tracking.

Want structured learning?

Take the full Nftables course →