如何将所有stream量转发/ NAT到一个接口/ IP到远程IP?

我有一个“服务器A”有多个IP连接到它,如下所示:

eth0:0 1.1.1.1 eth0:1 1.1.1.2 eth0:2 1.1.1.3 

我有另一个“服务器B”,也有多个IP连接到它,如下所示:

 eth0:0 2.2.2.1 eth0:1 2.2.2.2 eth0:2 2.2.2.3 

现在,我想在“服务器A”上设置iptables,将“eth0:2”上的所有inputstream量转发/ NAT到“服务器B”上的IP 2.2.2.3。

我已经validation了“服务器A”能够在IP 2.2.2.3上“通话”到“服务器B”。 Ping和Telnet打开端口工作得很好,我打开了前进标志(net.ipv4.ip_forward = 1)

我已经尝试了多种不同的方式,DNAT,SNAT,MASQUERADE等,但是我什么都不能工作。

如果我尝试在同一服务器上的IP之间转发stream量,此线路正常工作:

 iptables -t nat -A PREROUTING -d 1.1.1.3 -j DNAT --to-destination 1.1.1.2 

但是如果我把“2.2.2.3”中的“1.1.1.2”换掉,那就不起作用了。

我假设我需要第二个iptable规则来解决它。 我没有任何运气(不是在同一时间)尝试了以下POSTROUTING规则:

 iptables -t nat -A POSTROUTING -d 2.2.2.3 -j MASQUERADE iptables -t nat -A POSTROUTING -d 2.2.2.3 -j SNAT --to 1.1.1.3 iptables -t nat -A POSTROUTING -j MASQUERADE 

我错过了什么?

编辑1:

我终于通过使用下面的工作:

 net.bridge.bridge-nf-call-iptables=0 iptables -t nat -A PREROUTING -d 1.1.1.3 -j DNAT --to-destination 2.2.2.3 iptables -t nat -A POSTROUTING -d 2.2.2.3 -j SNAT --to 1.1.1.3 

但是,现在出现了另一个问题。 服务器2.2.2.3上的所有日志等显示所有的stream量现在来自1.1.1.3,如apache日志,邮件日志等。我认为这是NAT的性质。

但是,当我在我的家庭路由器上执行标准端口转发到运行apache的笔记本电脑时,我在日志中看到原始的“请求者IP”。 那么,路由器如何做到这一点? 我怎么能在我的服务器设置上做同样的事情?

底线,我想转发从服务器A(1.1.1.3)到服务器B(2.2.2.3)的所有stream量,但我也希望能够看到来自服务器B(2.2.2.3)的stream量,即apache日志应该显示请求者的原始IP。

我想我应该使用其他方式比NAT来做到这一点,这应该是可能的,因为即使我简单的家庭路由器能够做到这一点。

一个额外的事情,连接到服务器A和服务器B的IP被locking到每个相应的服务器。 因此,服务器A不能发送来自IP 2.2.2.3的stream量。 它被我的供应商locking在路由器中。

你修改后的问题的简短回答是有两种方法可以做到这一点; 都要求你删除第二个NAT步骤(这会破坏你正在寻找的信息)。 这样做后你的select是:

1)使服务器A成为服务器B的下一跳,用于所讨论的stream量,这就是为什么它可以像上面提到的那样为你的路由器工作。 这可以按照cludgeyness的顺序来完成,使服务器A成为服务器B的默认路由,或者使用策略路由 ,或者使用一些简单的iptables ,或者使用某种types的隧道。

2)在服务器B上“手动”反转服务器A的NAT,导致stream量不对称(通常不鼓励)。 就像iptables -t nat -I POSTROUTING -j SNAT -s 2.2.2.3 --to 1.1.1.3

(1)我对100%信心十足。 (2)我有90%的信心。

要了解这一点,你需要了解交通stream量。

  1. 客户端X发送一个数据包到1.1.1.3。
  2. 服务器A将该数据包的目的地址转换为2.2.2.3预路由,然后将数据stream路由到2.2.2.3,然后将该数据包的源地址转换为1.1.1.3后路由,然后将数据包发送到服务器B.
  3. 服务器B在2.2.2.3接收到数据包,并在第二个NAT步骤中看到源地址1.1.1.3。 它处理数据包并将应答发送回其源(1.1.1.3)。
  4. 服务器A在1.1.1.3接收数据包,反转源NAT,路由数据包,反转目标NAT,并将数据包发送回客户端X.
  5. 客户端X收到来自1.1.1.3的响应

现在让我们想象一下,如果你没有第二个NAT,会发生什么:

  1. 客户端X发送一个数据包到1.1.1.3。
  2. 服务器A将该数据包的目的地址转换为2.2.2.3预路由,然后将数据stream路由到2.2.2.3,但将数据包发送到服务器B时将源地址保留为X.
  3. 服务器B在2.2.2.3接收到数据包,并看到X的源地址。它处理数据包并将应答发送回其源X.
  4. 客户端X收到来自2.2.2.3的响应并丢弃它,因为它不知道Adam的2.2.2.3!

为了使客户端X了解数据包,它需要以与原始数据包的目的地相同的源地址到达客户端X.

这种情况发生的正常方式是服务器B有机会反转预路由NAT。 为了实现这一点,你需要在晚些时候通过数据包。 目前,您通过更改数据包的源地址来做到这一点,但这会破坏您在修改后的问题中所要求的信息。

所以你的答案的第一步是,你不能做第二个NAT步骤(路由后的SNAT):在服务器A上运行iptables -t nat -D POSTROUTING -j SNAT --to 1.1.1.3

现在,您将面临逆转第一个NAT步骤的挑战。

如果服务器B要这样做,则需要服务器B接收数据包。

  • 如果服务器A在服务器B的同一个局域网上有一个地址C,那么这相对容易。在服务器B上: ip route replace default via C ,或者ip route add default via C table a; ip rule add from 2.2.2.3 table a ip route add default via C table a; ip rule add from 2.2.2.3 table a
  • 否则,你必须做一些隧道的事情。

但是,如果服务器B的位置的路由器不是特别复杂(有状态地检查数据包并拒绝那些对于已知业务stream不正确顺序的数据包),则可能会有一个更简单的方法,即超级难看的选项:在服务器B的基础上,你知道在服务器A上完成了什么:在服务器B上iptables -t nat -I POSTROUTING -j SNAT -s 2.2.2.3 --to 1.1.1.3应该做这个build议的例子。 这将使A和B的Linux连接跟踪系统有些混乱(服务器将无法将返回stream量与传入stream量相关联,因此它们的连接跟踪将使连接处于UNREPLIED状态),但对于大部分stream量进入数百兆。

在这种情况下,最后一次穿过交通stream量:

  1. 客户端X发送一个数据包到1.1.1.3。
  2. 服务器A将该数据包的目的地址转换为2.2.2.3预路由,然后将数据stream路由到2.2.2.3,但将数据包发送到服务器B时将源地址保留为X.
  3. 服务器B收到2.2.2.3的数据包,看到X的源地址,它处理数据包并将应答路由回源X,但在发送出去之前,源地址的路由后NAT转换为1.1.1.3 。
  4. 客户端X收到来自1.1.1.3的回应,很高兴。

既然你希望你的服务器像一个路由器那样工作,你需要检查几件事情:

首先,必须在内核中启用数据包转发(默认情况下不是):

 echo "1" > /proc/sys/net/ipv4/ip_forward 

您还需要确保iptables允许转发stream量(查看您的FORWARD链)。

这和DNAT规则应该足以使数据包在一个方向上stream动。 但是,如果你需要一个TCPstream,你还必须确保你也有你提到的SNAT规则(否则,远程主机会认为有问题,因为2.2.2.3的服务器正在回复他发送的数据包如1.1.1.3)。

顺便说一句,出于性能的原因,如果你有静态的IP,最好使用SNAT来代替MASQUERADE。