还在为 Termius 不支持
ProxyCommand而苦恼?本文将手把手教你通过 Cloudflared 隧道 + 本地端口映射,实现 Termius(需 Pro)和 VSCode SFTP 插件无缝连接内网目标服务器。一次配置,永久生效。
一、场景与痛点
很多开发者和运维人员使用 Cloudflare Tunnel(cloudflared)将内网 SSH 服务安全地暴露出来。常见的 SSH 配置方式是在 ~/.ssh/config 中写入:
Host netops-01
HostName netops.abc.com
User jumpuser
IdentityFile ~/.ssh/id_ed25519
ProxyCommand cloudflared access ssh --hostname %h
ServerAliveInterval 30
ServerAliveCountMax 4
然而,当你试图将这个配置用于 Termius 时,会发现 Termius 的图形界面不支持 ProxyCommand,导入时会被直接忽略。同时,Termius 的“主机链”(Host Chaining)功能需要 Pro 付费计划才能使用。
更麻烦的是,如果你还需要用 VSCode 的 SFTP 插件 同步代码,同样面临跳板机配置的困惑。
本文将一步步带你解决所有问题。
二、整体架构与核心思路
架构图
text
你的电脑 (macOS)
│
│ cloudflared access tcp (后台服务)
▼
localhost:2222 ──→ (跳板机 netops.abc.com)
│
│ Termius Host Chaining / SFTP hop
▼
跳板机 (jumpuser)
│
│ SSH 转发到内网
▼
目标服务器 (192.168.1.100)
核心思路
- 用
cloudflared在本地打开一个 TCP 端口(如2222),将跳板机映射到本地的127.0.0.1:2222。 - Termius 使用 Host Chaining:先连
127.0.0.1:2222(跳板机),再通过跳板机连目标服务器。 - VSCode SFTP 使用
hop字段:实现同样的两级跳转。 - 将
cloudflared配置为 macOS 的launchd后台服务,实现开机自启。
效果
- ✅ Termius 免费版用户可通过本地端口直连跳板机(但 Host Chaining 仍需 Pro)
- ✅ VSCode SFTP 完全免费可用
- ✅ 一次配置,重启电脑后自动连接
三、安装 cloudflared
前置条件:你已经拥有一个 Cloudflare 账号,并在 Zero Trust 中创建了 Tunnel,且配置了相应的域名路由(如
netops.abc.com指向内网 SSH 服务)。如果你尚未完成,请先参考 Cloudflare 官方文档 创建 Tunnel 并绑定域名。
macOS(使用 Homebrew)
bash
brew install cloudflared
验证安装
bash
cloudflared --version
其他系统请参考 Cloudflare 官方下载页面。
四、让 cloudflared 在后台永久运行(macOS Launch Agent)
每次手动开终端太麻烦,我们把它配置为 macOS 的后台服务。
4.1 确认 cloudflared 路径
bash
which cloudflared
通常路径为 /opt/homebrew/bin/cloudflared(Apple Silicon)或 /usr/local/bin/cloudflared(Intel)。
4.2 创建 Launch Agent 配置文件
将以下命令复制到终端执行(注意替换:HOSTNAME 改为你的实际域名,CLOUDFLARED_PATH 改为上一步查到的路径):
bash
# 设置你的域名(替换为实际域名)
HOSTNAME="netops.abc.com"
# 设置 cloudflared 的实际路径
CLOUDFLARED_PATH="/opt/homebrew/bin/cloudflared"
cat > ~/Library/LaunchAgents/com.mycloudflared.ssh.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.mycloudflared.ssh</string>
<key>ProgramArguments</key>
<array>
<string>${CLOUDFLARED_PATH}</string>
<string>access</string>
<string>tcp</string>
<string>--hostname</string>
<string>${HOSTNAME}</string>
<string>--url</string>
<string>localhost:2222</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/cloudflared_ssh.log</string>
<key>StandardErrorPath</key>
<string>/tmp/cloudflared_ssh.err</string>
</dict>
</plist>
EOF
4.3 加载并启动服务
bash
launchctl load -w ~/Library/LaunchAgents/com.mycloudflared.ssh.plist launchctl start com.mycloudflared.ssh
4.4 验证服务是否运行
bash
launchctl list | grep cloudflared
如果看到 com.mycloudflared.ssh 且状态正常,说明已成功运行。
停止服务的命令(备用):
bash
launchctl unload -w ~/Library/LaunchAgents/com.mycloudflared.ssh.plist
五、配置 Termius(使用 Host Chaining)
⚠️ 重要提示:Termius 的 Host Chaining 功能需要 Pro 及以上付费计划才能使用。免费版用户可跳过此节,直接使用命令行
ssh -J连接。
5.1 创建跳板机主机(Intermediate Host)
在 Termius 中点击 New Host:
| 字段 | 填写内容 |
|---|---|
| Address | 127.0.0.1 |
| Port | 2222 |
| Username | jumpuser(跳板机用户名) |
| 认证方式 | 选择 Key,导入跳板机的私钥(如 ~/.ssh/id_ed25519) |
保存后,这个主机代表你的跳板机。
5.2 创建目标服务器主机(Target Host)
再次点击 New Host:
| 字段 | 填写内容 |
|---|---|
| Address | 192.168.1.100(目标服务器内网 IP) |
| Port | 22 |
| Username | 目标服务器用户名 |
| 认证方式 | 选择 Key,导入目标服务器的私钥 |
5.3 设置 Host Chaining
在目标主机的设置页面:
- 向下滚动,点击 Show more
- 找到 Host Chaining/Chain 字段,点击它
- 从列表中选择第一步创建的跳板机主机
- 点击 Save
现在点击连接目标主机,Termius 会自动先连跳板机,再从跳板机 SSH 到目标服务器。
六、配置 VSCode SFTP 插件(使用 hop 字段)
本文以
Natizyskunk版 SFTP 插件为例,它完全支持hop字段。
6.1 关键认知:hop 的配置逻辑
在使用 Natizyskunk 版插件时,hop 的配置逻辑和直觉刚好相反:
| 配置位置 | 含义 |
|---|---|
最外层(host / port / username) | 跳板机(堡垒机) 的连接信息 |
hop 内部(host / port / username) | 目标服务器 的连接信息 |
插件会先连接最外层的跳板机,登录成功后,再从跳板机跳转到 hop 内部指定的目标服务器。
6.2 正确的配置示例
在项目根目录创建或编辑 .vscode/sftp.json,不允许有任何注释(JSON 格式不支持注释):
json
{
"name": "dev",
"remotePath": "/var/www/project",
"host": "127.0.0.1",
"port": 2222,
"username": "jumpuser",
"privateKeyPath": "/Users/yourname/.ssh/id_ed25519",
"hop": {
"host": "192.168.1.100",
"port": 22,
"username": "target_user",
"password": "目标服务器密码"
},
"uploadOnSave": false,
"useTempFile": false,
"openSsh": false,
"downloadOnOpen": false,
"ignore": [
".vscode",
".git",
".DS_Store",
".idea",
".history"
],
"concurrency": 4,
"protocol": "sftp",
"connectTimeout": 10000,
"interactiveAuth": false,
"secure": false,
"remoteTimeOffsetInHours": 0,
"remoteExplorer": {
"order": 0
}
}
6.3 配置说明
- 外层(跳板机):
127.0.0.1:2222,用户jumpuser,使用私钥认证。 hop内部(目标服务器):192.168.1.100,用户target_user,使用密码认证(也可改为privateKeyPath使用私钥)。- 连接顺序:
本地 → 127.0.0.1:2222 (跳板机) → 192.168.1.100 (目标服务器)。
6.4 为什么不推荐 proxy 字段?
在 Natizyskunk 版插件中,proxy 字段即使在 openSsh: true 下,仍然由插件内置的 ssh2 库处理,而非调用系统 ssh 命令。这可能导致以下问题:
- 兼容性差,报错
Connection lost before handshake sshDebug日志不输出详细调试信息- 与某些 SSH 服务器配置不兼容
因此,本文强烈推荐使用 hop 字段,它能稳定实现跳板机连接。
6.5 JSON 格式避坑提醒
- ❌ 不允许添加任何注释(
//或/* */) - ❌ 不允许末尾有多余逗号
- ✅ 所有字符串必须使用双引号
- ✅ 布尔值(
true/false)不加引号
如果配置格式错误,VSCode 会报错 JSON 中不允许有注释 (521),请检查并删除所有注释。
七、常见问题与排错
Q1:Termius 连接 127.0.0.1:2222 失败?
- 检查
cloudflared后台服务是否在运行:launchctl list | grep cloudflared - 查看错误日志:
cat /tmp/cloudflared_ssh.err - 确认私钥权限正确:
chmod 600 ~/.ssh/id_ed25519
Q2:SFTP 插件报错 Connection lost before handshake?
- 检查
hop配置逻辑是否写反:外层应是跳板机,hop内部应是目标服务器。 - 检查
127.0.0.1:2222是否畅通:nc -zv 127.0.0.1 2222 - 确认跳板机能访问目标服务器:登录跳板机后执行
ssh 目标用户@192.168.1.100 - 确认认证方式正确(外层跳板机私钥,内层目标机密码/私钥)。
Q3:SFTP 插件报错 JSON 中不允许有注释 (521)?
删除 sftp.json 中所有 // 或 /* */ 注释,确保为纯 JSON 格式。
Q4:Termius 免费版能用 Host Chaining 吗?
- 不能。Host Chaining 是 Termius Pro 及以上计划的专属功能。免费用户可改用命令行
ssh -J jumpuser@127.0.0.1:2222 目标服务器用户名@192.168.1.100。
Q5:可以用 proxy 字段代替 hop 吗?
在 Natizyskunk 版插件中,不推荐使用 proxy。该插件的 proxy 仍由 ssh2 库处理,兼容性差,容易失败。建议使用 hop 字段。
八、总结
配置对照表
| 工具 | 配置方法 | 核心要点 |
|---|---|---|
| cloudflared | launchd 后台服务 | 将跳板机映射到 127.0.0.1:2222 |
| Termius | Host Chaining(需 Pro) | 先连跳板机,再连目标服务器 |
| VSCode SFTP | hop 字段 | 外层是跳板机,hop 内是目标服务器 |
经验教训
Natizyskunk版 SFTP 插件的hop配置逻辑是反直觉的:外层是跳板机,内层是目标服务器。proxy字段在该插件中不可靠,即使开启openSsh: true也无法调用系统 SSH。- JSON 配置文件不支持注释,使用纯 JSON 格式。
- Termius 的 Host Chaining 需要 Pro 付费,免费用户可用命令行
ssh -J替代。
一次配置,永久生效。无论是日常运维、代码同步,还是远程调试,这套方案都能帮你高效地穿透内网,直达目标服务器。
📌 本文使用环境:macOS (Apple Silicon) + cloudflared 2024.x + Termius 免费版/Pro + VSCode SFTP (Natizyskunk) 插件。其他平台(Windows/Linux)可参考思路调整。
如果文章发布后读者有补充问题,欢迎在评论区留言交流!😊
讨论 / DISCUSS
还没有留言,来留下第一条评论吧!