使用SSH反向隧道进行内网穿透
2017-11-12 16:52
218 查看
使用SSH反向隧道进行内网穿透
这篇文章主要介绍了如何利用SSH 反向隧道穿透NAT,并演示了如何维持一条稳定的SSH 隧道。假设有机器A 和B,A 有公网IP,B 位于NAT 之后并无可用的端口转发,现在想由A 主动向B 发起SSH 连接。由于B 在NAT 后端,无可用公网IP + 端口 这样一个组合,所以A 无法穿透NAT,这篇文章应对的就是这种情况。
首先有如下约定,因为很重要所以放在前面:
机器代号 | 机器位置 | 地址 | 账户 | ssh/sshd 端口 | 是否需要运行sshd |
---|---|---|---|---|---|
A | 位于公网 | a.site | usera | 22 | 是 |
B | 位于NAT 之后 | localhost | userb | 22 | 是 |
C | 位于NAT 之后 | localhost | userc | 22 | 否 |
systemd,如果你使用其他的init
程序,如果没有特殊理由还是换到一个现代化的GNU/Linux 系统吧……
SSH
反向隧道
这种手段实质上是由B 向A 主动地建立一个SSH 隧道,将A 的6766 端口转发到B 的22 端口上,只要这条隧道不关闭,这个转发就是有效的。有了这个端口转发,只需要访问A 的6766 端口反向连接B 即可。首先在B 上建立一个SSH 隧道,将A 的6766 端口转发到B 的22 端口上:
1 | B $ ssh -p 22 -qngfNTR 6766:localhost:22 usera@a.site |
1 | A $ ssh -p 6766 userb@localhost |
隧道的维持
稳定性维持
然而不幸的是SSH 连接是会超时关闭的,如果连接关闭,隧道无法维持,那么A 就无法利用反向隧道穿透B 所在的NAT 了,为此我们需要一种方案来提供一条稳定的SSH 反向隧道。一个最简单的方法就是
autossh,这个软件会在超时之后自动重新建立SSH
隧道,这样就解决了隧道的稳定性问题,如果你使用Arch
Linux,你可以这样获得它:
1 | $ sudo pacman -S autossh |
autossh来维持:
1 | B $ autossh -p 22 -M 6777 -NR 6766:localhost:22 usera@a.site |
-M参数指定的端口用来监听隧道的状态,与端口转发无关。
之后你可以在A 上通过6766 端口访问B 了:
1 | A $ ssh -p 6766 userb@localhost |
隧道的自动建立
然而这又有了另外一个问题,如果B 重启隧道就会消失。那么需要有一种手段在B 每次启动时使用autossh来建立SSH
隧道。很自然的一个想法就是做成服务,之后会给出在
systemd下的一种解决方案。
“打洞”
之所以标题这么起,是因为自己觉得这件事情有点类似于UDP 打洞,即通过一台在公网的机器,让两台分别位于各自NAT 之后的机器可以建立SSH 连接。下面演示如何使用SSH 反向隧道,让C 连接到B。
首先在A 上编辑
sshd的配置文件
/etc/ssh/sshd_config,将
GatewayPorts开关打开:
1 | GatewayPorts yes |
sshd:
1 | A $ sudo systemctl restart sshd |
autossh指令略加修改:
1 | B $ autossh -p 22 -M 6777 -NR '*:6766:localhost:22' usera@a.site |
端口SSH 连接到B:
1 | C $ ssh -p 6766 userb@a.site |
最终的解决方案
整合一下前面提到的,最终的解决方案如下:首先打开A 上
sshd的
GatewayPorts开关,并重启
sshd(如有需要)。
然后在B 上新建一个用户autossh,根据权限最小化思想,B
上的
autossh服务将以autossh 用户的身份运行,以尽大可能避免出现安全问题:
12 | B $ sudo useradd -m autosshB $ sudo passwd autossh |
密钥,并上传到A:
123 | B $ su - autosshB $ ssh-keygen -t 'rsa' -C 'autossh@B'B $ ssh-copy-id usera@a.site |
ssh-keygen指令时尽管一路回车,不要输入额外的字符。
然后在B 上创建以autossh 用户权限调用
autossh的service
文件。将下面文本写入到文件
/lib/systemd/system/autossh.service,并设置权限为644:
123456789101112131415 | [Unit]Description=Auto SSH TunnelAfter=network-online.target[Service]User=autosshType=simpleExecStart=/bin/autossh -p 22 -M 6777 -NR '*:6766:localhost:22' usera@a.site -i /home/autossh/.ssh/id_rsaExecReload=/bin/kill -HUP $MAINPIDKillMode=processRestart=always[Install]WantedBy=multi-user.targetWantedBy=graphical.target |
network-online.target生效:
1 | B $ systemctl enable NetworkManager-wait-online |
systemd-networkd,你需要启用的服务则应当是
systemd-networkd-wait-online。
然后设置该服务自动启动:
1 | B $ sudo systemctl enable autossh |
1 | B $ sudo systemctl start autossh |
1 | A $ ssh -p 6766 userb@localhost |
1 | C $ ssh -p 6766 userb@a.site |
1 | C $ ssh -p 6766 -qngfNTD 7677 userb@a.site |
7677的
sock4本地(localhost)代理后,你就可以在家里的浏览器上看到公司内网的网页。
本文标题:使用SSH反向隧道进行内网穿透
文章作者:I&ME
发布时间:2016-02-17, 18:09:57
最后更新:2016-12-02, 00:03:54
原始链接:https://arondight.github.io/2016/02/17/使用SSH反向隧道进行内网穿透/
许可协议: "署名-非商用-相同方式共享
4.0" 转载请保留原文链接及作者。
相关文章推荐
- 使用SSH反向隧道进行内网穿透
- 使用SSH反向隧道进行内网穿透
- 使用SSH反向隧道进行内网穿透(远程端口转发)
- 使用SSH反向隧道进行内网穿透
- SSH反向隧道进行内网穿透
- 内网穿透系列——SSH反向隧道 (最简单的内网穿透方案)
- autossh SSH反向隧道使用
- 在使用 bitvise SSH client时,进行隧道S2C端口映射时,远程主机外网不能访问问题。
- Ubuntu SSH反向隧道从外网连接内网
- 利用SSH反向隧道搭建远程协助平台
- 使用配置方式进行ssh的整合以及管理员管理的案例(二)
- 使用pd 进行数据的反向工程
- 使用ssh过程中对数据库进行update时报错
- Ubuntu 无法使用 root 用户进行 SSH 登录
- 使用PowerDesigner 15对现有数据库进行反向工程(图解教程一)
- 使用PowerDesigner 15对现有数据库进行反向工程
- SSH隧道与端口转发内网穿透
- 系统管理工具包: 使用 SSH 进行分布式管理
- Ansible安装完后使用ssh进行连接测试