发布于

使用 SSH 隧道访问云服务器内网服务

作者

去年 11 月底趁着腾讯云服务器打折,以 45 元/年的超级白菜价购入了一台 双核、4G、8M 的腾讯云轻量应用服务器(后来腾讯云免费给 CPU 升配到了 4 核),平时主要拿来部署博客、数据库以及一些自己写的接口。云服务器在公网上暴露端口具有很大的安全隐患:有无数多的机器人在扫描各个公网服务器上的端口,稍有不慎服务器就会被盯上。考虑到自己不是专业运维,也不想花太多时间精力关注服务器平时的安全问题,就索性把大部分服务锁在服务器内网里,部分经常访问的服务和接口通过 frp 暴露出来,平时需要使用的时候只需要本地开启 frp 客户端连接服务器即可,安全性较高。

frp 的方案虽好,但是不够“轻量” —— 访问云服务器上的内网服务需要在本地开启 frp 客户端服务,有些临时使用的设备可能本身没有安装 frp 客户端程序,想要访问服务可能还需要在本地再配置一次 frp。此外,每次想要在服务器上暴露一个新的服务还需要再去修改服务器上的 frp 配置。这套流程对于我这种比较简单的需求而言,显得比较麻烦。

SSH 端口转发

SSH 给人的一种刻板印象是只能用来安全登陆远程服务器,而实际上,SSH 还利用其本身建立的安全连接隧道向外提供了端口转发功能。使用 SSH 的端口转发功能非常容易,只需要在原本的 SSH 连接命令的基础上提供本地端口和远程服务器端口对应的映射关系即可:

ssh -L [LOCAL_IP:]LOCAL_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER

其中 -L 用来指定映射关系,LOCAL_PORT 为本机端口号,DESTINATIONDESTINATION_PORT 分别是目标服务器和其对应的服务端口号。

假如我想要将本地 5678 端口映射到服务器 cloud.huohaodong.com (公网 IP 为 114.132.213.30) 在 22220 端口上提供的 MySQL 服务(用户名为 ubuntu),对应的 ssh 命令如下:

ssh -L 5678:114.132.213.30:22220 ubuntu@cloud.huohaodong.com

此外还可以通过修改 ssh 配置文件的方式,使得每次建立对应的 ssh 的同时建立指定的端口映射关系:

Host cloud.huohaodong.com
  HostName cloud.huohaodong.com
  User ubuntu
  LocalForward 22220 127.0.0.1:22220
  LocalForward 22221 127.0.0.1:22221

在上面的配置中,每次用户 ubuntu 成功通过 ssh 连接到 cloud.huohaodong.com 后都会随之建立对应的端口转发映射关系。这里是将所有 ssh 客户端本机的 22220 与 22221 端口的请求转发到服务器本机的 22220 与 22221 端口。

配置文件中的 127.0.0.1 表明是将请求转发到服务器本机对应的端口中,如果服务器本身是作为跳板机使用,则需要将 127.0.0.1 替换为对应的服务器地址。

此时只需要通过 ssh SSH_SERVER 连接对应的服务器即可建立端口转发关系,之后通过相应的命令即可访问到对应的服务:

ssh cloud.huohaodong.com
mysql -u root -h localhost -P 22220 -p

总结

SSH 端口转发的方案非常灵活轻量:1. SSH 几乎内置在所有主流的操作系统中,所有设备都可以默认具备 SSH 连接的能力,大多数情况下无需额外配置;2. SSH 服务在配置“只允许密钥登陆”后,安全性很高;3. SSH 端口转发只需要客户端本地在连接时提供所需要的端口映射关系即可(命令参数或者配置文件),即插即用,而不需要的时候只需关闭当前 SSH 连接即可终止端口映射。

SSH 端口转发仅适用于一般场景,如果端口映射需求比较复杂,则可以考虑使用 VPN 或者 frp 的方案,性能和安全性都有保障,一劳永逸。