我可以使用以下命令,但它们会更改源 IP 地址:
iptables -t nat -A PREROUTING -p tcp --dport port -j DNAT --to-destination dest_ip:port
iptables -t nat -A POSTROUTING -j MASQUERADE
因此,我在 dest_ip 的计算机上获得了相当于这台计算机的 IP 地址的源 IP 地址,但我想获取真实的 IP 地址。
如果我删除iptables -t nat -A POSTROUTING -j MASQUERADE
,我将无法获得任何响应。我该如何解决这个问题?
所有 IP 地址都是外部 IP 地址。
答案1
PREROUTING
不使用规则而使用MASQUERADE
规则将实现您所要求的功能。它仍然不起作用,但那是出于不同的原因。
如果您有一个客户端192.0.2.1
向 上的服务器发送 SYN 数据包198.51.100.2
,则您的第一条规则可以将该数据包的目标地址更改为 上的其他服务器203.0.113.3
,然后按原样转发它。
198.51.100.2
使用此方法可能遇到的第一个问题是和之间的连接203.0.113.3
可能具有源 IP 过滤。这会导致数据包被丢弃,因为源地址仍然是,192.0.2.1
但路由器期望198.51.100.2
。如果您的特定网络中存在这种情况,可以使用隧道来解决。
但是你会遇到另一个问题。一旦数据包到达,203.0.113.3
SYN-ACK 将被发送回192.0.2.1
。这将直接路由到客户端,而无需经过第一台应用规则的机器DNAT
。
发送 SYN 的客户端192.0.2.1
将收到来自 的198.51.100.2
SYN-ACK 。这将与客户端上的任何 TCP 连接不匹配,客户端将回复 RST 数据包。一旦 RST 数据包到达,服务器端的 TCP 连接就会关闭。203.0.113.3
192.0.2.1
203.0.113.3
总共传输了四个数据包,连接在完全建立之前在服务器端关闭。这四个数据包将重复发送,直到客户端重新发送 SYN 为止,直到超时。
有几种方法可以解决这个问题:
- 路由所有流量
203.0.113.3
以198.51.100.2
确保其在返回途中得到转换。不幸的是,这将使公共 IP203.0.113.3
无法用于任何其他目的。 - 为 分配一个辅助 IP
203.0.113.3
,例如,您可以将其10.0.113.3
作为辅助 IP 地址。在 上,198.51.100.2
您DNAT
可以10.0.113.3
使用隧道203.0.113.3
将数据包发送到正确的目标主机。在 上,203.0.113.3
您可以使用路由策略来确保具有源 IP 的数据包10.0.113.3
通过隧道路由回来,而其他数据包则通过您的默认网关路由。 - 停止使用 NAT,而是使用 DSR 负载平衡方法将数据包从 发送
198.51.100.2
到203.0.113.3
。如果这两个没有直接连接且它们之间没有路由器,则将再次需要隧道。但这次隧道内的数据包保留了原始目标地址,并且203.0.113.3
不需要路由策略,而是将正确的回复直接发送到客户端。这样做的缺点是203.0.113.3
需要将 分配198.51.100.2
为辅助 IP,因此198.51.100.2
和203.0.113.3
将无法相互通信,但它们仍然可以与其他人正常通信。 - 如果您只需要支持 HTTP,则可以使用代理而不是 NAT。然后您可以使用它
X-Forwarded-For
来203.0.113.3
告知原始客户端 IP。203.0.113.3
然后,Web 服务器将需要信任X-Forwarded-For
来自的任何连接198.51.100.2
,并忽略来自其他客户端 IP 的连接。