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


77

我想做些NATiptables。这样,所有到达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.