原始 IP 因 IPTables NAT 而丢失到另一台服务器

原始 IP 因 IPTables NAT 而丢失到另一台服务器

我正在尝试将所有 HTTP 流量从一台 EC2 Linux 服务器(外部 IP 11.11.11.11)转发到另一台服务器(外部 IP 22.22.22.22),设置以下规则:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 22.22.22.22:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo service iptables save
sudo service iptables restart

但是当从客户端运行 CURL 时,目标服务器将 11.11.11.11 视为请求的原始 IP。因此,我尝试了类似问题中提供的方法,-d 11.11.11.11在第一个命令中添加了,因此它看起来像这样:

sudo iptables -t nat -A PREROUTING -d 11.11.11.11 -p tcp --dport 80 -j DNAT --to-destination 22.22.22.22:80

但是现在尝试 CURL 到 11.11.11.11 会导致Connection refused错误。

知道为什么第二个命令失败以及如何正确执行此操作吗?

答案1

更改 IP 地址是 NAT 的工作方式。这本质上就是目的网络地址转换。如果源地址没有改变,目标机器将尝试直接回复原始客户端,这将失败,因为客户端会认为该回复来自意外的地方(来自“错误”IP 地址的回复)并拒绝它,或者状态防火墙会阻止它(将其检测为从未建立的会话的延续),或者目标主机没有返回发送者的路由。

为了保留原始主机的身份,您必须将该信息保存在 IP 数据包以外的其他地方。

最常见的方法可能是 HTTP 反向代理;目前有 HAProxy、squid、varnish、apache、nginx 和许多其他解决方案。它们的工作原理是插入一个新标头(通常X-Forwarded-For:插入到 http 请求标头中),以将连接的客户端标识到目标 Web 服务器。

这是最简单的解决方案。NAT 似乎不符合您的需要。

另外,HAProxy 和其他一些平台可能支持一种称为PROXY协议的东西,它以伪带外格式传输客户端 IP 和端口(以及原始目标 IP 和端口),然后再通过连接传输实际有效负载。与解决方案不同X-Fowarded-For:,如果实际 Web 服务器不支持,则可以通过应用程序解释该解决方案(通过访问 http 请求标头),而协议PROXY要求目标服务器理解该协议。从好的方面来说,这种替代方案适用于大多数基于 TCP 流的协议(除了 http),因为它不需要修改实际请求本身。

相关内容