Nftables Cheatsheet
Table of Contents
- Getting Started
- Table Commands
- Import / Export
- Nftables Families
- Common Useful Commands
- Convert Iptables to Nftables
- Nftables and Docker
Getting Started
Installation
On Debian/Ubuntu based systems, you should be able to install nftables by running:
sudo apt update && sudo apt install nftables
Enable And Start Nftables
sudo systemctl enable nftables
sudo systemctl start nftables
Terms
Chain "Priority"
When creating chains, you will need to assign a priority. The priority needs to be 0 or above, and chains with a lower priority get processed first. Thus, you may wish to think of it as "order" rather than "priority".
Import / Export
Import
Import NFT File Ruleset
sudo nft --file ruleset.nft
Also, if you want to read from stdin, you can do so like so:
cat ruleset.nft | sudo nft --file -
Import JSON File Ruleset
sudo nft --json --file rules.json
Also, if you want to read from stdin, you can do so like so:
cat ruleset.json | sudo nft --json --file -
Export
Export NFT
To export the rules, one can do the following:
sudo nft list ruleset > ruleset.nft
Export JSON
If you want to export the rules in JSON format, add the --json
flag like so:
sudo nft --json list ruleset > ruleset.json
This will output the rules in a compressed JSON format. If you want to be able to easily be able to read/edit the rules, you can use the jq tool like so:
sudo nft --json list ruleset | jq . > ruleset.json
sudo apt install jq -y
Make Rules Persistent
The rules defined within the configuration file at /etc/nftables.conf are what are used when a server restarts. Thus, we can use the export command and a few manual additions to overwrite this configuration file to make our dynamically added rules permanent like so:
# First set the shebang
echo '#!/usr/sbin/nft -f' > ruleset.nft
# Tell nftables to reset
echo "flush ruleset" >> ruleset.nft
# Add the existing rules after a spacer/newline
echo "" >> ruleset.nft
nft list ruleset >> ruleset.nft
# Overwrite the configuration file with our generated file.
mv ruleset.nft /etc/nftables.conf
Default Nftables Config
The default /etc/nftables.conf
file is:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter;
}
chain forward {
type filter hook forward priority filter;
}
chain output {
type filter hook output priority filter;
}
}
In JSON format, this would be represented as:
{
"nftables": [
{
"metainfo": {
"version": "1.0.6",
"release_name": "Lester Gooch #5",
"json_schema_version": 1
}
},
{
"table": {
"family": "inet",
"name": "filter",
"handle": 1
}
},
{
"chain": {
"family": "inet",
"table": "filter",
"name": "input",
"handle": 1,
"type": "filter",
"hook": "input",
"prio": 0,
"policy": "accept"
}
},
{
"chain": {
"family": "inet",
"table": "filter",
"name": "forward",
"handle": 2,
"type": "filter",
"hook": "forward",
"prio": 0,
"policy": "accept"
}
},
{
"chain": {
"family": "inet",
"table": "filter",
"name": "output",
"handle": 3,
"type": "filter",
"hook": "output",
"prio": 0,
"policy": "accept"
}
}
]
}
Schema
Information about the JSON schema can be found online.
Table Commands
List Tables
You can use the following command to list your tables:
sudo nft list tables
Add Table
ADDRESS_FAMILY="inet"
TABLE_NAME="my_table"
sudo nft add table $ADDRESS_FAMILY $TABLE_NAME
ADDRESS_FAMILY
Delete Table
ADDRESS_FAMILY="inet"
TABLE_NAME="my_table"
sudo nft delete table $ADDRESS_FAMILY $TABLE_NAME
ADDRESS_FAMILY
Chain Commands
Chains filter packets and live under tables. You attach each rule to a chain so that packets are caught in the chains filter and are subsequently passed to the chain's rules.
Create Base Chain
Base chains act as entry points for packets coming from the network stack.
ADDRESS_FAMILY="inet"
TABLE_NAME="my_table"
CHAIN_NAME="my_chain"
TYPE="filter"
HOOK="input"
PRIORITY=0
sudo nft add chain $ADDRESS_FAMILY $TABLE_NAME $CHAIN_NAME '{type $TYPE hook $HOOK priority $PRIORITY; }'
Create Regular Chain
Regular chains do not act as filters, but can act as jump targets. They can help with controlling the flow and organization of your nftables.
ADDRESS_FAMILY="inet"
TABLE_NAME="my_table"
CHAIN_NAME="my_chain"
sudo nft add chain $ADDRESS_FAMILY $TABLE_NAME $CHAIN_NAME
Nftables Families
Netfilter enables filtering at multiple networking levels. With iptables there is a separate tool for each level: iptables, ip6tables, arptables, ebtables. With nftables the multiple networking levels are abstracted into families, all of which are served by the single tool nft. The following are descriptions of current nftables families, but additional families may be added in the future.
ip
- Tables of this family see IPv4 traffic/packets. The iptables tool is the legacy x_tables equivalent.
ip6
- Tables of this family see IPv6 traffic/packets. The ip6tables tool is the legacy x_tables equivalent.
inet
- Tables of this family see both IPv4 and IPv6 traffic/packets, simplifying dual stack support.
arp
- Tables of this family see ARP-level (i.e, L2) traffic, before any L3 handling is done by the kernel. The arptables tool is the legacy x_tables equivalent.
bridge
- Tables of this family see traffic/packets traversing bridges (i.e. switching). No assumptions are made about L3 protocols.
netdev
- The netdev family is different from the others in that it is used to create base chains attached to a single network interface. Such base chains see all network traffic on the specified interface, with no assumptions about L2 or L3 protocols. Therefore you can filter ARP traffic from here. There is no legacy x_tables equivalent to the netdev family.
Common Useful Commands
Open Port
If you set your server policy to default drop/reject on the input table, then you will need to open up ports that you wish to allow. E.g. the command below will open up port 22 so that you can connect to the server:
sudo nft add rule 'inet filter input tcp dport 22 accept'
If you wish to take it a step further, and specify that the destination IP should be our server, then you could do:
sudo nft add rule 'inet filter input ip daddr $MY_IP tcp dport 22 accept'
If you wish to only allow connecting on port 22 from a certain IP address, such as perhaps your VPN's IP address, then you would do this like so:
ALLOWED_IP="192.168.2.2"
sudo nft add rule inet filter input ip saddr $ALLOWED_IP tcp dport 22 accept
Also, you can use CIDR notation to open up port 22 from a certain IP range. E.g. this would open up port 22 to only IP addresses on the 192.168.1.1-192.168.1.255 range.
sudo nft add rule inet filter input ip saddr 192.168.1.1/24 tcp dport 22 accept
If you wish to specify the interface that the packet must have come in on, then you can add iifname "$INTERFACE_NAME"
like so:
sudo nft add rule 'inet filter input iifname lan0 tcp dport 22 accept'
Combining them all together would be something like so:
sudo nft add rule 'inet filter input iifname lan0 ip saddr 192.168.1.1/24 ip daddr 192.168.1.23 tcp dport 22 accept'
Convert Iptables to Nftables
Install Package
You can use the following command to install a porting tool
sudo apt install iptables-nftables-compat
Create Iptables File Of Existing Iptables Rules
Use the following command to create a dump/backup of your existing iptables rules
sudo iptables-save > iptables-rules.txt
Convert Iptables File To Nftables Ruleset
Use the porting tool we installed earlier to port the iptables rules over to nftables rules:
sudo iptables-restore-translate -f iptables-rules.txt > ruleset.nft
Then you may wish to import the ruleset, before then possibly exporting the JSON form.
Nftables and Docker
Docker manipulates iptables for the networking to "magically" work. It is currently configured to only work with iptables and not nftables. However you may be able to work around this. Please refer to the following resources:
- Unix & Linux - nftables whitelisting docker
- GitHub Gist - Not happy with Docker modifying your precious firewall rules?
- GitHub alexandre-khoury/blog - How to manage Docker's firewall manually with nftables
As others have pointed out, it is probably easiest to leave nftables out of the server running docker, and have an external firewall service that you use to manage the traffic going into and out of your server.
References
- Linode - Get Started with nftables
- Nftables wiki
- Nftables man page
- Linux Audit - Exporting nftables rules and configuration
- Redhat Customer Portal - Chapter 47. Getting started with nftables
- Redhat Customer Portal - Chapter 6.3. Configuring NAT using nftables
First published: 20th April 2022