私有 IPV4 地址如何绕过 iptables NAT(tcp RST、FIN)

私有 IPV4 地址如何绕过 iptables NAT(tcp RST、FIN)

我有一个路由器使用 iptables 执行简单的 NAT 转换 iptables -t nat -o -j MASQUERADE

除了某些 TCP RST 和 FIN 数据包离开路由器未进行 NAT 的特殊情况外,该方法几乎所有情况下都能正常工作。

在这种情况下,我设置了 1 或 2 台客户端计算机来流式传输 Flash 视频(例如 www.nasa.gov/ntv)。在路由器上,我随后拆除并重新建立公共接口(即调制解调器)。正如预期的那样,Flash 流停滞。重新建立连接后,我尝试刷新 Flash 页面,我看到一些 TCP RST 和 [FIN,ACK] 数据包离开公共接口(我假设 Flash 尝试恢复其流)。

我不知道这些数据包如何能让路由器不进行 NAT

答案1

谢谢你的提示。我正是我需要的,它能让我走上正确的道路。

根本原因是局域网和公共接口之间未过滤的转发。当公共接口被拆除时,它会清除 conntrack 条目。然后客户端尝试恢复其连接,并最终发出 RST 和 FIN 数据包。由于 NAT 仅在新连接上设置,因此这些数据包不会对路由器进行修改。

我必须更改我的转发规则,以仅允许 NEW、ESTABLISHED、RELATED 数据包从私有局域网转发。

答案2

放下[RST,确认][结束,确认]不起作用。有许多应用程序(如 ftp upload)无法确认 FTP 传输的完成。gscott 的评论是正确的方法,但还需要一个额外的要求。您必须通过应用策略使其变得严格

iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -P INPUT DROP

为此,您需要指定所有规则,否则数据包将被丢弃。

答案3

这可能是 iptables 的 MASQUERADE 目标中的一个错误。在您的场景中,似乎有以下同时发生的事件:

  • 这些数据包恰好属于状态表中已存在的连接
  • 状态条目包含不再属于系统的 NAT 地址源

因此,伪装数据包的尝试可能会由于伪装的地址无效而失败,因此数据包将被不加改变地路由出去。

MASQUERADE 目标的预期行为是当接口关闭或地址更改时清除相应的状态条目,因此这种情况不应该发生。但是iptables 中存在一个古老的错误这听起来可能会引发类似的行为。

要进行进一步的故障排除,请记下路由器的公共 IP 地址,重现问题并使用(其中 12.34.56.78 是您之前记下的 IP 地址)查看状态表egrep 12.34.56.78 /proc/net/ip_conntrack。如果尽管公共接口地址已更改,但您仍收到带有旧 IP 地址的 conntrack 行,则您可能遇到了 iptables 错误 - 考虑更新您的内核/iptables 并将问题报告给 netfilter 团队。

答案4

中的规则-t nat仅适用于流(状态NEW)中的第一个数据包。该流中的其他数据包将进行相同的处理,而无需对它们应用任何其他 iptables 规则。但无法启动流(例如FINRST,或者可能是 以外的任何数据包SYN)并且与当前流无关的数据包将被 忽略-t nat。iptables 状态机将这些数据包归类为 状态INVALID。可以使用以下方法将它们过滤掉:

iptables -A FORWARD -m state --state INVALID -j DROP

根据您的其他规则,可能需要将此规则插入到-j ACCEPT规则之前。

相关内容