因此,您还必须抓取查询。任何使数据包使用路由器的 IP 地址都可以:路由器的内部 IP ( masquerade),因为路由器拥有此 IP,或任何 Internet IP (使用snat),因为它们是通过路由器路由的。您甚至可以想象为此使用一些 TEST-NET IP(例如:192.0.2.2):无论如何,在本地网络之外永远不会看到 IP 地址。缺点是 DNS 服务器无法识别进行查询的 IP。如果这真的很重要,更新的内核(即将发布的 5.7 或 5.8)将提供相当于 iptables 的 NETMAP 的版本。
为简单起见,让我们masquerade在这里使用。
因此,在等效的后路由链中,可以使用类似的东西创建(请适应您自己的命名约定):
nft add chain ip nat postrouting '{ type nat hook postrouting priority 100; policy accept; }'
规则是:
ip daddr 192.168.22.5 udp dport 53 counter masquerade
这不会影响从 DNS 服务器发起的任何返回流量,因为它的 conntrack 条目将不再处于状态 NEW 并且不会遍历此nat规则。
如果您只想影响来自br0而不是来自其他地方的先前 dnat-ed 流量,有几个选项:
检查源 IP 来自 192.168.22.0/24 和 dnat-ed
ip saddr 192.168.22.0/24 ip daddr 192.168.22.5 udp dport 53 ct status dnat counter masquerade
使用最新的内核(> = 5.6)匹配传入接口(仍在后路由中)就足够了:
iifname "br0" ip daddr 192.168.22.5 udp dport 53 ct status dnat counter masquerade
或者,如果它们与其他用途不冲突,您可以在预布线和后布线中使用标记:
预路由:
iifname "br0" ip saddr != 192.168.22.5 udp dport 53 counter set mark 1 dnat to 192.168.22.5:53
您只需添加一个附加条件以不匹配此 IP 地址,因此最终不执行 NAT:
但是...如果客户端和 DNS 服务器都在同一个 LAN 中,那么回复将直接从 DNS 服务器到客户端。例如,将 192.168.22.101 的客户端设置为使用 google 的公共解析器(涉及所有涉及的隐私问题),您将得到以下信息:
查询:192.168.22.101 到 8.8.8.8 -> 路由和 dnat-ed -> 192.168.22.5
回复:192.168.22.5 -> 桥接(或在这两种情况下路由器根本看不到)ip 系列规则看不到 -> 192.168.22.101
但是由于 192.168.22.101 期望来自 8.8.8.8 的答案,而不是来自 192.168.22.5 的答案,它会失败。
因此,您还必须抓取查询。任何使数据包使用路由器的 IP 地址都可以:路由器的内部 IP (
masquerade
),因为路由器拥有此 IP,或任何 Internet IP (使用snat
),因为它们是通过路由器路由的。您甚至可以想象为此使用一些 TEST-NET IP(例如:192.0.2.2):无论如何,在本地网络之外永远不会看到 IP 地址。缺点是 DNS 服务器无法识别进行查询的 IP。如果这真的很重要,更新的内核(即将发布的 5.7 或 5.8)将提供相当于 iptables 的 NETMAP 的版本。为简单起见,让我们
masquerade
在这里使用。因此,在等效的后路由链中,可以使用类似的东西创建(请适应您自己的命名约定):
规则是:
这不会影响从 DNS 服务器发起的任何返回流量,因为它的 conntrack 条目将不再处于状态 NEW 并且不会遍历此nat规则。
如果您只想影响来自br0而不是来自其他地方的先前 dnat-ed 流量,有几个选项:
检查源 IP 来自 192.168.22.0/24 和 dnat-ed
使用最新的内核(> = 5.6)匹配传入接口(仍在后路由中)就足够了:
或者,如果它们与其他用途不冲突,您可以在预布线和后布线中使用标记:
预路由:
后路由:
最后,由于 DNS 使用 TCP 和 UDP,您可能也应该使用
tcp dport 53
.源自主机本身的流量与
iifname $outgoing_interface
(butiifname lo
) 不匹配,因此您的担忧不存在。