如何在同一网络中将端口从一个IP转发到另一个IP?


77

我想做些NAT在iptables。这样,所有到达192.168.12.87port 的数据包都80将转发到192.168.12.77port 80。

iptables如何做到这一点?

要么

还有其他方法可以达到相同目的吗?


@Matthewlfe,由于某种原因,我需要将所有apache请求从(192.168.12.87)转发到(192.168.12.77)。
— 2014年

1
@Matthewlfe,我有两个生产服务器。一个连接到公共静态IP地址。由于某些连接问题,我无法从连接到DB和其他系统192.168.12.87。因此,我需要将所有请求转发给192.168.12.77。
— 2014年

@lain,我不熟悉iptables。而且,我看到了一些例子。但是,似乎需要两个以太网。链接:revsys.com/writings/quicktips/nat.html
— 坐在

您还可以在Web服务器配置中使用代理模式将请求从192.168.12.87发送到192.168.12.77(如果您的网络服务器支持)
— krisFR 2014年

Answers:


74

假设这些规则iptables在服务器上运行,则它们应该起作用192.168.12.87:

#!/bin/sh

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

iptables -F
iptables -t nat -F
iptables -X

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77:80
iptables -t nat -A POSTROUTING -p tcp -d 192.168.12.77 --dport 80 -j SNAT --to-source 192.168.12.87

您必须在端口80上对进入的流量进行DNAT,但是还需要将流量SNAT回去。


替代方法(最佳方法恕我直言):

根据您的Web服务器是什么(Apache,NGinx),您应该考虑在前端服务器(192.168.12.87)上使用HTTP代理:


只要禁用了ufw,就可以工作,即使在ufw中允许了端口,但是如果启用了ufw,则此转发功能无效,您知道吗?
— Sudhir N

1
好问题,好答案。另一个有用的用例是,如果您需要临时将进入某个服务(例如鱿鱼)的所有流量重定向到另一个IP /端口,以便对原始服务进行一些维护,而无需重新配置所有客户端!非常便利!
— PF4Public

3
“但是您还需要将流量SNAT回传。” ->你救了我的一天。谢谢
— obayhan

此解决方案不适用于我。我需要从eth0转发到KVM来宾使用的虚拟网络(virb0)。我尝试添加-i和-o选项,但是-o不允许进行预路由。有什么建议么?
— lostiniceland '17

请谨慎使用此解决方案。我现在完全无法访问我的远程计算机。
— 索伦

28

看似不明显的原因iptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77是返回数据包将如何路由。

您可以设置规则,使发送到192.168.12.87的数据包被简单地NAT到192.168.12.77,但是192.168.12.77然后会将回复直接发送回客户端。这些答复不会通过您的iptables规则进行NAT的主机,因此,一个方向的数据包将被转换,而另一个方向的数据包则不会。

有三种方法可以解决此问题。

  1. 在第一台主机上,不仅要进行DNAT,还要进行SNAT,这样返回流量将通过第一台主机发回。该规则可能看起来像iptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87
  2. 从DSR负载平衡和DNAT数据包中获取灵感,这些数据包是在以太网层而不是IP层。通过将数据包的目标MAC替换为192.168.12.77的MAC,并在以太网上发送而不接触IP层,则192.168.12.77可以在虚拟接口上配置192.168.12.87,从而能够终止TCP连接客户端知道的服务器IP。
  3. 在第一台主机上使用幼稚(但不起作用)的解决方案。然后通过对返回流量进行SNAT处理第二个主机上的返回数据包。规则看起来像iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87

这三个解决方案中的每一个都有缺点,因此,如果确实需要执行此特定转发,则需要仔细考虑。

  1. 使用SNAT将丢失客户端IP,因此2号主机将认为所有连接都来自192.168.12.87。此外,您将使用主机号1的带宽用于所有答复数据包,这将与其他方法相比采用更直接的路由。
  2. DSR方法将破坏两个节点之间的所有其他通信。DSR方法实际上仅在服务器地址不是任何主机的主IP时才适用。每个主机都需要有一个主IP,而不是DSR IP。
  3. 在一个主机上使用连接跟踪在一个方向上进行转换,而在另一主机上使用连接跟踪在另一个方向上进行转换,这很丑陋,并且有多种方式可以破坏它。例如,如果任一主机上的端口号都被NAT修改,则无法重建端口号。同样不明确的是,如果连接跟踪看到的第一个数据包是SYN-ACK而不是ACK,则它将正确运行。

我认为这三种方法中的第一种是最可能有效的一种。因此,如果您不需要知道客户端IP地址,那就是我推荐的地址。

您也可以选择完全忽略NAT,而不尝试解决MAC或IP层上的问题。您可以一直进行到HTTP层并在那里寻找解决方案。在这种情况下,您将找到一个HTTP代理解决方案。如果您在192.168.12.87上安装HTTP代理并进行了适当配置,则可以让它将请求转发到192.168.12.77并转发回答案。另外,它可以插入保留原始客户端IP的X-Forwarded-For标头。然后,需要将192.168.12.77上的服务器配置为信任来自192.168.12.87的X-Forwarded-For标头。


我很惊讶-j MASQUERADE这里没有提到;这不是DNAT常用的方法吗?
— remram

3
我提到的@remram SNAT而不是MASQUERADE,因为这就是文档所说的。文档中的确切措辞为:It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
— kasperd 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.