如何使ssh隧道向公众开放?


174

好了,回到这个问题,我正在运行命令

ssh -R 8080:localhost:80 -N root@example.com

在Mac上。然而,正在建立隧道的港口并未公开运作。我正在运行一个这样的命令,以便可以在远程计算机上打开本地端口。在远程计算机上的localhost上打开端口时,它确实起作用,但是当我尝试从本地计算机访问远程计算机的公用IP地址时,该端口似乎没有打开。如何将隧道在IP上公开供任何人访问?

编辑:似乎远程方仅在本地主机上绑定,而不是绑定到所有接口。

编辑2:客户端是Mac OS X 10.6,服务器是Linux Mint,但它们都是OpenSSH。


公共IP是什么意思?如果您尝试通过路由器并通过Internet连接到本地计算机,则大多数路由器将不允许这种环回。
harrymc

Answers:


350

如果检查手册页中的ssh,则会发现read的语法为-R

-R [ bind_address:] 端口主机HOSTPORT

bind_address省略时(如您的示例),该端口仅绑定在回送接口上。为了使其绑定到所有接口,请使用

ssh -R \*:8080:localhost:80 -N root@example.com

要么

ssh -R 0.0.0.0:8080:localhost:80 -N root@example.com

要么

ssh -R "[::]:8080:localhost:80" -N root@example.com

第一个版本分别绑定到所有接口。第二个版本创建一个仅IPv4的常规绑定,这意味着该端口可通过IPv4在所有接口上访问。从技术上讲,第三个版本可能与第一个版本相同,但是再次创建一个唯一的绑定::,这意味着该端口可以通过IPv6本机访问,也可以通过IPv4映射的IPv6地址通过IPv4访问(在Windows,OpenBSD上不起作用) 。(您需要使用引号,因为[::]否则可能会被解释为一个问题。)

请注意,如果您使用OpenSSH sshd服务器,则GatewayPorts需要启用服务器的选项(将其设置为yesclientspecified),以使其起作用(检查/etc/ssh/sshd_config服务器上的文件)。否则(此选项的默认值为no),服务器将始终强制端口仅在回送接口上进行绑定。


12
哦,我的天啊!!!我已经做了一百万次!!我只是忘记*了bash中会提供文件而我需要\*
Trevor Rudolph,

4
是的,这就是我一直喜欢的原因0.0.0.0-它仅是IPv4,但大部分时间都会使用它:)
Stefan Seidel

34
GatewayPorts是解决了我的问题。
桑妮

4
GatewayPorts =是(在远程sshd配置上)也为我修复了该问题
Phil_1984_

3
感谢@StefanSeidel,这真是我的“ GatewayPorts是”这一天
karser

37

编辑:

-g 适用于本地转发端口,但是您想要的是反向/远程转发端口,这是不同的。

你想要的是这个

从本质上讲,对example.com设置GatewayPorts=clientspecified/etc/ssh/sshd_config

---先前的(错误的)答案-

使用-g选项。从ssh的手册页:

-g     Allows remote hosts to connect to local forwarded ports.

似乎没有工作...它启动了,但我无法远程连接
Trevor Rudolph

2
尝试netstat -elnpt从单独的tty中运行,以找出哪些端口绑定到了哪个地址。如果没有-g,则应将端口绑定到127.0.0.1:PORT。使用-g,应将其绑定到0.0.0.0:PORT,从而可以远程访问。
snapshoe


2
GatewayPorts=clientspecifiedGatewayPorts clientspecified
Trevor Rudolph

并将其添加到客户端或远程吗?
Trevor Rudolph

14

这是我完成的答案:

我最终将其ssh -R ...用于隧道socat传输,并在此之上将网络流量重定向至127.0.0.1

隧道绑定到127.0.0.1: ssh -R mitm:9999:<my.ip>:8084 me@mitm

socat: mitm$ socat TCP-LISTEN:9090,fork TCP:127.0.0.1:9999

另一种选择是做最重要的是仅本地隧道,但我觉得这是很多

mitm$ ssh -L<mitm.ip.address>:9090:localhost:9999 localhost


我喜欢这样的事实,即我不必处理sshd配置,并且无需sudo就可以完成所有操作。另外,我了解到socat存在。谢谢!
BrutusCat 2014年

+ up,你好先生。我试图告诉ssh绑定到0.0.0.0没有成功..然后看到了*语法,尝试了一下,没有骰子。我想这可能是sshd config上的某种安全功能或不允许的功能。终于看到了这篇文章,并且socat很棒。超级有用,可以把它放在我的后兜里;]
Jaime

10

您也可以使用双向转发,也可以更改/ etc / ssh / sshd_config。

首先转发到远程计算机上环回设备上的临时端口(例如10080),然后在此处使用本地转发将所有接口上的端口10080重定向到80:

ssh -A -R 10080:localhost_or_machine_from:80 user@remote.tld "ssh -g -N -L 80:localhost:10080 localhost"

1
这实际上可以绕过转发规则!
Michael Schubert

喜欢这个解决方案。当您不想更改计算机上的配置时,这是一个很好的解决方法
Grezzo

8

使用“网关端口”选项。

ssh -g -R REMOTE_PORT:HOST:PORT ...

为了使用它,您可能需要GatewayPorts yes在服务器的上添加“ ” /etc/ssh/sshd_config


实际上,这可行。我要做的是将EC2实例用作REST服务器的转发器。这样,我不需要将服务器固定在DMZ中,也不需要公共IP。有趣的是,在我创建的第一个EC2实例中,ssh -R remote_port:localhost:port xxx @ ec2xxx可以正常工作,但是由于某种原因,我后来不得不创建另一个实例,从那时起,我一直得到:连接拒绝了 用tcpdump查看我得到了什么,并且没有太多信息。-g再加上GatewayPorts可以解决问题。
美国东部时间

1

跳转主机是OpenSSH的新增功能。这需要通过SSH访问中间件,但无需其他配置即可工作。

ssh -J root@example.com remoteuser@localhost -p 8080

该命令指示SSH首先连接到root@example.com该计算机,然后再从该计算机以用户名发起到端口8080的连接localhost(即,从跳转主机到远程主机的通道)remoteuser


0

如果您想使用配置~/.ssh/config而不是使用命令行参数,则可以尝试以下操作

Host REMOTE_HOST_NAME RemoteForward \*:8080 127.0.0.1:80

记住要让远程主机的防火墙允许连接到8080,并确保未GatewayPorts/etc/ssh/sshd配置选项设置为no

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.