使用 autossh 进行快速内网穿透


一、前言

总所周知,现在国内的普通宽带普遍都使用了内网 IP 地址。

如果想要搭建服务器,一般来说要么直接在云主机上搭建,要么在本地搭建然后借助云主机进行内网穿透。

由于云主机上存储空间的价格一般都比较昂贵,所以大多数人还是会选择内网穿透。

一说到搭建内网穿透服务器,可能大多数人(包括我)第一反应都是使用 Ngrok。

Ngrok 确实是一个很好的内网穿透全套解决方案,但是配置和管理都比较复杂,而且现在新版的 Ngrok 也已经开始商业化(闭源)了。

我一开始也是打算使用 Ngrok,但是弄了好久都不成功。结果在探索途中突然发现了 autossh 这玩意,顿时豁然开朗。我怎么就把 SSH 这么好的功能给忘了……

⚠️ 注意
• SSH 仅支持 TCP 端口映射。

autossh 使用了系统原生的 SSH 端口映射功能,性能开销非常小。

autossh 的配置也极其简单,只需要在服务器和客户端上进行少许的配置即可完成内网穿透。

本文纯属个人学习经验分享,仅供参考。如有错误请及时提出,谢谢!


二、操作环境

  • 服务器:CentOS 7.4.1708(最小安装、关闭防火墙)
  • 客户端:CentOS 7.4.1708

三、服务器的配置

3.1 配置 SSH 服务器

请使用 vim 之类的文本编辑器打开 /etc/security/limits.conf

找到包含 GatewayPorts 字符串的这一行,然后将这一行改为:

GatewayPorts clientspecified

也可以直接在文件末尾添加上面这一行。

接下来检查一下包含 PubkeyAuthentication 字符串的这一行,确定该行内容为:

PubkeyAuthentication yes

(不是的话请手动修改)

修改、检查完成之后请保存文件。

该步骤的目的是允许客户端指定服务器内网穿透服务监听的端口,以及确认允许客户端使用密钥登录。

3.2 重启 SSH 服务

systemctl restart sshd

四、客户端的配置

4.1 安装 autossh 软件包

yum -y install autossh

4.2 生成 SSH 密钥,并上传至服务器

请移步我写的另一篇文章。

SSH 设置密钥对实现免密码连接

4.3 启动内网穿透

命令常用方法

autossh [-p <服务器 sshd 监听端口>] -M 0 -fN \
-o "PubkeyAuthentication=yes" \
-o "ServerAliveInterval 5" \
-o "ServerAliveCountMax 6" \
-o "ConnectTimeout=10" \
[-o ProxyCommand="nc --proxy-type http|socks4|socks5 --proxy <代理服务器地址>:<代理服务器端口> %h %p"] \
-R <远程服务器监听 IP>:<远程服务器监听端口>:<要映射服务的 IP>:<要映射服务的端口> \
[-R <远程服务器监听 IP>:<远程服务器监听端口>:<要映射服务的 IP>:<要映射服务的端口> ...] \
<服务器用户名>@<服务器 IP/域名>

注:可在同一 SSH 进程中映射多组端口。

选项 说明
-p <服务器 sshd 监听端口> 配置服务器 SSH 服务的监听端口。
-M 0 不使用 autossh 自带的监控功能,只有当 ssh 进程退出时才会重新建立 ssh 连接。
-fN 不在服务器上执行任何命令,仅用作端口转发。
-o "PubkeyAuthentication=yes" 使用密钥对进行认证。
-o "PasswordAuthentication=no" 禁止使用密码认证。
-o "ServerAliveInterval 5" 客户端每隔 5 秒发送一个心跳包。
-o "ServerAliveCountMax 6" 连续 6 个心跳包没回应视为连接丢失。
-o "ConnectTimeout=10" 如果 SSH 进程不能在 10 秒内建立连接则自动退出。用于防止网络不好而导致的 SSH 进程假死。
-o ProxyCommand="nc --proxy-type http|socks4|socks5 --proxy <代理服务器地址>:<代理服务器端口> %h %p" 透过代理服务器建立 SSH 连接。支持 SOCKS4、SOCKS5 及 HTTP 协议。(如果连接的是国外云主机强烈推荐使用)

举例说明

把本地的 80 端口映射到服务器上的 8080 端口,且服务器上的所有接口都要监听 8080 端口。

autossh -M 0 -fN \
-o "PubkeyAuthentication=yes" \
-o "ServerAliveInterval 5" \
-o "ServerAliveCountMax 6" \
-o "ConnectTimeout=10" \
-R 0.0.0.0:8080:127.0.0.1:80 \
[email protected]

执行完 autossh 命令之后,系统就会一直维护这条映射条目,您就可以高枕无忧了!哪怕是网络不稳定,或者说服务器宕机重启了,在恢复正常的时候映射都会自动恢复。

启动 autossh 之后,可以看到一个 ssh 的子进程,这个子进程才是真正在执行端口映射的 SSH 进程。

如果想立即终止 autossh 并取消端口映射,可以使用 kill -9 命令直接杀死 autossh 进程。

如果想配置开机自动映射,直接把一整条命令写进 /etc/rc.local 文件即可,非常方便。


五、总结 & 注意事项

如果需要映射的端口不多,只有几个的话,autossh 确实是最佳选择。

但是如果需要映射大量端口,建议还是使用类似 Ngrok 的端口映射工具,毕竟这类工具拥有比较完善的管理功能。

⚠️ 还有一点非常重要 ⚠️

鉴于目前的网络形势,如果需要把端口映射到国外的云主机上,那么我强烈建议把 SSH 流量封装到其它安全的协议中!

否则,一旦 SSH 的流量稍微一大,就非常容易导致云主机的 IP 无法访问。

具体实现方法我这里就不说了,请大家自行摸索,免得惹麻烦。

发表评论

电子邮件地址不会被公开。