SSH隧道¶
SSH Tunneling (SSH隧道)也称为SSH port forwarding(SSH端口转发),这是一个非常有用的工具,可以实现类似 Squid父级socks代理 架构中穿透GFW实现多级代理,也可以用一条简单SSH命令(VPN)实现自由翻墙。
SSH提供了一种通过端口转发,可以在SSH智商实现任何TCP/IP端口隧道,也就是应用数据流被定向到加密的SSH连接中,以避免传输过程中被拦截或解密。这种SSH tunneling方式也使得原本不支持加密通讯的应用程序实现了网络加密。

SSH命令行端口转发¶
我在 私有云架构 中需要访问 HPE ProLiant DL360 Gen9服务器 服务器的带外管理 HP服务器iLO技术 ,带外管理采用内部IP地址 192.168.6.254
。要访问这个内部IP地址的 443
端口才能够访问 HP服务器iLO技术 的WEB管理界面。
我采用了旁路的 Jetson Nano 构建SSH端口转发,即 ssh 到 jetson nano 主机上,在这个SSH会话中启用SSH端口转发:
ssh -L 25443:192.168.6.254:443 -N -f huatai@192.168.7.23
这样,当 ssh
到 192.168.7.23
上时,本地主机访问本机回环地址 127.0.0.1
的 25443
端口,就会被SSH tunneling通过 192.168.7.23
转发到远程 192.168.6.254
的 443
端口:
MyDesktop 127.0.0.1:25443 => ssh tunneling => 192.168.7.23 => data forwarding => 192.168.6.254:443
备注
上述SSH命令还使用了2个有用的参数:
-N
不执行远程命令-f
将ssh命令运行在后台
上述 ssh `` 命令输入参数较多,可以通过本地笔记本上的ssh配置文件 ``~/.ssh/config
来完成:
Host jetson
HostName 192.168.7.23
LocalForward 25443 192.168.6.254:443
LocalForward 8443 192.168.6.204:8443
这样实现SSH端口转发只需要简单执行:
ssh jetson
备注
上述配置中共配置了2个端口转发
此外,在配置头部加上 ssh多路传输multiplexing加速 配置,更是如虎添翼,一次ssh登陆就可以保持SSH tunneling持续:
Host *
ServerAliveInterval 60
ControlMaster auto
ControlPath ~/.ssh/%h-%p-%r
ControlPersist yes
StrictHostKeyChecking no
Compression yes
多目标主机端口转发¶
上述SSSH端口转发是针对一台目标主机的端口转发,实际上SSH端口转发可以在一次SSH登陆时同时完成多台目标主机的端口转发。也就是登陆一台堡垒主机,就可以通过不同的端口来访问内网的不同服务器。
举例,在内网中有多台MySQL服务器,每个MySQL服务器都对外使用 3306
端口提供服务,则可以使用以下命令同时开启端口转发:
ssh -L 33061:db1:3306 3306:db01:3306 3308:db02:3306 user@gateway
同样,简单配置一个 ~/.ssh/config
Host multi-db
HostName gateway
LocalForward 33061 db1:3306
LocalForward 33062 db2:3306
LocalForward 33063 db3:3306
远程服务器squid提供给本地局域网¶
在翻越GFW的时候,例如 配置Docker使用代理 为docker容器提供代理服务,但是docker只支持http代理,不支持socks代理,就不能使用方便快捷的 SSH Tunneling: 动态端口转发 。虽然也可以在本地局域网搭建一个 Squid代理服务 ,在墙外服务器上再搭建一个squid,然后通过 SSH隧道 连接两端的squid服务器 ( Squid父级socks代理 ),但是这种方式比较适合大型局域网(本地局域网代理缓存可以大大节约下载带宽),对于偶尔使用的快速构建系统有点过于沉重了。
既然 SSH隧道 能够把本地端口直接转发到远程服务器,那么也就意味着,可以直接使用远程服务器上的 Squid代理服务 : 好处是只需要搭建一次服务器端代理服务器,后续就不用再本地安装了。我在解决 排查X86移动云Kind创建失败 结合 Docker客户端的Proxy 就是这么处理的。
修订
~/.ssh/config
添加:
Host parent-squid
HostName <SERVER_IP>
User huatai
LocalForward 192.168.7.152:3128 127.0.0.1:3128
然后执行ssh命令打通端口转发:
ssh parent-squid
这里 192.168.7.152
是我本地局域网主机的IP地址,提供将 3128
端口转发到 <SERVER_IP>
服务器的 127.0.0.1
接口的 3128
端口(该端口上有squid提供服务)
进阶¶
SSH Tunneling有更为神奇和强大的能力:
SSH Tunneling: 远程服务端口转发 将没有公网IP的内网主机对外提供服务
SSH Tunneling: 动态端口转发 自由访问Internet的利器