在网关上使用 iptables 进行端口转发

在网关上使用 iptables 进行端口转发

我的本地网络中有一台 Linux 机器,我将其用作网关,因此我的所有网络流量都会通过它(该机器只有一个网络接口,我将其用于传入和传出流量)。我需要转发端口上传入的所有 HTTP 包7080前往港口80。此外,我想将 HTTP 响应重定向回发送请求的客户端。

我尝试使用以下 iptables 规则来实现这一点:

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7080 -j ACCEPT
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

iptables -t nat -A OUTPUT -p tcp --dport 7080 -j REDIRECT --to-ports 80
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 7080

当这些规则处于活动状态时,我不会在客户端上收到任何 HTTP 响应。

有人知道我做错了什么,或者我该如何解决这个问题?

答案1

您应用了错误的链。收到的数据包首先由 PREROUTING 处理;如果它们被识别为要发送到“这台”机器,则交给 INPUT,否则交给 FORWARD 和 POSTROUTING。OUTPUT 链仅适用于生成本地。iptables 教程有一个精彩篇章关于这一点。

基于示例互联网上的其他地方,为了回答您提出的问题,您可能只需要这样做:

# Packets that arrive for port 7080 should be redirected to port 80
iptables -t nat -A PREROUTING -p tcp --dport 7080 -j REDIRECT --to-ports 80

# Separately, all packets that leave this machine that go to port 80
# (which will include the ones redirected above) should be masqueraded,
# i.e. use NAT:
iptables -t nat -A POSTROUTING -p tcp --dport 80 -j MSAQUERADE

我非常确定你想要做的事情会更复杂,尤其是因为你实际上并没有说你想在哪个方向发生这种情况。如果你真正想做的只是设置一个端口转发,这样你的外部 IP 地址(假设它是 251.112.112.42)在互联网上看起来就像它有一个在端口 7080 上运行的网络服务器 - 但你实际上是从端口 80 上的内部机器(假设是 192.168.42.1)提供服务。这也很容易,只是不同,甚至更接近已经提到的例子

# Anything sent to your external IP:port gets redirected to the internal one:
iptables -t nat -A PREROUTING -d 251.112.112.42/32 -p tcp --dport 7080 \
    -j DNAT --to-destination 192.168.42.1:80

# Make sure those connections actually work, by rewriting everything back,
# again simply using NAT:
iptables -t nat -A POSTROUTING -d 192.168.42.1 -p tcp -dport 80 -j MASQUERADE

答案2

INPUT 仅表示将由您的用户空间处理的数据包。

您不应使用 INPUT,而应使用 nat 表中的 PREROUTING 链。

tcpdump 对于调试数据包到底发生了什么非常有用。

答案3

您必须对 tcp 数据包进行 3 项更改:SourceNAT、DestinationNAT 和端口更改。不允许对同一数据包进行此操作。但您可以使用第三方应用程序(如 nginx)并简单地通过此应用程序重定向数据包。

相关内容