端口转发 - 为什么 iptables 需要 POSTROUTING 规则?

端口转发 - 为什么 iptables 需要 POSTROUTING 规则?

假设我有两台服务器:

-->服务器 A 的 IP 为 XXX.XXX.XXX.XXX

-->服务器 B 的 IP 地址为 YYY.YYY.YYY.YYY

我想要的是将流量从服务器 A(端口 80)重定向到服务器 B(端口 80)。

一个简单的方法是将以下规则与服务器 A 中的 iptables 一起放置:

iptables -t nat -A PREROUTING -p tcp --dport port -j DNAT --to-destination server B:80

然而,这个简单的规则不起作用。我们必须添加以下规则:

iptables -t nat -A POSTROUTING -j MASQUERADE

为什么这样?为什么我们需要添加 POSTROUTING 规则?在 PREROUTING 之后,数据包一定会自动转到服务器 B,对吗?

答案1

* 我不是 iptables 或 Linux 网络调度方面的专家,但我会尽力提供帮助!

根据描述纳特(网络地址解读)表中,在iptables 手册页

“当遇到创建新连接的数据包时,会查阅该表。它由三个内置函数组成:PREROUTING(用于在数据包进入后立即更改数据包)、OUTPUT(用于在路由之前更改本地生成的数据包)和POSTROUTING(用于在数据包即将发出时更改数据包)”。

POSTROUTING 链在数据包发出之前对其进行更改。

下面我得到的 MASQUERADE 解释Linux 文档项目我还让你的信息变得有意义:

  • 我告诉机器我的 PPP 或以太网连接的 Linux 盒子A是它的网关。
  • 当数据包进入 Linux 盒子时A,它将为数据包分配一个新的 TCP/IP 源端口号,并在数据包标头中插入自己的 IP 地址,保存原件。然后,MASQ 服务器将通过 PPP/ETH 接口将修改后的数据包发送到互联网上。
  • 当数据包从互联网返回到 Linux 盒子时A,Linux 检查端口号是否是上面分配的端口之一。如果是,MASQ 服务器将获取原始端口和 IP 地址,将它们放回到返回的数据包标头中,并将数据包发送到
  • 发送数据包的主机永远不会知道其中的差异。

答案2

你的问题分为两部分。

  1. 为什么我们需要 MASQUERADE 规则。
  2. 为什么它需要在 POSTROUING 链中。
  3. 有什么替代方案吗?

要回答第一个问题,我们必须首先了解 iptables NAT 的工作原理。 NAT 表用于连接的第一个数据包,以确定应将哪些转换应用于该连接。一旦处理了第一个数据包,就会创建一个内部映射表条目,该条目用于处理连接的后续数据包,但盒子只能处理它看到的数据包。

因此,我们假设 XXX.XXX.XXX.XXX 和 YYY.YYY.YYY.YYY 都是 Internet 上的服务器,没有配置特殊路由。假设客户端也在没有防火墙的开放互联网上,并且 IP 为 ZZZ.ZZZ.ZZZ.ZZZ 。让我们看看如果没有 MASQURADE 规则会发生什么。

  • 客户端发送初始数据包 ZZZ.ZZZ.ZZZ.ZZZ:1234 -> XXX.XXX.XXX.XXX:80
  • 数据包到达执行目标 NAT 的服务器 A,因此数据包现在为 ZZZ.ZZZ.ZZZ.ZZZ:1234 -> YYY.YYY.YYY.YYY:80,它创建连接跟踪条目并将数据包放回网络。
  • ISP 可能会在此时阻止数据包进行“欺骗”,或者他们可能会将其传送到服务器 B。让我们假设他们确实将其传送到服务器 B。
  • 数据包到达服务器 B,服务器 B 生成响应 YYY.YYY.YYY.YYY:80 -> ZZZ.ZZZ.ZZZ.ZZZ:1234
  • 响应被传递给客户端。
  • 客户端在其套接字表中查找响应,但未能找到匹配项并丢弃该数据包(可能在响应中发送 ICMP 错误)。

如果我们添加 MASQUERADE 规则,情况会如何变化?

  • 客户端发送初始数据包 ZZZ.ZZZ.ZZZ.ZZZ:1234 -> XXX.XXX.XXX.XXX:80
  • 数据包到达执行目标 NAT 的服务器 AMASQURADING,因此数据包现在是 XXX.XXX.XXX.XXX:5678 -> YYY.YYY.YYY.YYY:80,它将其放回到网络上。
  • ISP 将数据包传递给服务器 B
  • 数据包到达服务器 B,服务器 B 生成响应 YYY.YYY.YYY.YYY:80 -> XXX.XXX.XXX.XXX:5678
  • 响应被传送到服务器A
  • 服务器 A 在其连接跟踪表中查找数据包,并将其源和目标更改为 XXX.XXX.XXX.XXX:80 -> ZZZ.ZZZ.ZZZ.ZZZ:1234
  • 网络将响应传递给客户端。
  • 客户端在其套接字表中查找响应并找到匹配项。连接已成功建立。

对于问题 2,我确实没有答案,iptables 坚持认为 SNAT/MASQUERADE 只能在 POSTROUTING 中完成,但我没有看到任何好的技术理由来解释为什么会出现这种情况。


我们可能有理由希望避免使用 MASQUERADE。它有几个问题,首先,我们丢失了我们希望用于滥用控制的原始流量来源的信息。其次,服务器 A 的端口供应有限。

这个问题可以解决,但前提是两台服务器都在我们的控制之下。该解决方案涉及三个步骤。

  • 我们在服务器 A 和 B 之间建立某种隧道。隧道端点被分配了私有 IP 地址。
  • 在服务器 A 上,我们将流量 DNAT 到服务器 B 的隧道 IP。
  • 在服务器 B 上,我们使用策略路由,以便来自服务器 B 的私有 IP 的流量沿着隧道发送到服务器 A,而不是发送回互联网。

相关内容