如何将端口从一台机器转发到另一台机器?

如何将端口从一台机器转发到另一台机器?

考虑以下情况:

在我家里,我有一个路由器(连接到互联网)、服务器(S)和我的主机(M)。 S 可以通过互联网访问(它有静态 IP),并且 24/7 都在线,而 M 则不能。

有时,我想让一些应用程序(监听 M 上的某个端口,例如 8888)可以从外部互联网访问。

为此,我想在 S (2222) 上设置一些端口以转发到 M 的端口 8888,以便任何访问 S:2222 的人都会感觉他正在访问 M:8888。

我尝试使用 ssh 端口转发,我的最佳尝试如下:

ssh -L 2222:M:8888 -N M

但这只允许我从服务器本身访问2222端口,而不能从其他机器访问2222端口。

有什么方法可以正确地做到这一点吗?最好,我希望它是一个简单的命令,当我不再需要该转发时,我可以使用 ^C 启动和关闭它。

答案1

是的,这GatewayPorts在 SSH 中是这样调用的。摘录自ssh_config(5)

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

如果我正确理解你的问题,你可以在转发中使用localhost而不是,因为你转发到的机器与你使用 SSH 的机器相同。M

所以,命令将变成这样:

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

并且看起来像这样netstat -nltp

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

现在,任何通过 TCP 端口 2222 访问该计算机的人实际上都会与 localhost:8888 进行通信,如计算机 M 中所示。请注意,这与普通转发到 M 的端口 8888 不同。

答案2

还有另一种方法。您可以使用 iptables 设置从 S:2222 到 W:8888 的端口转发。单个命令:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

其中 1.2.3.4 是 M 的 IP 地址。它称为 NAT(网络地址转换)。

答案3

更多替代方案:(netcat传统)或socat

在服务器(S)上:

socat tcp-listen:2222,reuseaddr,fork tcp:M:8888

或者

nc -l -p 2222 -c 'nc M 8888'

详情见: 创建从一个本地端口到另一个本地端口的隧道的简单方法?

答案4

简洁回答

原始命令大部分都很好,但它没有指定要侦听的地址,这导致进程127.0.0.1默认侦听。

将命令从ssh -L 2222:M:8888 -N M更改为ssh -L S:2222:M:8888 -N M,它应该可以正常工作。

详细解答

-L您遇到的问题是由于在“localPort:remoteHost:remotePort”中使用短符号引起的。

如果您使用它,ssh请收听127.0.0.1

例如:

ssh -L 2222:M:8888 -N M

将导致类似这样的结果(注意正在监听的地址):

sudo netstat -nlp | grep 2222
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN      16208/ssh

如果您使用完整符号(“localAddress:localPort:remoteHost:remotePort”):

ssh -L external-address-of-S:2222:M:8888 -N M

会导致类似的结果

sudo netstat -nlp | grep 2222
tcp        0      0 external-address-of-S:2222          0.0.0.0:*               LISTEN      16208/ssh

PSGatewayPorts是一种更通用的解决方案,但如果您的服务器有多个 IP 地址,它的行为会有所不同。该解决方案允许您选择要侦听的 IP(并允许您将不同 IP 上的相同端口转发到不同的目的地),同时GatewayPorts侦听所有 IP 并将它们转发到同一目的地。哪一种更适合您取决于您​​的要求 - 但两者都适合 OP。

PPS 我意识到这是一个非常古老的问题,但它在今天仍然非常相关(可能由于云的广泛使用而更重要),并且我相信它缺少一个简单的答案,可以帮助遇到类似问题的人。

相关内容