1

Been using nftables for the last 2 years with the same config, updated the program the other day and now its complaining that my config isnt valid even though all the documentation still says its right. maybe someone can spot a rogue symbol or something?

heres my config:


flush ruleset

# `inet` applies to both IPv4 and IPv6.
table inet filter {
    chain input {
        type filter hook input priority 0;

        # accept any localhost traffic
        iif lo accept

        # no ping floods:
        ip protocol icmp icmp type echo-request limit rate over 10/second burst 4 packets drop
        ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 4 packets drop

        # accept traffic originated from us
        ct state established,related accept

        # ssh
        tcp dport 22 accept

        # http/https
        tcp dport 80 accept
        tcp dport 443 accept

        # tftp/netboot
        udp dport 4011 accept
        udp dport 67 accept
        tcp dport 69 accept
        udp dport 69 accept

        # listinator
        tcp dport 8080 accept
        tcp dport 4343 accept

        # smb
        tcp dport 139 accept
        tcp dport 445 accept
        udp dport 137 accept
        udp dport 138 accept

        # mc
        tcp dport 25565 accept

        # count and drop any other traffic
        counter drop
    }

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

    chain forward {
        type filter hook forward priority 0;
        nft add rule inet filter forward ct status dnat accept;
        policy drop;
    }
}

and the error when starting:

Starting nftables...
/etc/nftables.conf:57:6-8: Error: syntax error, unexpected add
        nft add rule inet filter forward ct status dnat accept;
            ^^^
nftables.service: Main process exited, code=exited, status=1/FAILURE
nftables.service: Failed with result 'exit-code'.
Failed to start nftables.
PetNoire
  • 11
  • 1

1 Answers1

0

This is inside an nftables script loaded with the command nft -f. The nft word has no meaning inside and should not appear. But there are 1 1/2 other problems at the same place. So let's see:

Around the line the nft command complains there is:

   chain forward {
       type filter hook forward priority 0;
       nft add rule inet filter forward ct status dnat accept;
       policy drop;
   }
  • nft to be removed,

  • already inside an inet filter forward (chain) block

    So add rule inet filter forward must also be removed. Actually the ; is superfluous because there's a new line after.

           ct status dnat accept
    
  • policy drop; must be put with the base chain definition

    This time with its mandatory ; part of the syntax. the policy keyword is part of the chain definition, not part of a rule definition. While this appears to be currently accepted separated from its base chain definition by rules between, that's not something to rely on: this could change in a later release.

    The same remark applies for the output chain: don't separate policy accept; from its base chain definition so you won't insert rules between by mistake later.

The forward chain should in the end be replaced with:

    chain forward {
        type filter hook forward priority 0; policy drop;
        ct status dnat accept
    }

What would be correct syntax, but not really interesting, is to define the rule not inside the blocks, but completely outside of structures, at the end of the script like this:

    chain forward {
        type filter hook forward priority 0; policy drop;
    }
}
add rule inet filter forward ct status dnat accept

Anyway nft list ruleset will then display it back as before within the inet filter forward chain block.


Notes:

  • while it's OK to use ip protocol icmp, it's not OK to use ip6 nexthdr ipv6-icmp

    the reason is that contrary to IPv4 where the protocol in the IPv4 header is always the layer 4 protocol, IPv6's next header is not always the layer 4 (icmp, udp, tcp...) header: it could be instead an Extension header appearing between the IPv6 header and the layer 4 (final) header. In this case the rule won't match.

    The OS already determined what layer 4 protocol this packet belongs to, so the information is available as meta information rather than packet content information: meta l4proto ipv6-icmp.

    This is also documented in the man page:

    This expression refers to the ipv6 header fields. Caution when using ip6 nexthdr, the value only refers to the next header, i.e. ip6 nexthdr tcp will only match if the ipv6 packet does not contain any extension headers. Packets that are fragmented or e.g. contain a routing extension headers will not be matched. Please use meta l4proto if you wish to match the real transport header and ignore any additional extension headers instead.

    But actually, as the same line does include an icmpv6 type ... line, this already filters the layer 4 protocol to match ICMPv6, and at the same time the use of ICMPv6 implicitly sets the layer 3 protocol to match IPv6: nothing is needed at all to make it right.

    Likewise the previous line can do without ip protocol icmp for the same reasons (but its current behavior is still fine).

    The line:

            ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 4 packets drop
    

    must be replaced simply with:

            icmpv6 type echo-request limit rate over 10/second burst 4 packets drop
    

    (without the need to prepend meta nfproto ipv6 meta l4proto icmpv6 )

  • TFTP

    • TFTP uses only UDP

      TCP port 69 is never used so doesn't require a rule to allow it.

    • TFTP and stateful firewalling

      TFTP is a protocol as difficult as FTP for firewalls. After initial query, the data transfer itself doesn't use UDP port 69 anywhere anymore. Adequate use of the TFTP conntrack helper with additional rules (that should autoload the nf_conntrack_tftp kernel module) should probably be needed, unless the deprecated sysctl setting net.netfilter.nf_conntrack_helper was enabled back.

      This would really become off-topic to address this here. See the beginning (only) of my answer to CentOS 8 as NAT router with nft and firewalld - how to get it to pass TFTP? to have an example TFTP ruleset that can be copied to replace the FTP example in the nftables wiki.

  • identical rules with just different port values can be factorized using anonymous sets. nftables version >= 1.0.2 even has the -o (optimize) option to try and do this automatically.

A.B
  • 9,037
  • 2
  • 19
  • 37
  • so why did it work perfectly the day before posting. also wow most detailed response ive gotten on here yet, id hit the up arrow if this site let me do anything – PetNoire May 12 '22 at 21:53
  • @PetNoire Can't what was different before, but did tell what must be done. If you think this solved your problem you can still mark this answer as the accepted answer to thank me. – A.B May 13 '22 at 20:25