Nftables isn't as straightforward to use as iptables...
We have a few operations to perform beforehand:
Create a table, which will contain:
our 'input' and 'output' chains (the inbound and outbound directions for our flows).
Create our usual firewall rules
Ntables operates on the principle of tables.
The following is an introduction to nftables.. Further exploration will be necessary
It will contain our 'chains', which in turn will contain our 'rules'.
I name it 'default' because I don't intend to create multiple for this tutorial... But of course, you can create multiple tables !
nft add table ip default
(replace ip with ip6 for an IPv6 table)
nft list tables
nft delete table ip default
nft add chain ip default INBOUND_TRAFFIC { type filter hook input priority 0; }
nft add chain ip default OUTBOUND_TRAFFIC { type filter hook output priority 0; }
nft list table ip default
nft delete chain ip default OUTBOUND_TRAFFIC
We open what we need, then we close.
The last rule is used to close
nft add rule default INBOUND_TRAFFIC tcp dport 443 accept
nft add rule default OUTBOUND_TRAFFIC icmp type echo-request accept
nft add rule default INBOUND_TRAFFIC icmp type echo-reply accept
nft add rule default OUTBOUND_TRAFFIC tcp dport 443 accept
nft add rule default INBOUND_TRAFFIC drop
nft add rule default OUTBOUND_TRAFFIC drop
nft -a list table ip default
Each rule is identifiable by its position and cas thus be replaced or modified more easily than before.
nft delete rule default OUTBOUND_TRAFFIC position 1
nft insert rule default OUTBOUND_TRAFFIC position 1 ip daddr 132.18.24.16 drop
nft add rule default INBOUND_TRAFFIC ip saddr 132.18.24.16 drop
nft add rule default OUTBOUND_TRAFFIC ip saddr 132.18.24.16 drop
(To ban an entire subnet, replace the IP with CIDR notation: 132.18.24.16/24)
nft flush chain default OUTBOUND_TRAFFIC
A file with a default table already exists; we can make a copy and write our own file, as shown below :
In a way similar to IPF, we indicate the command to use at the beginning of the script.
Please note, what follows is very basic (SSH, http, https, and ping):
#!/sbin/nft -f
# Flush last ruleset :
flush ruleset
# Creation of the default table
add table default
# Creation of inbound and outbound flows
add chain ip default INBOUND_TRAFFIC { type filter hook input priority 0; }
add chain ip default OUTBOUND_TRAFFIC { type filter hook output priority 0; }
# List of rules
add rule default INBOUND_TRAFFIC tcp dport 22 accept
add rule default OUTBOUND_TRAFFIC tcp sport 22 accept
add rule default INBOUND_TRAFFIC tcp sport 80 accept
add rule default OUTBOUND_TRAFFIC tcp dport 80 accept
add rule default INBOUND_TRAFFIC tcp sport 443 accept
add rule default OUTBOUND_TRAFFIC tcp dport 443 accept
add rule default INBOUND_TRAFFIC udp sport 53 accept
add rule default OUTBOUND_TRAFFIC udp dport 53 accept
add rule default INBOUND_TRAFFIC icmp type echo-request accept
add rule default OUTBOUND_TRAFFIC icmp type echo-reply accept
# Close the firewall :
add rule default INBOUND_TRAFFIC drop
add rule default OUTBOUND_TRAFFIC drop
#!/sbin/nft -f
# Flush last ruleset :
flush ruleset
# Creation of the default table
add table default
# Creation of inbound and outbound flows
add chain ip default INBOUND_TRAFFIC { type filter hook input priority 0; }
add chain ip default OUTBOUND_TRAFFIC { type filter hook output priority 0; }
# Create a set
add set ip default ports_tcp_aut { type inet_service; flags constant; elements = { 80, 443 } }
# Then call it in your rule :
add rule ip default INBOUND_TRAFFIC tcp sport @ports_tcp_aut accept
add rule ip default OUTBOUND_TRAFFIC tcp dport @ports_tcp_aut accept
I encourage you to refer to the following article for further details (especially regarding the flags) :
https://wiki.gentoo.org/wiki/Nftables/Examples#Typical_workstation_.28separate_IPv4_and_IPv6.29