🔐 魔改版 CF-Workers-WebSSH:给 WebSSH 加上「访问密码门禁」和「跨设备连接同步」,顺手修了个 SFTP Bug
📌 仓库地址
🍴 魔改版:https://github.com/qmsdh/CF-Workers-WebSSH
🏛️ 原版:https://github.com/cmliu/CF-Workers-WebSSH
一句话总结:在完全保留 cmliu 原版全部能力的前提下,新增了 ACCESS_PASSWORD 访问密码门禁和 CONNECTIONS_KV 跨设备加密同步,并修复了 SFTP 上传覆盖同名文件报错的 Bug。
📖 一、原版是什么,为什么我还要魔改?
cmliu 的 CF-Workers-WebSSH 是一个跑在 Cloudflare Workers 上的纯原生 WebSSH 终端:
- ✅ 浏览器通过 HTTPS/WebSocket 连接 Worker
- ✅ Worker 用 Cloudflare TCP Sockets 直连公网 SSH 服务器
- ✅ SSH 2.0 握手、主机密钥校验、用户认证、交互式 PTY 会话全部在边缘运行时内完成
- ✅ 零 SSH 第三方依赖,前端、会话网关、SSH 客户端由同一个 Worker 提供
- ✅ 前端基于 xterm.js,内置 SFTP 文件管理和实时进程监控
这个项目我日常重度使用,但有两个长期痛点:
⚠️ 痛点 1:会话创建始终是匿名的
原版 README 自己就反复提醒:公网部署前务必套一层 Cloudflare Access、WAF 和限流策略,否则公开网关可能被滥用。对只是想"随手开个安全入口给自己用"的人来说,去 Zero Trust 配一套 Access 策略的门槛还是偏高。⚠️ 痛点 2:历史连接列表只存在浏览器 Local Storage
换一台电脑、换一部手机,之前保存的服务器地址、端口、用户名、指纹全部要重新手填,多设备党狂怒。
于是就有了这个魔改版:这两个方向各加一个能力,其余原封不动。
🛠️ 二、魔改了什么:一张表看懂
| 对比项 | 🏛️ 原版 | 🔐 魔改版 |
|---|---|---|
| 访问控制 | 匿名创建会话,依赖 Cloudflare Access | ⭐ 内置 ACCESS_PASSWORD 访问密码门禁 |
| 会话票据接口 | POST /api/session 空 Body 即可 | ⭐ 可携带 { "password": "..." } 校验 |
| 连接列表同步 | 仅浏览器本地 | ⭐ 新增 KV + 客户端 AES-256-GCM 加密同步 |
| 新增 API | 无 | ⭐ GET/POST /api/connections |
| 新增绑定 | 无 | ⭐ CONNECTIONS_KV(KV Namespace) |
| CORS | 仅 Content-Type | ⭐ 额外允许 X-Access-Password 请求头 |
| 前端新增模块 | 无 | ⭐ frontend/src/kv-sync.ts |
| SFTP 覆盖上传 | ❌ 报错,需先手动删除旧文件 | ✅ 已修复,可正常覆盖 |
| 其余核心功能 | 全部保留 | ✅ 全部保留,一行未删 |
🚪 魔改点 1:访问密码门禁(ACCESS_PASSWORD)
给 Worker 加了一把应用层的钥匙:
- 🔑
/api/session校验请求体中的password是否等于ACCESS_PASSWORD - 🔑
/api/connections校验请求头X-Access-Password - 🔑 前端首次加载提示输入访问密码,暂存在
sessionStorage - 🔑 密码校验失败(401)时,前端自动清缓存并要求重新输入
- 🔐 密码比较使用常量时间比较,降低时序侧信道风险
💡 和 Cloudflare Access 有什么区别?
Access 是"在门口加一道门",要去 Zero Trust 后台建应用、配身份提供商、配策略;ACCESS_PASSWORD是"钥匙直接在你手里",设一个 Secret 就完事,体验更贴近传统 SSH 客户端。🛡️ 二者可以叠加:Access 管住入口,密码作为第二道防线,纵深防御。
⚠️ 注意:未配置
ACCESS_PASSWORD时,原版匿名会话逻辑仍可用,但/api/connections会拒绝服务。公网部署强烈不建议留空。
☁️ 魔改点 2:跨设备连接列表加密同步(CONNECTIONS_KV)
换设备不再重新手填服务器,历史连接自动跟着你走:
- 🔄 新增
CONNECTIONS_KV绑定与/api/connections接口 - 🔐 使用
ACCESS_PASSWORD通过 PBKDF2 派生 AES-256-GCM 密钥(SHA-256,迭代 210,000) - 🔒 连接列表在浏览器端加密后才发送到 Worker,Worker 只把密文写入 KV
- 📥 页面加载时自动合并「本地 Local Storage + 远端 KV 解密结果」
- 📤 新增、删除、保存连接、更新主机指纹时都会自动推送
- 🧯 同步失败不阻塞本地使用,Local Storage 仍是本地事实源
❓ 直接回答你最可能问的问题:我的服务器密码/私钥会存到 Cloudflare 上吗?
❌ 不会。 KV 里只有
v1.<iv>.<ciphertext>格式的密文,加密解密全发生在你的浏览器里(Web Crypto API)。Cloudflare 或任何中间人都拿不到明文。⚠️ 唯一注意点:
ACCESS_PASSWORD既是访问密码也是同步加密口令——改密码后旧密文无法解密,前端会忽略旧数据并用新密码重新推送当前本地列表。
✅ 原版能力一行未删
这不是"阉割换功能",而是"原版 + 两件新武器"。以下能力全部保留:
✅ Durable Objects 会话隔离
✅ xterm.js 响应式终端
✅ SFTP 文件管理
✅ 实时进程管理
✅ password / keyboard-interactive / Ed25519 / RSA / ECDSA 私钥认证
✅ 主机 SHA-256 指纹校验
✅ 历史密码 AES-256-GCM 加密(IndexedDB)
✅ UTF-8 / GB18030 / Big5 编码支持
✅ 一次性会话票据、同源检查、HTTPS 强制、安全响应头、公网目标校验
🐛 三、顺手修了一个 Bug:SFTP 上传覆盖同名文件报错
🐞 修复前:用户覆盖上传(overwrite)已存在的远程文件时,报错:
'''txt
SFTP request 71 failed with status 4: Failure
'''
因为 SFTP 协议里的"重命名"功能有一条规定:目标文件名必须是不存在的,否则重命名会直接失败。✨ 修复后:覆盖上传(重名写文件)可以正常完成,直接传就行。
如果还有其他bug,欢迎提 Issue 反馈你在实际使用中遇到的其他问题。
🚀 四、部署步骤速览
前置条件:Cloudflare 账号 · Fork 本仓库 · Node.js ≥ 22.12.0 · Wrangler ≥ 4.114.0 · 一个 KV Namespace
- 🍴 Fork 仓库到自己的 GitHub
- 📦 创建 KV Namespace:Cloudflare Dashboard → Workers 和 Pages → KV → 创建命名空间,复制 ID
- ✏️ 修改
wrangler.toml:把CONNECTIONS_KV的id替换成你自己的 KV Namespace ID - 🔑 设置
ACCESS_PASSWORD:推荐 Dashboard 的 Variables and Secrets,或npx wrangler secret put ACCESS_PASSWORD,⚠️ 不要提交到 Git - ☁️ 创建 Worker:Cloudflare Workers 创建应用时选择你 Fork 的仓库,构建命令填
npm run deploy ✔️ 验证:
- 访问 Worker 域名应出现密码输入提示
curl https://<你的域名>/api/health应返回{"status":"ok"}- 连接一次 SSH 后换设备输入相同密码,连接列表应自动同步
- 🎯 (可选)绑定自定义域名并设置
workers_dev = false,进一步收口公网入口
💡 一句话总结:原版部署 = Fork + 一键部署;魔改版部署 = 原版步骤 + 一个 KV + 一个 Secret,换来门禁和跨设备同步。
❓ 五、常见问题 FAQ
Q1:不配置
ACCESS_PASSWORD会怎样?
A:原版匿名会话逻辑仍可用,但跨设备同步(/api/connections)会拒绝服务。公网部署不建议留空。Q2:我的服务器密码/私钥会进 KV 吗?
A:不会。KV 只存密文,明文只在你浏览器里,加解密全在客户端完成。Q3:原版功能是不是被删了?
A:没有,一行未删,所有原版能力全部保留。Q4:和直接套 Cloudflare Access 有什么区别?
A:Access 是边缘层身份认证,配置门槛较高;ACCESS_PASSWORD是应用层口令,一个 Secret 搞定。二者可叠加使用。
🙏 六、特别鸣谢
最后,也是最重要的一句:
🎗️ 本魔改版基于 cmliu 的开源项目 cmliu/CF-Workers-WebSSH 修改而来,遵循 Apache License 2.0。
没有原作者从零用 TypeScript + Web Crypto 手写整套 SSH 2.0 协议栈的硬核功底,就没有这个魔改版存在的可能——无第三方依赖、单 Worker 部署、Durable Objects 会话隔离,这套架构本身就是作品。魔改版能做的,本质上只是在巨人肩膀上补了两块拼图。
特别鸣谢 @cmliu 的开源精神与持续维护! ⭐
强烈建议大家也去给原项目点一个 Star:https://github.com/cmliu/CF-Workers-WebSSH