Chapter 11. Creating and managing nftables tables, chains, and rules
You can display nftables
rule sets and manage them.
11.1. Basics of nftables tables
A table in nftables
is a namespace that contains a collection of chains, rules, sets, and other objects.
Each table must have an address family assigned. The address family defines the packet types that this table processes. You can set one of the following address families when you create a table:
-
ip
: Matches only IPv4 packets. This is the default if you do not specify an address family. -
ip6
: Matches only IPv6 packets. -
inet
: Matches both IPv4 and IPv6 packets. -
arp
: Matches IPv4 address resolution protocol (ARP) packets. -
bridge
: Matches packets that pass through a bridge device. -
netdev
: Matches packets from ingress.
If you want to add a table, the format to use depends on your firewall script:
In scripts in native syntax, use:
table <table_address_family> <table_name> { }
table <table_address_family> <table_name> { }
Copy to Clipboard Copied! In shell scripts, use:
nft add table <table_address_family> <table_name>
nft add table <table_address_family> <table_name>
Copy to Clipboard Copied!
11.2. Basics of nftables chains
Tables contain chains which in turn are containers for rules. The following two chain types exists:
- Base chain: Base chains act as an entry point for packets from the networking stack.
-
Regular chain: You can use regular chains as a
jump
target to better organize rules.
If you want to add a base chain to a table, the format to use depends on your firewall script:
In scripts in native syntax, use:
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> policy <policy> ; } }
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> policy <policy> ; } }
Copy to Clipboard Copied! In shell scripts, use:
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }
Copy to Clipboard Copied! To avoid that the shell interprets the semicolons as the end of the command, place the
\
escape character in front of the semicolons.
Both examples create base chains. To create a regular chain, do not set any parameters in the curly brackets.
Chain types:
The following are the chain types and an overview with which address families and hooks you can use them:
Type | Address families | Hooks | Description |
---|---|---|---|
| all | all | Standard chain type |
|
|
| Chains of this type perform native address translation based on connection tracking entries. Only the first packets of a connection traverse. |
|
|
| Accepted packets that traverse this chain type cause a new route lookup if relevant parts of the IP header have changed. |
Chain priorities:
The priority parameter specifies the order in which packets traverse chains with the same hook value. You can set this parameter to an integer value or use a standard priority name.
The following matrix is an overview of the standard priority names and their numeric values, and with which address families and hooks you can use them:
Textual value | Numeric value | Address families | Hooks |
---|---|---|---|
|
|
| all |
|
|
| all |
|
|
|
|
|
|
| |
|
|
| all |
|
| all | |
|
|
| all |
|
|
|
|
|
|
| |
|
|
|
|
Chain policies:
The chain policy defines whether nftables
should accept or drop packets if rules in this chain do not specify any action. You can set one of the following policies in a chain:
-
accept
(default) -
drop
11.3. Basics of nftables rules
Rules define actions to perform on packets that pass a chain that contains this rule. If the rule also contains matching expressions, nftables
performs the actions only if all previous expressions apply.
If you want to add a rule to a chain, the format to use depends on your firewall script:
In scripts in native syntax, use:
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> ; policy <policy> ; <rule> } }
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> ; policy <policy> ; <rule> } }
Copy to Clipboard Copied! In shell scripts, use:
nft add rule <table_address_family> <table_name> <chain_name> <rule>
nft add rule <table_address_family> <table_name> <chain_name> <rule>
Copy to Clipboard Copied! This shell command appends the new rule at the end of the chain. If you prefer to add a rule at the beginning of the chain, use the
nft insert
command instead ofnft add
.
11.4. Managing tables, chains, and rules using nft commands
To manage an nftables
firewall on the command line or in shell scripts, use the nft
utility.
The commands in this procedure do not represent a typical workflow and are not optimized. This procedure only demonstrates how to use nft
commands to manage tables, chains, and rules in general.
Procedure
Create a table named
nftables_svc
with theinet
address family so that the table can process both IPv4 and IPv6 packets:nft add table inet nftables_svc
# nft add table inet nftables_svc
Copy to Clipboard Copied! Add a base chain named
INPUT
, that processes incoming network traffic, to theinet nftables_svc
table:nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }
# nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }
Copy to Clipboard Copied! To avoid that the shell interprets the semicolons as the end of the command, escape the semicolons using the
\
character.Add rules to the
INPUT
chain. For example, allow incoming TCP traffic on port 22 and 443, and, as the last rule of theINPUT
chain, reject other incoming traffic with an Internet Control Message Protocol (ICMP) port unreachable message:nft add rule inet nftables_svc INPUT tcp dport 22 accept nft add rule inet nftables_svc INPUT tcp dport 443 accept nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable
# nft add rule inet nftables_svc INPUT tcp dport 22 accept # nft add rule inet nftables_svc INPUT tcp dport 443 accept # nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable
Copy to Clipboard Copied! If you enter the
nft add rule
commands as shown,nft
adds the rules in the same order to the chain as you run the commands.Display the current rule set including handles:
nft -a list table inet nftables_svc
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 443 accept # handle 3 reject # handle 4 } }
Copy to Clipboard Copied! Insert a rule before the existing rule with handle 3. For example, to insert a rule that allows TCP traffic on port 636, enter:
nft insert rule inet nftables_svc INPUT handle 3 tcp dport 636 accept
# nft insert rule inet nftables_svc INPUT handle 3 tcp dport 636 accept
Copy to Clipboard Copied! Append a rule after the existing rule with handle 3. For example, to insert a rule that allows TCP traffic on port 80, enter:
nft add rule inet nftables_svc INPUT handle 3 tcp dport 80 accept
# nft add rule inet nftables_svc INPUT handle 3 tcp dport 80 accept
Copy to Clipboard Copied! Display the rule set again with handles. Verify that the later added rules have been added to the specified positions:
nft -a list table inet nftables_svc
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 636 accept # handle 5 tcp dport 443 accept # handle 3 tcp dport 80 accept # handle 6 reject # handle 4 } }
Copy to Clipboard Copied! Remove the rule with handle 6:
nft delete rule inet nftables_svc INPUT handle 6
# nft delete rule inet nftables_svc INPUT handle 6
Copy to Clipboard Copied! To remove a rule, you must specify the handle.
Display the rule set, and verify that the removed rule is no longer present:
nft -a list table inet nftables_svc
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 636 accept # handle 5 tcp dport 443 accept # handle 3 reject # handle 4 } }
Copy to Clipboard Copied! Remove all remaining rules from the
INPUT
chain:nft flush chain inet nftables_svc INPUT
# nft flush chain inet nftables_svc INPUT
Copy to Clipboard Copied! Display the rule set, and verify that the
INPUT
chain is empty:nft list table inet nftables_svc
# nft list table inet nftables_svc table inet nftables_svc { chain INPUT { type filter hook input priority filter; policy accept } }
Copy to Clipboard Copied! Delete the
INPUT
chain:nft delete chain inet nftables_svc INPUT
# nft delete chain inet nftables_svc INPUT
Copy to Clipboard Copied! You can also use this command to delete chains that still contain rules.
Display the rule set, and verify that the
INPUT
chain has been deleted:nft list table inet nftables_svc
# nft list table inet nftables_svc table inet nftables_svc { }
Copy to Clipboard Copied! Delete the
nftables_svc
table:nft delete table inet nftables_svc
# nft delete table inet nftables_svc
Copy to Clipboard Copied! You can also use this command to delete tables that still contain chains.
NoteTo delete the entire rule set, use the
nft flush ruleset
command instead of manually deleting all rules, chains, and tables in separate commands.