Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

CF-Workers-WebSSH

一个运行在 Cloudflare Workers 上的原生 WebSSH 终端。浏览器通过 HTTPS/WebSocket 连接 Worker,Worker 使用 Cloudflare TCP Sockets 直接连接公网 SSH 服务器,并在边缘运行时内完成 SSH 2.0 握手、主机密钥校验、用户认证和交互式 PTY 会话。

运行时无 SSH 第三方依赖,前端、会话网关、SSH 客户端实现和静态资源均由同一个 Worker 部署提供。

[!IMPORTANT] 项目始终允许匿名创建网关会话,不提供内置访问令牌或用户身份认证。公网部署前务必使用 Cloudflare Access、WAF 与限流策略保护页面和 API,并关闭不需要的 workers.dev 公网入口。

功能特性

  • Cloudflare Workers 原生部署,使用 Durable Objects 隔离每个 SSH 会话。
  • 基于 xterm.js 的响应式终端,支持桌面端和移动端、自动缩放、全屏和会话日志。
  • 内置 SFTP 文件管理,可浏览目录、上传/下载文件、新建与删除空目录、删除文件和重命名。
  • 内置实时进程管理,通过独立 WebSocket 和 SSH exec channel 展示 top 进程、CPU、负载、内存与 Swap 使用率。
  • 支持 SSH password 与单密码提示的 keyboard-interactive 认证,以及 Ed25519、RSA、ECDSA 的未加密 OpenSSH 私钥认证。
  • 首次连接时暂停认证并显示主机 SHA-256 指纹,确认后才会发送 SSH 凭据。
  • SSH 连接成功后自动写入浏览器本地"历史记录",密码使用 AES-256-GCM 加密,私钥不保存。
  • 支持 UTF-8、GB18030、Big5 显示编码、初始命令和分享链接(密码认证时链接携带 Base64 密码,粘贴即自动连接)。
  • 提供一次性会话票据、同源检查、HTTPS 强制、安全响应头和公网目标校验。
  • SSH 数据包、密钥交换、加密、认证和通道逻辑全部使用 TypeScript 与 Web Crypto 实现。

工作原理

浏览器(xterm.js)
    │  HTTPS:申请一次性会话票据
    │  WSS:终端输入、输出和控制消息;独立 SFTP 文件通道
    ▼
Cloudflare Worker
    │  同源检查、会话票据、静态资源
    ▼
每会话 Durable Object
    │  消耗一次性票据、校验目标地址、运行 SSH 2.0 客户端
    │  Cloudflare TCP Socket
    ▼
公网 SSH 服务器

支持范围

类别当前支持
SSH 协议SSH 2.0 交互式 Shell、PTY、SFTP v3、窗口尺寸同步、Keepalive
用户认证Password、单密码提示 keyboard-interactive、OpenSSH Ed25519、RSA、ECDSA P-256/P-384/P-521 私钥
密钥交换curve25519-sha256ecdh-sha2-nistp256
主机密钥Ed25519、ECDSA P-256/P-384/P-521、RSA SHA-2
加密算法AES-128/256-GCM、AES-128/192/256-CTR
MACHMAC-SHA2-256、HMAC-SHA2-512(AES-GCM 不使用独立 MAC)
终端编码UTF-8、GB18030、Big5(取决于浏览器 TextDecoder 支持)

限制:只能连接公网 IP 或解析结果全部为公网地址的域名;不支持出站 TCP 25 端口;不支持加密私钥、PEM/PKCS#8 私钥、SSH Agent、多因素键盘交互认证、SCP、端口转发、ProxyJump、SSH 压缩和会话内 rekey。文件上传与下载单文件限制为 64 MiB,目录删除仅支持空目录。

部署教程

Deploy to Cloudflare Workers

点击上方按钮,授权 Cloudflare 读取你的 GitHub 仓库后即可一键创建并部署 Worker。部署平台会自动读取仓库中的 wrangler.toml,并以 npm run deploy 作为构建命令完成首次构建与发布。

[!NOTE] 一键部署需要你对自己的仓库有写入权限。若尚未 Fork,请先 Fork 到个人 GitHub 账号,部署时在仓库选择列表中选中你 Fork 后的仓库即可。

  1. Fork 该项目到用户自己的 GitHub 仓库。
  2. Cloudflare > Workers 和 Pages > 创建应用程序 > Continue with GitHub 按钮,选择已 Fork 的项目进行部署。
  3. 在"构建命令"(Build Command)一栏中填入 npm run deploy
  4. 点击"部署"按钮即可完成部署。

配置项

名称类型默认值说明
CONNECT_TIMEOUT_MSVariable"10000"TCP 建连超时,运行时限制在 2000–30000 ms。
SSH_SESSIONSDurable Object binding已配置每个连接独立的会话对象。
ASSETSWorkers Assets binding已配置dist/ 静态资源交给 Worker 提供。

会话创建始终匿名,不存在用于开启、关闭或保护会话创建的项目变量。公开网关可能被滥用、产生费用或导致 Cloudflare 账户受限,应在 Cloudflare 边缘配置身份访问策略、WAF、限流和使用监控。

自定义域名与 Cloudflare Access

绑定自定义域名:在 Cloudflare Dashboard 的 Workers & Pages -> 选择 Worker -> Settings -> Domains & Routes -> Add -> Custom domain 中添加。也可在 wrangler.toml 中写入:

routes = [
  { pattern = "ssh.example.com", custom_domain = true }
]

确认自定义域名可用后,将 workers_dev = false 关闭公网 workers.dev 入口。

在 Cloudflare Zero Trust 中为自定义域名创建 Self-hosted Application,配置只允许指定用户、邮箱域或身份提供商访问。WebSocket 使用同一站点的 Access 会话,可保护整个 WebSSH 页面和 API。建议纵深防御:

  • 确保所有可访问域名都受 Access 保护。
  • 设置 workers_dev = false,避免公开 workers.dev 地址绕过自定义域名策略。
  • 使用 WAF 规则限制异常请求和不需要的访问区域。
  • 对会话申请与 WebSocket 建连路径配置限流,并设置告警。
  • 验证 Access 策略同时覆盖页面、/api/session/api/ssh

本地开发

cp .env.example .dev.vars   # Windows: Copy-Item .env.example .dev.vars
npm run dev                 # 启动 Wrangler,访问 http://localhost:8787

如需前端热更新,使用两个终端:

# 终端 1
npm run build:web
npx wrangler dev

# 终端 2
npm run dev:web    # 访问 http://localhost:5173,Vite 代理 /api 到 8787

[!NOTE] 本地 Worker 仍从你的网络连接目标 SSH 服务器,公网目标限制同样生效。不要使用生产 SSH 凭据测试不受信任的代码分支。

常用命令

命令作用
npm run dev通过 Wrangler 构建前端并启动本地 Worker
npm run dev:web启动 Vite 前端开发服务器
npm run build:web将前端构建到 dist/
npm run typecheck检查 Worker 与前端 TypeScript
npm run check执行全部检查、构建和部署 dry-run
npm run deploy通过 Wrangler 构建前端并部署到 Cloudflare

项目结构

.
├── frontend/                  # xterm.js 前端
│   ├── index.html
│   └── src/
│       ├── main.ts            # 连接管理、xterm、WebSocket 客户端
│       ├── history.ts         # 历史记录归一化与去重
│       ├── history-key.ts     # IndexedDB 中的 AES-GCM 密钥
│       ├── password-crypto.ts # 历史密码 AES-GCM 加解密
│       ├── ui-state.ts        # 连接按钮与面板状态机
│       └── style.css
├── src/
│   ├── backend/
│   │   ├── durable-object.ts  # 会话票据、TCP Socket 与会话生命周期
│   │   ├── security.ts        # 票据、同源与公网目标校验
│   │   ├── session.ts         # SSH 状态机与浏览器消息桥接
│   │   └── sftp-handler.ts    # SFTP 文件操作与传输状态
│   ├── ssh/                   # SSH 协议、KEX、密码学、认证与通道
│   ├── http-security.ts       # HTTPS 与安全响应头
│   ├── types.ts               # Worker 环境、连接消息和 SSH 类型
│   └── worker.ts              # HTTP/API/Assets 入口
├── wrangler.toml              # Worker、Assets、Durable Object 与 migration
└── package.json

API 概览

接口方法用途
/api/healthGET返回 Worker 与 SSH 功能健康状态
/api/sessionPOST匿名创建一次性会话票据
/api/ssh?ticket=...&session=...GET + WebSocket Upgrade进入对应 Durable Object 并建立 SSH 会话
/api/sftp?session=...&token=...GET + WebSocket Upgrade使用一次性附着令牌进入当前会话的文件通道
/api/processes?session=...&token=...GET + WebSocket Upgrade使用一次性附着令牌进入当前会话的进程监控通道

所有 /api/* 响应均允许跨站访问,并支持浏览器 OPTIONS 预检请求。公网访问控制应由 Cloudflare Access、WAF 和限流策略提供。

安全说明

  • 一次性票据使用随机密钥和 HMAC-SHA256 签名,绑定请求端 IP、60 秒过期并立即销毁。
  • 域名解析后逐个检查公网地址,直接连接已验证 IP,限制 SSRF 与 DNS 重绑定。
  • SSH 主机密钥会验证交换签名并计算 SHA256: 指纹;没有固定指纹时,认证会暂停等待用户确认。
  • 历史密码使用 AES-256-GCM 加密,密钥保存在 IndexedDB 中,不写入 Local Storage。
  • 响应设置 CSP、HSTS、X-Frame-OptionsX-Content-Type-Options 等安全头。
  • Worker 是实际的 SSH 客户端,密码或私钥会在 Worker 会话内存中被处理。请使用权限最小化的独立账号或密钥。

许可证

Apache License 2.0

致谢

本项目在开发过程中参考了以下优秀开源项目,特此致谢:

关于 About

一个运行在 Cloudflare Workers 上的无依赖 WebSSH 终端:纯 TypeScript 实现 SSH 2.0 客户端,借助 Durable Objects 直连公网 SSH 服务器,前端基于 xterm.js。
cloudflare-workersdurable-objectssshssh-clienttypescriptwebssh

语言 Languages

TypeScript83.4%
CSS9.9%
HTML6.7%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
124
Total Commits
峰值: 105次/周
Less
More

核心贡献者 Contributors