zcat /proc/config.gz | grep NF_TABLES
Ubuntu
apt install nftables systemctl status nftables mv -i /etc/nftables.conf /etc/nftables.conf.dist
Slackware
slackpkg install nftables iptables libnftnl libpcap libnl3 dbus-1 mv /etc/nftables/ /etc/nftables.dist/
Make sure you have no interfering rules there (could be caused by Docker for example)
iptables -nvL iptables -nvL -t nat iptables -nvL -t mangle nft list ruleset
just for the record, the default ruleset looks like this
flush ruleset table inet filter { chain input { type filter hook input priority 0; } chain forward { type filter hook forward priority 0; } chain output { type filter hook output priority 0; } }
we’re going for a very specific setup – we want TCP REJECT and ICMP HOST UNREACHABLE, not just DROP.
the default policy can only be accept
or drop
. But reject
can still be defined as last and ipso-facto default rule nevertheless.
vi /etc/nftables.conf flush ruleset table inet filter { chain input { type filter hook input priority filter; policy drop; iifname lo accept iifname != lo ip daddr 127.0.0.0/8 reject iifname != lo ip6 daddr ::1 reject ip protocol icmp accept ip6 nexthdr ipv6-icmp accept #tcp dport 2222 accept ct state established,related accept reject } chain forward { type filter hook forward priority 0; policy drop; reject } chain output { type filter hook output priority 0; policy accept; } } # established,related,invalid
an alternative would be policy ACCEPT and REJECT only the front-facing interface (here xenbr0
)
flush ruleset define nic=eth0 #define nic=xenbr0 table inet filter { chain input { type filter hook input priority filter; policy accept; ip protocol icmp accept ip6 nexthdr ipv6-icmp accept ip protocol vrrp ip daddr 224.0.0.0/8 accept #iif $nic tcp dport 2222 accept iif $nic ct state established,related accept iif $nic meta l4proto tcp reject with tcp reset iif $nic reject } }
and for a workstation e.g.
flush ruleset define nic=eth0 define nic2=wlan0 table inet filter { chain input { type filter hook input priority filter; policy accept; ip protocol icmp accept ip6 nexthdr ipv6-icmp accept #iif $nic tcp dport 32002 accept iif $nic ct state established,related accept iif $nic meta l4proto tcp reject with tcp reset iif $nic reject iif $nic2 ct state established,related accept iif $nic2 meta l4proto tcp reject with tcp reset iif $nic2 reject } chain forward { type filter hook forward priority filter; policy drop; } chain output { type filter hook output priority filter; policy accept; } }
in case you got firewalling rules in place from above, you first need to allow forwarding
# NAT --> accept chain forward { type filter hook forward priority 0; policy accept; }
static front-facing address
table ip nat { chain postrouting { type nat hook postrouting priority 100; ip saddr INTERNAL-CIDR oif FACING-INTERFACE snat FACING-IP; } }
–or– dynamic front-facing address
table ip nat { chain postrouting { type nat hook postrouting priority srcnat; oif eth0 masquerade oif wlan0 masquerade } }
you can also define the subnets you wanna SNAT more precisely while masquerading
ip saddr 192.168.122.0/24 oif wlan0 masquerade
chain prerouting { type nat hook prerouting priority -100; iif $nic tcp dport 80 dnat x.x.x.x; #iif $nic tcp dport 80 dnat x.x.x.x:ALTERNATE-PORT; }
apply on Ubuntu
systemctl status nftables systemctl start nftables systemctl enable nftables systemctl reload nftables
or on Slackware at boot time
vi /etc/rc.d/rc.inet1 # self-verbose sysctl -w net.ipv4.ip_forward=1 echo -n FIREWALL AND SNAT... nft -f /etc/nftables.conf && echo done || echo FAIL
nft list ruleset
flush a single table
nft flush table inet filter
If you want to be more precise on what kind of ICMP traffic you’re letting pass through, here are some hints
#icmp type echo-request accept #icmpv6 type {echo-request,nd-neighbor-solicit} accept
also something for IPv6 here
# accept neighbour discovery otherwise connectivity breaks ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept
during testing phases on a remote server, avoid shooting yourself in the pants
crontab -l > /var/tmp/crontab.dist crontab -e */15 * * * * nft flush ruleset
proceed (and cross fingers)
date nft -f /etc/nftables.conf nft list ruleset
then DO NOT FORGET TO GET RID OF THAT CRON JOB
https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes
https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server
https://wiki.gentoo.org/wiki/Nftables
https://wiki.gentoo.org/wiki/Nftables/Examples
https://wiki.archlinux.org/index.php/nftables
https://wiki.archlinux.org/title/nftables
https://wiki.debian.org/nftables
https://cryptsus.com/blog/setting-up-nftables-firewall.html
https://gist.github.com/kravietz/e527895020da22cb20281d5fdee0b1da
https://linux-audit.com/nftables-beginners-guide-to-traffic-filtering/
https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT)
[FR] https://www.it-connect.fr/chapitres/configurer-le-nat-sous-nftables/
https://superuser.com/questions/985800/complete-masquerading-nat-example-using-nftables-on-linux
https://unix.stackexchange.com/questions/283275/how-to-do-masquerading-with-nftables
https://serverfault.com/questions/895611/nftables-dnat-forwarding-is-not-working-properly
https://wiki.archlinux.org/title/nftables
https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes
https://serverfault.com/questions/157375/reject-vs-drop-when-using-iptables
Nftables opening gmabit https://discourse.pi-hole.net/t/nftables-opening-gmabit/28830
Rejecting traffic https://wiki.nftables.org/wiki-nftables/index.php/Rejecting_traffic
https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains
https://wiki.nftables.org/wiki-nftables/index.php/Operations_at_ruleset_level
https://wiki.nftables.org/wiki-nftables/index.php/Simple_rule_management
https://wiki.archlinux.org/title/nftables#Flush_table
https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing