我有
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 固定报头不提供最终的传输报头协议,而只提供下一个标头,其可以是选项标头,因此有所不同。