我正在根据这个问题的答案进行工作,man nft
以便dnat
在我的配置中创建一些规则nftables
。
相关配置摘录为:
define src_ip = 192.168.1.128/26
define dst_ip = 192.168.1.1
define docker_dns = 172.20.10.5
table inet nat {
map dns_nat {
type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service
flags interval
elements = {
$src_ip . $dst_ip . udp . 53 : $docker_dns . 5353,
}
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat;
}
}
当我应用此规则时nft -f
,我没有看到任何命令输出,因此我认为它已成功。但是,当我使用规则检查规则集时,nft list ruleset
这些规则不存在。当该dnat to ...
行被注释掉时,规则似乎被应用,但是当该行存在时,规则不被应用。
prerouting
我试图替换的链中的规则集合是:
ip saddr $src_ip ip daddr $dst_ip udp dport 53 dnat to $docker_dns:5353;
...
版本信息:
# nft -v
nftables v1.0.6 (Lester Gooch #5)
# uname -r
6.1.0-11-amd64
为什么这可能不起作用?谢谢
有3个问题。
没有显示错误
这看起来是nftables 1.0.6 中的一个错误,请参阅以下要点。
这里有相同的版本和OP的规则集
/tmp/ruleset.nft
:错误:未知数据类型
ip_proto
原始链接的问答使用了正确的类型
inet_proto
。不应将其替换为ip_proto
未知类型。所以替换回来:正确的原始拼写:
可用类型的列表可以在 PAYLOAD EXPRESSION 中找到
nft(8)
,更准确地说,对于这种情况,可以在IPV4 HEADER EXPRESSION中找到:typeof ip protocol
<=>type inet_proto
(不是type ip_proto
)。通常
typeof
应该优先type
避免猜测正确的类型,但正如我在链接的 Q/A 中所写,某些版本的nftables可能无法正确处理这种精确的情况。替代方案是:这几乎是使用它的规则的剪切/粘贴,但它的行为应该经过彻底的测试。
没有显示错误 - 采取 2
一旦修复了之前的错误(并将结果放入
/tmp/ruleset2.nft
),那么,正如OP所写,再次尝试规则集会默默失败:失败的唯一线索是非 0 返回代码。
使用较新的nftables版本时:
现在显示错误。无论 1.0.6 中出现什么问题,至少在 1.0.8 版本中已得到修复。
错误:在 inet 表中指定“dnat ip”或“dnat ip6”以消除歧义
由于 NAT 是在
inet
系列(组合 IPv4+IPv6)中完成的,而不是在ip
(IPv4) 或ip6
(IPv6) 系列中完成,因此通常可选的一个参数变成了必需参数:声明应应用 NAT 的 IP 版本(即使可以推断出它)来自地图表布局 (IPv4))。文档告诉:所以:
应替换为:
最初的 Q/A 没有说明该系列,因此假设它是默认
ip
系列,不需要这样做。当然,这适用于nftables 1.0.6,只是错误报告有问题。返回码现在将为 0。