场景
- 波波(技术实施人员)在客户处实施项目
- 能 SSH 访问客户服务器
- 能访问外网(包括咱公司公网服务器)
- 没有外网 IP,不能通过 SSH 被直接连接到
- 霸哥(研发人员)在公司内部局域网内,但是需要连接客户局域网内的客户服务器,进行调试
方案
- 波波使用 XShell(SSH)做两次代理:
- 将波波笔记本上的本地指定端口 9999 正向代理到客户服务器的 SSH 服务端口
- 将咱公司公网服务器远端指定端口 9527 反向代理到波波笔记本上的本地指定端口 9999
- 霸哥登录咱公司公网服务器,SSH 连接本地 9527 端口,经过波波的代理,连接到客户服务器的 SSH 服务端口
提示:HTTP 服务也可以通过类似步骤实现中转,通过访问我们本地指定端口,经过对方网络内的某一台机器中转,访问客户局域网内的 Web 服务。
步骤
- XShell 建立两个连接
- 客户服务器
- 咱公司公网服务器
- 切换到客户服务器连接的那个界面
- 点击界面上的查看 -> 隧道窗格
- 下面新出现的那一栏中切换到转移规则标签
- 鼠标右击,选择添加
- 类型:
Local(Outgoing)
源主机:localhost
侦听端口:9999
目标主机:localhost
目标端口:客户服务器 SSH 端口,比如22
确定
- 切换到咱公司公网服务器连接的那个界面
- 点击界面上的查看 -> 隧道窗格
- 下面新出现的那一栏中切换到转移规则标签
- 鼠标右击,选择添加
- 类型:
Remote(Outgoing)
源主机:localhost
侦听端口:9527
目标主机:localhost
目标端口:9999
确定
- 在咱公司公网服务器上,通过以下命令实现对客户服务器 SSH 服务的访问:
ssh <USER>@localhost -p 9527
说明:<USER>
是客户服务器的用户名
原理
原理我并不清楚,不过我猜,可能是这样:
正向代理
- A 机器发起 SSH 连接(隧道 0),连接到 B 机器
- A 机器复制一个 SSH 连接(隧道 1)
并且告诉 B 机器,建立一个指向你 22 端口的连接,然后:- 将来自 SSH 连接(隧道 1)的数据都通过这个连接发出去
- 将来自这个连接的数据都通过 SSH 连接(隧道 1)发给 A 机器
- A 机器监听一个本地端口 9999,如果有程序连接到 9999 端口的话:
- 将来自 SSH 连接(隧道 1)的数据都通过这个连接发出去
- 将来自这个连接的数据都通过 SSH 连接(隧道 1)发给 B 机器
说明:
- A 机器,实际上是 A 机器上的 ssh 程序
- B 机器,实际上是 B 机器上的 sshd 程序
Linux 命令:
# -Nf 参数作用:连接连接之后不执行命令(通过 login 程序登录虚拟终端),关闭隧道 0,保持隧道 1,然后转入后台运行
ssh -NfL 9999:<B 机器>:22 localhost
反向代理
- A 机器发起 SSH 连接(隧道 0),连接到 C 机器
- A 机器复制一个 SSH 连接(隧道 1)
并且告诉 C 机器,监听你的 9527 端口,然后,如果有程序连接到 9527 端口的话:- 将来自 SSH 连接(隧道 1)的数据都通过这个连接发出去
- 将来自这个连接的数据都通过 SSH 连接(隧道 1)发给我(A 机器)
- A 机器建立一个指向本地端口 9999 的连接
- 将来自 SSH 连接(隧道 1)的数据都通过这个连接发出去
- 将来自这个连接的数据都通过 SSH 连接(隧道 1)发给 C 机器
Linux 命令
ssh -NfR 9527:localhost:9999 <C 机器>