我可以使用以下命令,但是它们会更改源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地址。
使用没有MASQUERADE
规则的PREROUTING
规则将做你所要求的。 它仍然行不通,但是这是出于不同的原因。
如果192.0.2.1
上的客户机向198.51.100.2
上的服务器发送SYN数据包,则第一个规则可以将该数据包的目标地址更改为203.0.113.3
上的其他服务器,并将其转发。
你可以用这种方法遇到的第一个问题是198.51.100.2
和203.0.113.3
之间的连接可能有源IP过滤。 这将导致数据包被丢弃,因为源地址仍然是192.0.2.1
但是路由器期望198.51.100.2
。 如果在特定networking中出现这种情况,可以使用隧道解决。
但是,你会遇到另一个问题。 一旦数据包到达203.0.113.3
,SYN-ACK将被发送回192.0.2.1
。 这将直接路由到客户端,而不通过应用DNAT
规则的第一台机器。
发送从192.0.2.1
到198.51.100.2
的SYN的客户端将看到从203.0.113.3
到192.0.2.1
的SYN-ACK。 这将不匹配客户端上的任何TCP连接,客户端将回复一个RST数据包。 一旦RST数据包达到203.0.113.3
TCP连接在服务器端被closures。
总共发送了四个数据包,并且在完全build立之前连接在服务器端被closures。 这四个数据包会重复多次,直到客户端重新发送SYN为止。
有几种方法可以解决这个问题:
203.0.113.3
到198.51.100.2
所有stream量,以确保它在返回时被翻译。 不幸的是,这将使公众IP 203.0.113.3
无用于任何其他目的。 203.0.113.3
,你可以例如把它作为辅助IP地址10.0.113.3
。 在198.51.100.2
你DNAT
到10.0.113.3
并使用一个隧道到203.0.113.3
,以获得数据包到适当的目标主机。 在203.0.113.3
,使用路由策略确保源IP为10.0.113.3
数据包通过隧道路由回去,其他数据包通过默认网关路由。 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
将不能互相通信,但是它们仍然可以和每个人通信其他。 X-Forwarded-For
让203.0.113.3
知道原来的客户IP。 然后, 203.0.113.3
上的Web服务器将需要信任源自198.51.100.2
任何连接的X-Forwarded-For
,并忽略来自其他客户端IP的连接。