对你修改过的问题的简短回答是,有两种方法可以做到这一点;两者都要求你删除第二个NAT步骤(它会破坏你正在寻找的信息).这样做之后的选择是:
1)使服务器A成为服务器B的下一跳,用于所讨论的流量,这就是为什么它适用于您提到的路由器.这可以通过使服务器A成为服务器B的默认路由,或使用policy routing,或使用some fancy iptables,或使用某种隧道,以cludgeyness的顺序完成.
2)“手动”在服务器B上反转服务器A的NAT,导致不对称的流量(通常不鼓励).像iptables -t nat -I POSTROUTING -j SNAT -s 2.2.2.3 – 到1.1.1.3之类的东西
我对选项(1)有100%的信心.我对(2)有90%的信心.
要理解这一点,您需要了解流量.
>客户端X将数据包发送到1.1.1.3.
>服务器A将该数据包的目的地NAT路由到2.2.2.3预路由,然后将流量路由到2.2.2.3,然后将该数据包的源NAT路由到路由后的1.1.1.3,然后将数据包发送到服务器B.
>服务器B在2.2.2.3上接收数据包,并在第二个NAT步骤中看到源地址1.1.1.3.它处理数据包并将回复发送回其源(1.1.1.3).
>服务器A在1.1.1.3上接收数据包,反转源NAT,路由数据包,反转目标NAT,并将数据包发送回客户端X.
>客户端X收到1.1.1.3的响应
现在让我们想象如果你没有第二个NAT会发生什么:
>客户端X将数据包发送到1.1.1.3.
>服务器A将该数据包的目的地NAT路由到2.2.2.3预路由,然后将流量路由到2.2.2.3,但在将数据包发送到服务器B时将源地址保留为X.
>服务器B在2.2.2.3上接收数据包,并看到X的源地址.它处理数据包并将回复发送回其源X.
>客户端X收到来自2.2.2.3的响应并丢弃它,因为它不知道来自Adam的2.2.2.3!
为了使客户端X能够理解数据包,它需要使用与原始数据包的目标相同的源地址到达客户端X.
发生这种情况的正常方法是服务器B有机会反转预路由NAT.要实现这一点,您需要在稍后的日期返回数据包.目前,您可以通过更改数据包的源地址来实现此目的,但这会破坏您在修订后的问题中要求的信息.
所以你的答案的第一步是,你不能做第二个NAT步骤(路由后SNAT):在服务器A上运行iptables -t nat -D POSTROUTING -j SNAT – 到1.1.1.3.
现在,您将面临逆转第一个NAT步骤的挑战.
如果服务器B要这样做,则需要服务器B来接收数据包.
>如果服务器A在与服务器B相同的LAN上具有地址C,则相对容易.在服务器B上:ip route通过C替换default,或者ip route add默认通过C表a; ip规则从2.2.2.3表中添加a.
>否则你必须做一些喜欢隧道的事情.
但是,如果服务器B位置的路由器不是特别复杂(有状态地检查数据包并拒绝那些对于已知流量流没有正确顺序的数据包),那么你有一个更简单,如果超级丑陋的选项:反转NAT在服务器B上根据你对服务器A所做的事情的了解:在服务器B上iptables -t nat -I POSTROUTING -j SNAT -s 2.2.2.3 – 到1.1.1.3应该这样做的建议例子.这将使A和B上的Linux连接跟踪系统有点混乱(服务器将无法将返回流量与传入流量相关联,因此它们的连接跟踪将使连接保持在UNREPLIED状态)但它应该可以正常工作到大多数流量到数百个兆.
在这种情况下,最后一次穿过交通流量:
>客户端X将数据包发送到1.1.1.3.>服务器A将该数据包的目的地NAT路由到2.2.2.3预路由,然后将流量路由到2.2.2.3,但在将数据包发送到服务器B时将源地址保留为X.>服务器B在2.2.2.3上接收数据包,并看到X的源地址.它处理数据包并将回复路由回其源X,但在发送之前,源地址的路由后NAT是1.1. 1.3.>客户X收到声称来自1.1.1.3的回复并且很高兴.