Netfilter new school with NFTABLES

nftables | nftables.nat

Requirements

zcat /proc/config.gz | grep NF_TABLES

Debian / Ubuntu

dpkg -l | grep tables
apt purge iptables
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

REJECT not DROP

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
table inet filter
flush table inet filter
table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;

        iif lo accept
        iif != lo ip daddr 127.0.0.0/8 reject
        iif != 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

Front-facing NIC

an alternative is to policy ACCEPT and filter only front-facing interface

–either– with DROP

define nic=xenbr0

table inet filter
flush table inet filter
table inet filter {
    chain input {
        type filter hook input priority filter; policy accept;

                iif lo accept
                iif != lo ip daddr 127.0.0.0/8 reject
                iif != lo ip6 daddr ::1 reject

        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 drop
    }
}

–or– with REJECT

        iif $nic ct state established,related accept
        iif $nic reject with tcp reset
        iif $nic reject with icmp type host-unreachable
        iif $nic reject

which in the end results in

                    iif eth0 ct state established,related accept
                    iif eth0 meta l4proto tcp reject with tcp reset
                    iif eth0 reject

and for a workstation e.g.

table inet filter
flush table inet filter
table inet filter {
    chain input {
        type filter hook input priority filter; policy accept;

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept

        # torrent on wired network only
        iif eth0 tcp dport 32002 accept

        iif eth0 ct state established,related accept
        iif eth0 drop

        iif wlan0 ct state established,related accept
        iif wlan0 drop
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}

or with REJECT (same as above but twice)

Ready to go

apply on Debian / 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

Acceptance

nft list ruleset

Additional notes

moar icmp

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

numered priorities

on Debian 10 you’ve got an older version of nftables which requires priorities to be written by numbers instead of names. so here’s a few for reference

   0        filter
-100        dstnat
 100        srcnat

Testing

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

Resources

https://wiki.nftables.org/wiki-nftables/index.php/Main_Page

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/

Nftables Netfilter Rules https://kb.leuxner.net/article/nftables-netfilter-rules/

tips & tricks

https://serverfault.com/questions/1018300/how-to-use-defined-variables-in-nftables-though-terminal-not-in-script

https://serverfault.com/questions/818323/how-to-define-port-range-in-nftables

icmp

http://shouldiblockicmp.com/

return-rst

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

ops

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

troubles

https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing

priorities

https://unix.stackexchange.com/questions/419851/when-and-how-to-use-chain-priorities-in-nftables

ip-based acls

https://unix.stackexchange.com/questions/558581/nftables-allow-redis-only-from-specific-ip-addresses

moar

https://stosb.com/blog/explaining-my-configs-nftables/


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5 | CONTACT
Copyright © 2024 Pierre-Philipp Braun