Netfilter new school with NFTABLES

Requirements

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
mv /etc/nftables/ /etc/nftables.dist/

Setup

we’re going for a very specific setup – we want to REJECT, not just DROP

vi /etc/nftables.conf #new file

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; 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 22 accept

        ct state established,related accept
        #ct state invalid reject
        reject
    }

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

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

Note you can also use names instead of numered priorities e.g. filter instead of 0.

Default policy can only be accept or drop. But reject can still be defined as last and ipso-facto default rule nevertheless.

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

NAT / MASQUERADE

vi /etc/nftables.conf

    #NAT --> accept
    chain forward {
            type filter hook forward priority 0; policy accept;
    }

table ip nat {
        #DNAT
        chain prerouting {
                type nat hook prerouting priority -100;
                #iifname eth0 tcp dport 80 dnat x.x.x.x
        }

        #SNAT
        chain postrouting {
                type nat hook postrouting priority 100;
                oifname eth0 masquerade
        }
}

another example

table inet my_nat {
        chain my_masquerade {
                type nat hook postrouting priority srcnat; policy accept;
                oifname "ppp0" masquerade
        }
}

Ready to go

apply on Ubuntu

    systemctl reload nftables

or on Slackware

nft -f /etc/nftables.conf

Acceptance

nft list ruleset

Additional notes

More icmp options

            #icmp type echo-request accept
            #icmpv6 type {echo-request,nd-neighbor-solicit} accept

            # accept neighbour discovery otherwise connectivity breaks
            ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept

An alternative would be policy ACCEPT and reject only on eth0

        type filter hook input priority 0; policy accept;
        ...
        iifname eth0 tcp dport 80 accept
        iifname eth0 tcp dport 443 accept
        iifname eth0 tcp dport 2222 accept
        iifname eth0 tcp dport 4444 accept
        iifname eth0 udp dport 4444 accept
        iifname eth0 ct state established,related accept
        #iifname eth0 ct state invalid reject
        iifname eth0 reject

TODO

Let’s filter outbound traffic also, shall we?

Resources

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

https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes

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

https://wiki.gentoo.org/wiki/Nftables

https://wiki.gentoo.org/wiki/Nftables/Examples

https://linux-audit.com/nftables-beginners-guide-to-traffic-filtering/

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

nat

https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT)

https://superuser.com/questions/985800/complete-masquerading-nat-example-using-nftables-on-linux


HOME | GUIDES | BENCHMARKS | html