Skip to content

In ZSH you have to scape } while in bash is not needed.

Install and enable

sudo pacman -S nftables
sudo systemctl start nftables
sudo systemctl enable nftables

You should also disable iptables, ebtables and arptables.

List stuff

nft list ruleset
nft list counters
sudo nft monitor
sudo nft list table filter --numeric --handle
## show HAndles
sudo nft list table inet filter --handle
sudo nft list tables

List sets

nft list set <family> <table> <set_name>

## If you added this
nft add set inet filter known_ip_addresses { type ipv4_addr \;\}
nft add element inet filter known_ip_addresses { 192.168.1.23 , 192.168.1.24 \}

## You show it like this
nft list set inet filter known_ip_addresses

Flush rulesets

sudo nft flush ruleset

Add

Add tables

Tables contain chains and sets; and chains contain rules

sudo nft add table inet filter

Add chains

filter is the name of the table

sudo nft add chain <family> <table> <chain_name> { type <type> hook <hook> priority {>=0} ; } ## You must escape the semicolon (;) ## Priority the larger the number, the less priority
sudo nft add chain inet filter input { type filter hook input priority 0 \; }

Types of families

  • ip - iptables
  • ip6 - ip6tables
  • inet - iptables and ip6tables
  • arp - arptables
  • bridge - ebtables

Types of chains

  • filter: for filtering packets.
  • route: for rerouting packets.
  • nat: for performing Network Address Translation. Only the first packet of a flow hits this chain, making it impossible to use it for filtering.

Types of hooks

  • prerouting: This is before the routing decision, all packets entering the machine hit this hook.
  • input: All packets for the local system hit this hook.
  • forward: Packets not for the local system, those that need to be forwarded hit this hook.
  • output: Packets that originate from the local system hit this hook.
  • postrouting: This hook comes after the routing decision has been made, all packets leaving the machine hit this hook.

Add a rule

sudo nft add rule <family> <table> <chain> <match> <argument> <parameter for argument> <statement>
sudo nft add rule inet filter input counter ## Count traffic to see if it's working
sudo nft add rule inet filter input limit ## ???

You can restore the counters, save the listing to a file and restore it.

Add sets

sudo nft add set <family> <table> <set_name> { type <type> \; }
sudo nft add set inet filter blackhole { type ipv4_addr \; }

Add elements to sets

nft add element <family> <table> <set_name> { <data_type> }
nft add element inet filter blackhole { 192.168.10.10 }

Add rules from sets

sudo nft add rule <family> <table> <chain> <match> <argument> <set with parameters> <statement (action)>
sudo nft add rule inet filter input ip saddr @blackhole drop

Add maps

sudo nft add map <family> <table> <name> { type <type> : <???> \; }
sudo nft add map inet filter mappington { type ipv4_addr : mark \; } ## Used to mark packages

Add elemnts to maps

sudo nft add map <family> <table> <name> { <data_type> : <mark> }
sudo nft add element inet filter mappington { 192.168.10.10 : 0xa , 192.168.10.11 : 0xb }

Add rules to maps

sudo nft add rule <family> <table> <chain> <matches> mark set ip saddr map <name of map>
sudo nft add rule inet filter input meta mark set ip saddr map @mappington
sudo nft add rule inet filter input ct mark set ip saddr map @mappington
conntrack -L [modprobe nft-conntrack-ipv4]

Remove

Remove a rule

You have to show the ruleset with the handle number and remove it.

nft list ruleset --handle --numeric --numeric --numeric
nft list ruleset -a -n -n -n
nft delete rule inet filter INPUT handle 18

Show handles

## Whole ruleset
sudo nft list ruleset --handle --numeric

## Specific chain
sudo nft list table inet filter --handle --numeric

## Show port addresses, IPs, protocols, user IDs, group IDs numbers
sudo nft list ruleset -a -n -n -n

Remove an specific handle when you only know the rule

sudo nft delete rule inet filter INPUT handle $(sudo nft list ruleset -a -n -n -n | grep 'iifname "tap0" tcp dport 445 accept' | grep "handle" | rev | cut -f 1 -d ' ' | rev)

Remove a set

nft delete set <family> <table> <set_name>
nft delete set inet filter known_ip_addresses

Translate

From iptables-save.

iptables-save > save.txt ## Save current rules to file
iptables-restore-translate -f /etc/iptables/iptables.rules > /path/to/nftables.file ## Translate rules from file and write to file
nft -f /path/to/nftables.file ## load from translated file

From iptables command.

iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

On the fly (I think this adds rules to nft from iptables syntax).

iptables-nft -A FORWARD -p icmp -j ACCEPT
ebtables-nft
arptables-nft

Create a file with rules


Load from file

sudo nft -f file

Save the current rules (as root)

# nft list ruleset > /etc/nftables.conf

Some examples are located in

/usr/share/nftables/

Examples

SSH only on home wifi

## Allow SSH
add rule inet filter INPUT tcp dport 22 ct state { new } ip saddr { 192.168.0.0/24 } ip daddr 192.168.0.56 iif wlp1s0 ether saddr 00:11:22:33:44:55 counter accept

This only works if the packages are coming from the gateway and if you have a static IP address.

Allow all

nft add rule inet filter OUTPUT ip protocol tcp accept
nft add rule inet filter OUTPUT ip protocol udp accept
---
nft delete rule inet filter OUTPUT handle $(nft list ruleset -annn | grep 'ip protocol 6 accept' | grep "handle" | rev | cut -f 1 -d ' ' | rev)
nft delete rule inet filter OUTPUT handle $(nft list ruleset -annn | grep 'ip protocol 17 accept' | grep "handle" | rev | cut -f 1 -d ' ' | rev)

Link