我观察到 MASQUERADE 目标与回复方向的数据包不匹配(就 netfilter conntrack 而言)。
我有一个简单的-t nat -A POSTROUTING -s 10.a.0.0/16 -d 10.b.0.0/16 -j MASQUERADE
规则,除了所有链上的 ACCEPT 政策之外别无其他,似乎
案例 1) 来自 10.a/16 网络的连接初始化尝试的 SYN 数据包被 NAT-ed(这没关系),而
情况 2) 再次来自 10.a/16 网络的 SYN/ACK 数据包(响应来自 10.b/16 的 SYN,即在这种情况下发起方是 10.b/16)不会被翻译,但 src 地址是保持原样,简单地路由。
我不确定这是预期的行为还是我错过了什么?我的意思是我不希望它以任何其他方式表现,一切似乎都有效。但是文档并没有向我确认这是 MASQUERADE 目标的出厂默认行为。
你能确认一下吗?谢谢。
TCP 连接的标识由一组四件事定义:
TCP 协议标准规定,如果这四项中的任何一项发生了变化,则数据包不得被视为同一连接的一部分。因此,如果初始 SYN 也未经过 NAT,则开始将 NAT 规则应用于 SYN/ACK 数据包是没有意义的。您必须从头到尾对整个连接应用相同类型的 NAT 映射,或者根本不对其进行 NAT;任何尝试添加或更改中间连接的 NAT 映射只会导致 TCP 连接失败。这是 TCP 协议的一个基本事实,Linux iptables/netfilter 代码旨在考虑到这一点。
在您的情况 2) 中,SYN/ACK 前面是来自 10.b/16 的 SYN。该 SYN 的来源为 10.b/16,因此它与 MASQUERADE 规则不匹配,并使用保持原样的地址进行路由。那么,如果从 10.a/16 回到 10.b/16 的 SYN/ACK 会被翻译,那么原始 SYN 的发送者将不再将其识别为对自己 SYN 的响应,即源 IP + 目标 IP + 源端口 + 目标端口组合与预期的有效响应不同。
本质上,在 10.b/16 中启动连接的系统中的 TCP 协议驱动程序会思考:“唉。
10.a.connection.destination
没有回答。并且10.b.NAT.system
明显是虚假的 SYN/ACK 困扰着我:我正在尝试连接10.a.connection.destination
,不是他。如果我有时间,我会发送一两个 RST 给10.b.NAT.system
; 希望他意识到自己的错误并停止打扰我。MASQUERADE 只是带有传出接口源的 SNAT(源 NAT)(请参阅
man iptables-extensions
.连接尝试(初始 SYN)被 NAT,然后在内核中跟踪连接(“conntrack”),并且此连接中的所有数据包都在适当的方向上被 NAT。
所以是的,对传入 SYN 的传出 SYN/ACK 答案不会被 SNAT NAT。如果要对传入的 SYN 进行 NAT,则需要 DNAT,而不是 SNAT。这也会对 SYN/ACK 应答进行 NAT。
它发生了,因为当数据包进入相反方向时,它的源是 10.b/24 和目标 10.a/24,这意味着它不会被您的规则处理。您必须添加两条规则才能使 MASQUERADE 发生: