如何在没有先前匹配的情况下使用 nftables dnat 和重定向

如何在没有先前匹配的情况下使用 nftables dnat 和重定向

我有

table ip nat {
    chain Redirect_to_local {
            limit rate 3/minute burst 10 packets log prefix "[nft.ip.dnat.8080]: "
            redirect to :8080
    }
    chain PREROUTING {
            type nat hook prerouting priority dstnat; policy accept;
            iifname != { "lo", "ISP*" } fib daddr type != { local, multicast, broadcast } udp dport == 8000 counter jump Redirect_to_local
    }
}

这是不正确的,因为transport protocol mapping is only valid after transport protocol match。但为什么呢?它确实匹配,但不是直接匹配。

如果我udp dport == 8000在重定向之前添加,它将被接受为正确的,尽管规则重复(这很烦人)。

有办法解决这个问题吗?还是我误解了?

答案1

ip protocol udp(从数据包的内容)或meta l4proto udp(从测量的数据包的属性。通常在编写时会自动暗示这一点,例如udp dport 8000)是无需再次指定端口即可判断其为 UDP 的方式。如果没有这条仅是单规则范围的信息,NAT 语句将接受仅更改第 3 层(此处为 IPv4)而不更改第 4 层:它将接受更改地址但不更改端口。redirect通常意味着更改端口(但不是必需的。仅包含的单条规则redirect行有效),然后通常必须说明协议。

因此你可以替换:

redirect to :8080

使用以下任一方式:

meta l4proto udp redirect to :8080

或者:

ip protocol udp redirect to :8080

注意:对于 IPv6,使用meta l4proto udp是唯一正确的选择,因为ip6 nexthdr udp(相当于ip protocol udp)在存在 IPv6 选项的情况下会失败,因为 IPv6 固定报头不提供最终的传输报头协议,而只提供下一个标头,其可以是选项标头,因此有所不同。

相关内容