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.