我们的路由器机器的 WAN 接口上有多个公共 IP (/27)。现在,我想添加匹配特定 // 组合的dport
dnatsaddr
规则daddr
。我的梦想是这样的:
map one2one_dnat {
# dst_addr . src_addr . proto . dst_port : dnat_to . dnat_to_port
type ipv4_addr . ipv4_addr . inet_proto . inet_service : ipv4_addr . inet_service
flags interval
counter
comment "1-1 dnat"
elements = {
42.42.42.5 . 0.0.0.0/0 . tcp . 8888 : 10.42.42.5 . 8888
}
}
# And then later in a chain
ip daddr . ip saddr . ip protocol . th dport dnat to @one2one_dnat
然而,这会导致:
root@XXX# nft -c -f assembled.nft
assembled.nft:252:59-60: Error: syntax error, unexpected to, expecting newline or semicolon
ip daddr . ip saddr . ip protocol . th dport dnat to @one2one_dnat
^^
以下语法示例确实有效(但不适用于预期的花式全合一地图):
dnat ip addr . port to ip saddr . tcp dport map { 42.42.42.5 . 8888 : 10.42.42.5 . 8888}
# And even with saddr restrictions
ip saddr 0.0.0.0/0 dnat ip addr . port to ip saddr . tcp dport map { 42.42.42.5 . 8888 : 10.42.42.5 . 8888}
任何想法/建议都将受到高度赞赏
答案1
这个想法就在这里,但对于命名映射情况使用了错误的语法,而对于匿名映射情况使用了正确的语法。
如果找到,映射会用该键的值替换该键(或者表达式的计算结果为 false,停止进一步处理)。即使沿着dnat
规则使用名为的地图键值对必须使用正确的语法:key map @keytovalue
.然后,这 3 部分将根据数据包的属性替换为值,并由规则的其他部分使用。
OP的尝试不遵循语法:
ip daddr . ip saddr . ip protocol . th dport dnat to @one2one_dnat
应该这样写:
dnat to ip daddr . ip saddr . ip protocol . th dport map @one2one_dnat
这里毫不奇怪:它与匿名映射成功使用的语法 OP 相同:键(由串联组成)后跟关键字,map
后跟映射引用(这是匿名情况下的定义)。dnat [to]
将成为结果 ip:port 值的使用者(仅当发生匹配时)。
进一步注释。
对于其他读者来说,这也需要足够近的时间nftables为了进行 NAT,用户态和内核部分都支持:nftables 0.9.4 和 Linux 内核 5.6:
具有串联的 NAT 映射。这允许您指定地址和端口用于从地图进行 NAT 修改,例如
nft add rule ip nat pre dnat ip addr . port to ip saddr map { 1.1.1.1 : 2.2.2.2 . 30 }
您还可以将这个新功能与命名集一起使用:
nft add map ip nat destinations { type ipv4_addr . inet_service : ipv4_addr . inet_service \; } nft add rule ip nat pre dnat ip addr . port to ip saddr . tcp dport map @destinations
将type
语法替换为typeof
语法沿串联,这通常对于可读性来说是更好的,并且避免必须找出所有涉及的类型名称,其中一些类型名称的记录很差,目前似乎不适用于OP的情况:ip protocol
和的使用th
似乎在地图和规则之间发生冲突至少适用于 nftables 1.0.7 和内核 6.1.x。因此最好不要typeof
在这里使用并 keep type
,否则将映射分成两个单独的映射,一个用于 UDP,一个用于 TCP,以避免这种冲突。
类似的 IPv6 设置也可能需要拆分,因为ip6 nexthdr
无法安全使用替换ip protocol
,以及正确的替换,meta l4proto
也不会配合。