Shell脚本:使用autossh实现内网穿透
发布时间:

Shell脚本:使用autossh实现内网穿透

在平时的工作生活中,经常有内网穿透的需求。本脚本就使用ssh自带的反向代理功能实现内网穿透,其中autossh只是为了维持反向代理的通道存活。

在平时的工作生活中,经常有内网穿透的需求。本脚本就使用ssh自带的反向代理功能实现内网穿透,其中autossh只是为了维持反向代理的通道存活。

一、内网穿透原理

处于内网中的机器(以下称为机器A, 192.168.1.2)只能被同网段的机器所访问,要实现任意网络访问的话,必须有一台拥有公网IP的机器(以下称为机器B,www.sunhanwu.top)作为桥梁,转发流量,连通内网机器和互联网中想要访问内网的机器(以下称机器C)。 假如机器C想要暴露22端口的服务(sshd服务), 就可以让拥有公网ip的机器B将其3008端口接受的流量转发到机器C的22端口,ssh命令就提供反向代理的功能。

# ssh正向代理
ssh -fCNL [本地主机端口]:localhost:[远程主机端口] [远程主机用户名]@[远程主机ip]
# ssh反向代理
ssh -fCNR [远程主机IP/省略]:[远程主机端口]:[本地主机IP]:[本地主机端口] [远程主机用户名]@[远程主机ip]

正向代理和反向代理的区别:一般来说正向代理指代理服务器代理客户端的请求,而反向代理的是代理服务端的端口监听,提供和服务端类似的服务。

ssh常见的参数含义如下:

  • -f:后台执行
  • -C:允许数据压缩
  • -N:不执行远程指令
  • -R:将远程主机的某个端口转发到本地机器的某个端口
  • -L:将本地的某个端口转发到远程机器的某个端口

例如,首先在内网机器A上执行如下反向代理命令:

ssh -fCNR 7280:localhost:22 root@[远程主机IP]

这个命令的含义是将远程主机的7280端口流量转发到本地的22端口,这样所有向远程主机7280端口发起的请求都会转发都机器A的22端口

仅仅一个反向代理的话其实就足够了, 但是问题是ssh的连接不稳定,长时间无操作的话会自动关闭。所以需要使用autossh来维持这个连接,autossh会发送心跳包,保持长连接的稳定性。 而autossh的操作和ssh基本一样。只是多增加了一个监控端口。

# autossh -M [远程服务器监控端口] -fCNR [远程主机IP/省略]:[远程主机端口]:[本地主机IP]:[本地主机端口] [远程主机用户名]@[远程主机ip]
autossh -M 6280 -fCNR 7280:localhost:22 root@[远程主机IP]

这里占用远程服务器的6280端口作为监控端口

二、使用脚本自动配置反向代理

2.1 修改公网服务器sshd配置

Note: 在使用脚本配置反向代理之前,首先需要修改一下公网服务器sshd的配置,不然配置的反向代理端口在公网服务器上只监听127.0.0.1, 对其他ip不开放。

修改/etc/ssd/sshd_config文件, 将GatewayPorts的注释取消,并且改为yes,之后重启sshd服务即可。

sudo systemctl restart sshd

2.2 配置反向代理

为了提高反向代理的配置效率,我写了一个比较简单的shell脚本,脚本的使用方式如下。

github项目地址在这里,为了防止网络问题无法下载,这里用我的服务器提供下载。

curl https://www.sunhanwu.top/upload/2022/12/autossh.sh -o autossh.sh
chmod +x autossh.sh
./autossh.sh

执行后需要填写如下的参数: 其中公网服务器域名是机器B的IP或者域名,代理端口是机器A要代理的端口。这里配置的就是使用公网服务器的9000端口代理内网机器的8080端口。 另外,如果是全新的机器的话,脚本会自动创建密钥对,配置免密登录,安装autossh等。如果已经存在代理进程,可以选择重启该任务或者退出当前脚本。