Nftables is the replacement for iptables, ebtables and arptables. It is a subsystem of Linux kernel providing filtering and classification of network packets,datagrams or frames.
Some key things to consider:
1.Installation:
dnf install nftables
2. Verify if nftables is enabled:
systemctl enable nftables
3. Flush all the rules
nft flush ruleset
4. When working remotely, it is recommended to allow incoming SSH or port 22 connections prior the base chains
nft add rule inet filter input tcp dport ssh accept
Base chains should exist which is the container for rules. There are two types
a. base chains – entry point for packets from networking stack
b. regular chain – can be used as a jump target and better organizing the rules.
Syntax for creating base chains:
nft create chain inet <table name> <base chain name> { type filter hook <(input|forward|output)> priority 0 \; }
Config:
nft create chain inet filter input { type filter hook input priority 0 \; }
nft create chain inet filter forward { type filter hook forward priority 0 \; }
nft create chain inet filter output { type filter hook output priority 0 \; }
5. Take note that there’s a chance of conflict if running both nftables and ufw, so it is recommended to remove ufw
dnf remove ufw
ufw disable
6. Loopback interface is allowed to accept traffic. Other interfaces should be configured to deny traffic to the loopback network:
IPv4: 127.0.0.0/8
IPv6: ::1
Apply the rules:
nft add rule inet filter input iif lo accept
nft create rule inet filter input ip saddr 127.0.0.0/8 counter drop
nft add rule inet filter input ip6 saddr ::1 counter drop
7. Outbound connections are allowed for all interfaces. Configure also to allow established connections.
nft add rule inet filter input ip protocol tcp ct state established accept
nft add rule inet filter input ip protocol udp ct state established accept
nft add rule inet filter input ip protocol icmp ct state established accept
nft add rule inet filter output ip protocol tcp ct state new,related,established accept
nft add rule inet filter output ip protocol udp ct state new,related,established accept
nft add rule inet filter output ip protocol icmp ct state new,related,established accept
8. Allow only open ports that are needed
There are few ways to verify open or listening ports, e.g. using “ss” command
Sample Output:
root@freelinux:~# ss -4tuln
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 0 0 *:5355 *:*
udp UNCONN 0 0 127.0.0.53%lo:53 *:*
udp UNCONN 0 0 10.0.2.15%enp0s3:68 *:*
tcp LISTEN 0 80 127.0.0.1:3306 *:*
tcp LISTEN 0 128 *:5355 *:*
tcp LISTEN 0 128 *:22 *:*
Syntax to allow open ports:
nft add rule [<family>] <table> <chain> <matches> <statements>
9. Default deny should be configured
The concept is to allow ports or hosts then last rule is to default deny to drop all the traffic.
nft chain inet filter input { policy drop \; }
nft chain inet filter forward { policy drop \; }
nft chain inet filter output { policy drop \; }
Here’s a sample config of /etc/nftables.conf file:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
#Loopback traffic
iif “lo” accept
ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop
ip6 saddr ::1 counter packets 0 bytes 0 drop
#Established connections are configured
ip protocol tcp ct state established,related,new accept
ip protocol tcp ct state established,related,new accept
ip protocol udp ct state established,related,new accept
ip protocol icmp ct state established,related,new accept
# Allow SSH,HTTP, HTTPS traffic from all
tcp dport { 22, 80, 443 } ct state new accept
# Base chain for hook forward
}
chain forward {
type filter hook forward priority 0; policy drop;
}
#Base chain for hook output
chain output {
type filter hook output priority 0; policy drop;