![通过 SSH 访问 NAT 路由器后面的办公室主机](https://linux22.com/image/1274051/%E9%80%9A%E8%BF%87%20SSH%20%E8%AE%BF%E9%97%AE%20NAT%20%E8%B7%AF%E7%94%B1%E5%99%A8%E5%90%8E%E9%9D%A2%E7%9A%84%E5%8A%9E%E5%85%AC%E5%AE%A4%E4%B8%BB%E6%9C%BA.png)
我想从家里访问办公室 Linux 主机的 ssh 端口。不幸的是,主机位于 NAT 路由器后面。因此,IP 地址不公开。但是可以访问另一个互联网主机(服务器),不幸的是,只有非 root 访问权限。搜索了一段时间后,我找不到合适的解决方案。
按照以下设置:
- 办公室 PC(Linux,根访问权限)位于 NAT 后面(IP 非公开),但可以完全访问互联网。
- 服务器 PC(Linux,无根访问权限)静态和公共 IP 以及完全的互联网访问权限。
- 家用电脑(Linux,root 访问权限)位于 NAT 后面(IP 非公开),但可以完全访问互联网。
可能的连接:办公室电脑 --> 服务器 <- 家用电脑
不可能:办公室电脑<-X-服务器-X->家用电脑
家庭 PC 和服务器都无法启动对办公室 PC 的访问。但办公室 PC 和家庭 PC 都可以启动与服务器的连接。
反向 SSH 隧道无法使用:我尝试了一种称为反向 ssh 隧道的方法。不幸的是,这需要在 /etc/ssh/sshd_config 中将服务器上的 GatewayPorts 设置为“是”,而我没有 root 访问权限。
原则上应该是可能的:
0)在服务器上我启动一个用户空间程序,监听 2 个端口(1 个传入,1 个传出)
1)在我的办公室电脑上,我运行了另一个程序,该程序保持与服务器上的传出端口的 TCP 连接开放。
2)我从家里连接到服务器的传入端口。
应该有一个标准的解决方案来解决这个问题。
解决这个问题最快、最干净的解决方案是什么?
坦率
答案1
youatwork@officepc$ autossh -R 12345:localhost:22 notroot@serverpc
之后:
you@homepc$ autossh -L 23456:localhost:12345 notroot@serverpc
you@homepc$ ssh youatwork@localhost -p 23456
您可以这样做:在步骤 1 中,将远程端口从办公室 PC 转发到服务器(12345
用作示例,任何大于 1024 的端口都可以)。现在连接到服务器上的 12345 应该会将您连接到办公室 PC 上的端口 22。
在步骤 2 中,将家庭计算机的端口 23456 转发到服务器上的 12345(然后转发到 officepc:22,如步骤 1 中设置的那样)
在步骤 3 中,您连接到本地端口 23456使用办公室电脑登录。步骤 2 会将其转发到您服务器上的端口 12345,步骤 1 会将其转发到您办公室的 PC。
请注意,我使用 autossh 进行转发,因为它是一个 ssh 包装器,如果隧道断开连接,它会自动重新连接;但是,只要连接不断开,普通 ssh 也可以工作。
存在一个可能的漏洞:任何能够连接到 serverpc 上的 localhost:12345 的人现在都可以连接到 officepc:22,并尝试入侵它。(请注意,如果您正在运行 SSH 服务器,无论如何都应该将其保护在默认启用的基本保护之上;我建议至少禁用 root 登录并禁用密码验证 - 参见例如这)
编辑:我已经使用相同的配置验证了这一点,并且它有效。GatewayPorts no
仅影响向全世界开放的端口,而不影响本地隧道。以下是转发的端口:
homepc:
outgoing ssh to serverpc:22
listening localhost:23456 forwarded through ssh tunnel
serverpc:
listening ssh at *:22
incoming localhost ssh tunnel (from homepc) forwarded to localhost:12345
listening localhost ssh tunnel (from officepc) forwarded from localhost:12345
officepc:
outgoing ssh to serverpc:22
incoming localhost through ssh tunnel (from serverpc) forwarded to localhost:22
因此,就网络堆栈而言,它们都是各自环回接口上的所有本地流量(加上 ssh 连接到serverpc);因此,GatewayPorts
根本没有检查。
但是,有指令AllowTcpForwarding
:如果是no
,则此设置将失败,因为根本不允许转发,甚至不允许通过环回接口转发。
注意事项:
如果使用 autossh 和最近的 ssh,您可能需要使用 ssh
ServerAliveInterval
和ServerAliveCountMax
保持隧道畅通。Autossh 有一个内置检查,但显然它在 Fedora 上存在一些问题。-M0
禁用它,并-oServerAliveInterval=20 -oServerAliveCountMax=3
检查连接是否畅通 - 每 20 秒尝试一次,如果连续失败 3 次,则停止 ssh(autossh 会创建一个新的):autossh -M0 -R 12345:localhost:22 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc autossh -M0 -L 23456:localhost:12345 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
如果转发失败,重新启动 ssh 隧道可能会很有用,使用
-oExitOnForwardFailure=yes
- 如果端口已经绑定,您可能会获得有效的 SSH 连接,但没有转发的隧道。建议使用
~/.ssh/config
选项(和端口),否则命令行会变得太冗长。例如:Host fwdserverpc Hostname serverpc User notroot ServerAliveInterval 20 ServerAliveCountMax 3 ExitOnForwardFailure yes LocalForward 23456 localhost:12345
然后您就可以使用服务器别名:
autossh -M0 fwdserverpc
答案2
如果你能从家里通过 ssh 连接到内部服务器,并从内部服务器连接到办公室的 Linux 机器,那么在家里你就可以使用 ssh通过(netcat)ProxyCommand
悄悄地从服务器反弹到内部机器nc
# ~/.ssh/config on your home machine:
Host internalpc
ForwardAgent yes
ProxyCommand ssh [email protected] exec nc internal.pc.example.com %p
然后,您只需ssh user@internalpc
通过服务器机器默默地转发,无需在任何一端打开端口或隧道。
答案3
在您想要远程访问 SSH 的计算机上安装 Robo-TiTO。
- 这将允许您在任何地方使用 Google Talk 客户端应用程序访问 SSH。
- 无需公共 IP 地址或特殊设置。
- 它是免费和开源的,不再支付任何应用服务。
- 无需打开SSH端口(保证您的计算机安全)。
- 无需打开任何隧道(例如 VPN 或类似的东西)
由于网站已迁移,以下安装说明已过时。新 URL 为https://github.com/formigarafa/robotito
我编写了一个脚本(在 Raspberry Pi 上的 Raspbian 操作系统上进行了测试),以便您可以轻松地在 Raspberry Pi、Debian 或 Ubuntu Box(Debian 软件包分发版)上安装 Robo-TiTO。这是让您的 Linux 机器可远程控制的步骤:
打开 Shell 命令或者您可以称之为终端,转到您的主文件夹,通过命令下载安装程序脚本:
$ wget https://opengateway.googlecode.com/files/robotito
然后通过输入命令运行脚本:
$ sudo ./robotito
然后你就可以
credentials.rb
用你的 GTalk 账户编辑 Robo-TiTO 的配置文件夹中的文件,然后按Ctrl+X和保存Y。默认使用 nano 编辑器。通过命令从 Robo-TiTO 文件夹运行 Robo-TiTO
$ cd robotito $ ./jabbershd start
现在,您可以从任何 Google talk 客户端使用 SSH。不要忘记将 Robo-TiTO GTalk 帐户添加到您的 Google talk 帐户,并在使用该帐户之前通过聊天进行测试。
答案4
对我来说,听起来你应该尝试使用 VPN,而不是 SSH 隧道:那种通过使用外部服务器进行代理的 VPN,例如鰤鱼。还有其他类似的免费软件,但我最喜欢的是 Hamachi。