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)