SSH tunneling 有两种功能:
- Local port forwarding,一般讲 port forwarding 是指这个
- Remote port forwarding,也称 reverse tunnel
它们被用来 bypass 某些防火墙策略。简单来讲:
Local port forwarding:
- 你想访问 B server 的某个端口,但是被防火墙挡住了
- 你有通过 SSH 访问 A server 的能力,同时 A server 可以访问 B server 的这个端口
- 你通过 SSH client,在本地 bind 某个端口,使得向这个端口的请求,通过 SSH 转发到 A server,再由 A server 的 SSH server 转发到 B server
- 此时你可以访问 B server 了
Remote port forwarding 则是反过来:
- 外部想访问你的本地某端口服务,但是被防火墙挡住了
- 你跟外部之间,共同可以访问 A server
- 你通过 SSH 访问 A server,要求 A 的 SSH server bind 某个端口,使得到这个端口的请求,通过 SSH 传到你本地上、想被外部访问的端口
- 此时外部就可以访问你本地的端口了
这篇 文章 讲得很清晰直观。看它。
同时注意,SSH 不仅可以 tunneling 端口,也可以是 sock 文件。
通过 XShell 配置
XShell 提供了图形化配置的能力:
其中源主机是指你的本地主机,侦听端口是指 tunnel 建立后会 bind 的本地端口,可以通过这个端口来访问远端主机的服务。
目标主机是指你的远端主机去访问服务时用的名称。如果你的 MySQL 服务 IP 是 1.2.3.4,那么目标主机就写这个 IP。目标端口即服务的端口,比如 MySQL 的 3306。
配置好后,你需要重开 / 重连你的 XShell session,这个 tunnel 才会建立起来。
命令行
假如你的远端机器是 5.6.7.8
,远端机器可访问的 MySQL 服务地址是 1.2.3.4
。如果你想通过访问本机的 9000 端口,来访问到远端的这个 MySQL 服务,那需要在你的本地机器上运行:
ssh -CNL 9000:1.2.3.4:3306 onlyice@5.6.7.8
L
表示这是 port forwardingC
表示压缩请求N
表示不登陆到 server 上,仅打开 tunnel;不指定 N 时会给你一个 server 的命令提示符,跟正常 SSH 登陆 server 一样
OpenSSH 配置文件
~/.ssh/config
中可以定义:
Host myvm
User onlyice
HostName 1.1.1.1
IdentityFile ~/.ssh/id_rsa
LocalForward 8300 example.com:3000
配置好后,你运行 ssh myvm
时,会自动打通隧道;访问本机 8300 端口时,会通过 myvm 访问远端的 example.com:3000。
你也可以通过 VSCode 的 Remote SSH 功能打开 myvm;VSCode 也会把隧道打通。