学校的网络位于无数重NAT内网中,而且还有各种VPN,所以想要从外网访问十分困难,之前试过各种方法都没成功。今天偶然看到了SSH反向穿透的方法,因为我访问内网服务器主要也是需要SSH连接功能,故此方法可以很好的满足我的需求。此处记录下配置方法。
SSH反向穿透需要有一台有公网IP的服务器作为桥梁,此处将位于多重NAT网络中需要访问的主机称为Target,而将有固定IP的中转服务器称为Server。SSH反向穿透的原理是,Target主动建立与Server间的SSH连接,利用SSH的端口转发功能,将访问Server某端口的数据包转发到Target SSH端口(22端口)上,以此实现间接登陆Target的目的。
假设Server上的转发端口为6766
,使用如下命令在Target上建立与Server间的反向隧道:
1 | ssh -p 22 -fN -R 6766:localhost:22 userServer@Server |
-R
用于定义反向隧道,-fN
用于在建立SSH连接后SSH进入后台运行。
之后需要在Server上打开sshd
的GatewayPorts
功能,这样才能实现只登录一次即可连接上Target。修改/etc/ssh/sshd_config
文件,添加下面这行:
1 | GatewayPorts clientspecified |
重启sshd
服务:
1 | service ssh restart |
此时就可以在任意一个终端上使用ssh -p 6766 userTarget@Server
登录到Target上了,需要注意的是,此时使用的用户名、密码、秘钥都应该是Target而不是Server的,只有IP地址或者是域名是Server的。
最后一个问题是,如何保持这个SSH反向隧道的稳定存在,并且实现若Target意外重启后能自动再次建立此反向隧道。解决方法是使用autossh
,并且把它作为一个服务自动启动。
先安装autossh
,之后在/etc/init.d
下建立一个名为autossh
的文件:(以下操作以Ubuntu为例,其他发行版可能会有区别)
1 |
|
-M
参数指定了一个监控端口,和端口转发无关,使用一个无用的端口即可;-i
指定了一个密钥,此处用RSA密钥的方式登陆Server。
保存此文件,并添加执行权限:chmod +x autossh
;注册服务:update-rc.d autossh enable
;最后启动服务:service autossh start
。
可使用sysv-rc-conf
工具查看autossh
服务的开机自启动情况。这样将其作为服务配置好后,就可以实现稳定的SSH反向穿透了,终于可以实现从任何地方自由访问内网主机的目的了~~
最后顺便提一下,SSH转发其实可以承载其他更多的网络服务,这个之后有空再来研究~
参考资料:
如何通过SSH反向隧道,访问NAT后面的Linux服务器?
使用SSH反向隧道进行内网穿透
使用autossh实现反向SSH隧道
ubuntu service的添加和删除
How to use systemctl in Ubuntu 14.04