SSH 隧道
利用 SSH 协议实现端口转发,支持多级跳板机连接,安全可靠。
基础使用
ssh -L 3307:123.123.14.120:3306 username@223.223.14.220 -N
参数解释:
-L 3307:123.123.14.120:3306:设置端口转发。将你本地电脑的3307端口映射到目标服务器A(123.123.14.120)的MySQL端口(3306)。username@223.223.14.220:这是服务器B的SSH登录用户名和公网IP。-N:表示不执行远程命令,仅建立隧道。
执行后,系统会提示你输入服务器B的SSH密码。连接成功后,这个SSH隧道就在后台运行了。
🗄️ 连接MySQL数据库
SSH隧道建立后,你的电脑(192.168.3.1)上连接本机3307端口,SSH隧道就会将请求转发到服务器A的3306端口。
进阶使用

场景:要实现从电脑 A 连接到 SFTP 服务器 D,目前的链路是:A (Windows) --[OpenVPN]--> B (CentOS) --[白名单]--> C (CentOS) --[白名单]--> D (SFTP)。
使用 SSH 配置文件(推荐)
在 Windows A 上打开目录 %USERPROFILE%.ssh\(通常是 C:\Users\你的用户名.ssh\)。
新建或编辑一个名为 config 的文件(无后缀),写入以下内容:
shell# 第一跳:中转机器 B Host serverB # 服务器别名,可以随便取 HostName [B的内网VPN IP] 或 [外网ip,如果有的话] User [B的用户名,登录服务器的用户名一般为root] IdentityFile ~/.ssh/key.pem # 如果是非密码登录而是通过密钥登录,指定密钥位置 PreferredAuthentications publickey # 指定登录方式为密钥 # 第二跳:中转机器 C Host serverC HostName [C的IP] User [C的用户名] ProxyJump serverB # 通过 B 跳转 # 最终目标:SFTP 服务器 D Host serverD HostName [D的IP] User [D的SFTP用户名] Port 22 # 如果SFTP不是22端口请修改 ProxyJump serverC # 通过 C 跳转配置完成后只需要执行命令
sftp serverD即可链接,但是这种是命令行里面的,如果要使用工具还得继续。要通过 Xftp 连接 D,最稳定且简单的方法是:先用命令行建立一个"本地隧道",然后让 Xftp 走这个隧道。
第一步在 PowerShell 建立隧道(打通 A 到 D 的大桥)
利用我们之前配置好的 config 文件(确保你已经按上一条回答配置好了 serverB, serverC, serverD)。
powershell# 这条命令的意思是:把本地的 2022 端口,通过跳转直接映射到 D 的 SFTP 端口 ssh -L 2022:localhost:2022 serverD -N如果你没配 config,或者想一行命令解决,可以用这个长命令,并保持这个窗口不要关闭
ssh -L 2022:[D的IP]:[D的端口] [B用户]@[B_IP] -t ssh -L [D的端口]:[D的IP]:[D的端口] [C用户]@[C_IP] -N第二步配置 Xftp 连接
现在,对于 Xftp 来说,服务器 D 就像是在你本地电脑的 2022端口上一样。
打开 Xftp,点击"新建"会话。
常规设置: 主机 (Host): 127.0.0.1 (代表你本地)协议: SFTP端口号 (Port): 2022(对应上面命令里的本地端口)
身份验证 (Authentication):
用户名: 输入 服务器 D 的登录用户名。
密码/密钥: 输入 服务器 D 的登录密码或私钥。
点击"连接"。
如果遇到连接失败
- 隧道命令的逻辑错误:你使用的 ssh -L 2022:localhost:2022 serverD 意思是"连接到 D,并将 D 自己的 2022端口转发到 A"。但你的目的是"通过 C 访问 D"。
- SFTP 权限限制:如果服务器 D 做了安全限制(比如只允许 SFTP 不允许执行 Shell 命令),那么 -N 参数建立隧道可能会被 D 拒绝。
推荐的最稳妥方案:通过 C 建立隧道
不要尝试直接把隧道打到 D,而是把隧道打到 C,让 C 帮你转发流量到 D。这样你只需要输入 B 和 C 的密码/密钥,而 D 的密码是在 Xftp 登录时才输入的。
powershell# 注意:这里我们只连到 serverC ssh -L 2022:[D的实际IP]:[D的端口] serverC -N -v- 2022: 是你 A 电脑上监听的端口。
- [D的实际IP]: 注意! 这里填的是在 C 机器看来,D 的 IP 地址。
- [D的端口]: D 的 SFTP 端口(通常是 22)。
- serverC: 使用你 config 里配置的跳转规则(A -> B -> C)。
- -v: 开启调试模式,你可以看到具体卡在哪里。
此时你会依次:
自动使用密钥登录 B。
提示输入 C 的密码。
成功后窗口会静止(没有新输出),这代表隧道通了。
现在隧道已经把 A 电脑的 2022端口直接通向了 D 的 SFTP 端口。配置 Xftp
- 主机: 127.0.0.1
- 端口: 2022
- 用户名: D 的用户名
- 密码: D 的密码
配置技巧
你的 config 文件可以写得非常庞大,包含几十个服务器和复杂的跳转逻辑。SSH 会根据你输入的 Host 别名,自动在内存中勾画出那条跳转路径。
你现在可以直接把 D、E 的各种路径都写进去,它们互不干扰。 想连哪个就 sftp 别名 即可。
# ==========================================
# 基础节点:B (所有的流量入口)
# ==========================================
Host serverB
HostName 20.8.0.1 # B 的 VPN 内网 IP
User root
IdentityFile ~/.ssh/id_rsa_b
PreferredAuthentications publickey
# ==========================================
# 分支节点:C (从 B 跳到 C)
# ==========================================
Host serverC
HostName 192.168.1.10 # C 的 IP
User root
ProxyJump serverB
# ==========================================
# 路径 1: A -> B -> C -> D
# ==========================================
Host serverD
HostName 10.0.0.5 # D 的 IP
User sftpuser
Port 2222
ProxyJump serverC # 这一行决定了它是从 C 跳过去的
# ==========================================
# 路径 2: A -> B -> C -> E (目标 E 通过 C 访问)
# ==========================================
Host serverE_viaC
HostName 10.0.0.6 # E 的 IP
User root
ProxyJump serverC # 这一行指定路径经过 C
# ==========================================
# 路径 3: A -> B -> E (目标 E 直接从 B 访问)
# ==========================================
Host serverE_direct
HostName 10.0.0.6 # 同样的 E IP
User root
ProxyJump serverB # 这一行改从 B 跳,不经过 C原理解读
- ProxyJump 的链式递归
当你执行 sftp serverD 时,SSH 会查看 serverD 的配置:
- 发现 ProxyJump serverC。
- 于是它去找 Host serverC。
- 发现 serverC 也有 ProxyJump serverB。
- 于是它去找 Host serverB。
- serverB 没有 ProxyJump,它会直接发起连接。
- 建立连接顺序:A -> B -> C -> D。
- 数据传输顺序:数据被层层封装加密,对 B 来说它只知道自己在帮 A 传数据给 C,它看不见发给 D 的内容。
别名(Alias)的力量
注意我在配置 E 时用了两个名字:serverE_viaC 和 serverE_direct。
- 你可以为同一物理 IP 设置不同的逻辑路径。
- 如果你输入 ssh serverE_viaC,它就走 C 跳。
- 如果你输入 ssh serverE_direct,它就直接从 B 跳。 这在其中一台机器(比如 C)临时宕机时非常有用。