Nftables:具有源地址限制和只有一张映射的 Dnat

Nftables:具有源地址限制和只有一张映射的 Dnat

我们的路由器机器的 WAN 接口上有多个公共 IP (/27)。现在,我想添加匹配特定 // 组合的dportdnatsaddr规则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也不会配合。

相关内容