应用
Sshwifty Plus
通过网页建立SSH连接,并自动管理你的SSH密钥,可以自托管于Cloudflare Worker,无需服务器。
开源仓库:https://github.com/krab-lab/sshwifty-plus
不建议使用其他人部署的服务,除非你能完全信任对方。他人只要保存了
SSHWIFTY_KEY_ENCRYPTION_SECRET 就能够随时解密数据库,获得你的服务器地址和SSH私钥。建议自行部署该服务,并配合适当的Zero Trust访问控制。功能变更
在原项目 Sshwifty 的基础上做了如下改动。
Workers与静态资源
- Cloudflare Worker同时托管静态UI,并处理
/sshwifty/socketWebSocket SSH流量。 - 当前只支持SSH;Telnet、服务端Hooks、Socks5、服务端
file://私钥读取不支持。 - SSH客户端使用
ssh2,并限制为Cloudflare Workers可兼容的算法组合。
GitHub登录与账号密钥
当 SSHWIFTY_AUTH_MODE 设置为 github 时,GitHub OAuth是必需登录方式。
- 每个GitHub账号首次登录时,系统会创建一组Ed25519和RSA 4096位SSH密钥对。
- 用户能在账号窗口查看和复制公钥。
- 私钥使用
SSHWIFTY_KEY_ENCRYPTION_SECRET加密后保存到Cloudflare D1。 - SSH认证方式可以使用
Saved Key,选择该选项时会使用托管的密钥连接远程服务器。 - 使用
Saved Key时,Worker先尝试Ed25519私钥,再尝试RSA私钥。
远程服务器记录
Connected before列表改为按GitHub账号保存到D1。
- SSH连接成功后自动保存远程服务器记录。
- 用户可以编辑或删除记录。
- 密码、上传的私钥和其他连接凭据不会保存到远程记录中。
部署
你需要准备:
- Cloudflare账号,并已启用Workers与D1。
- Fork该仓库到自己的Github账号。
在Cloudflare Dashboard创建D1数据库
- 登录Cloudflare Dashboard。
- 打开 存储与数据库,进入 D1 SQLite数据库。
- 点击 创建数据库,名称填写
sshwifty。 - 创建完成后复制数据库ID,这是一串UUID,类似
84fa53bb-3b6b-4d23-9f28-bfdcc23aa243。
检查仓库配置
部署配置由根目录的 wrangler.jsonc 提供。连接仓库前确认其中的D1 binding使用:
"d1_databases": [
{
"binding": "DB",
"database_name": "sshwifty",
"database_id": "YOUR_D1_DATABASE_ID",
"migrations_dir": "worker/migrations"
}
]
将上一步的数据库ID写入 database_id,提交到部署分支。可使用GitHub网页编辑器修改 wrangler.jsonc 并提交。
wrangler.jsonc 是Git部署的配置来源。不要在Dashboard和仓库配置中为同一个binding填写相互冲突的数据库。在Cloudflare中连接GitHub仓库
- 打开 Workers & Pages。
- 点击创建应用,选择
Continue with Github。 - 授权Cloudflare访问GitHub,选择包含本项目的仓库。
- 进入构建配置,填写以下内容:
| 配置项 | 值 |
|---|---|
| 项目名称 | sshwifty-plus |
| 根目录 | / |
| 构建命令 | npm run generate |
| 部署命令 | npx wrangler deploy |
- 保存并启动首次部署。
部署后,在Worker的 绑定 中确认存在:
- 类型:D1数据库
- 名称:
DB - 值:
sshwifty
在GitHub创建OAuth App
在对应Worker的域中复制生产URL,或添加一个自定义域。
- 打开GitHub的 Settings → Developer settings → OAuth Apps。
- 点击
New OAuth App。 - 将Authorization callback URL设置为:
https://YOUR_WORKER_DOMAIN/sshwifty/auth/github/callback
例如Worker域名为 https://sshwifty.example.com,callback URL必须是:
https://sshwifty.example.com/sshwifty/auth/github/callback
推荐使用自定义域。
- 点击
Generate a new client secret,记录GitHub OAuth App的Client ID与Client Secret,下一步要填写到Cloudflare Dashboard。
在Dashboard填写Variables和Secrets
首次部署后,打开对应Worker的 设置 → 变量与密钥,填写以下值。
普通变量
这些变量已经在
wrangler.jsonc 内声明,不需要手动添加,你可以根据需要修改。| 名称 | 值 | 说明 |
|---|---|---|
SSHWIFTY_AUTH_MODE | github | 要求GitHub登录 |
SSHWIFTY_DIAL_TIMEOUT | 120 | SSH连接超时,单位秒 |
SSHWIFTY_HEARTBEAT_TIMEOUT | 10 | 心跳间隔,单位秒 |
SSHWIFTY_ALLOWED_HOSTS | 例如 ssh.example.com:22,10.0.0.10:2222 | 填写后只能连接指定的主机和端口,暂不支持通配符和网段 |
SSHWIFTY_PUBLIC_ACCESS | true | 允许无需密码即可进入Sshwifty入口 |
SSHWIFTY_PRESETS | [] | SSH preset JSON |
SSHWIFTY_SERVER_MESSAGE | 任意提示文本 | 可选 |
为避免Dashboard值与仓库配置不一致,建议将长期固定的非敏感值提交到 wrangler.jsonc;将环境专属值通过Dashboard管理。
Secrets
不要在任何地方暴露这些值,更不要将这些值写入
wrangler.jsonc !使用 添加 → 密钥 添加以下值:
| 名称 | 值来源 | 用途 |
|---|---|---|
GITHUB_CLIENT_ID | GitHub OAuth App的Client ID | GitHub登录必需 |
GITHUB_CLIENT_SECRET | GitHub OAuth App的Client Secret | GitHub登录必需 |
SSHWIFTY_SHARED_KEY | 自行设置一个密码 | 可选,当 SSHWIFTY_PUBLIC_ACCESS 禁用时,要求输入密码才能使用Sshwifty |
SSHWIFTY_SESSION_SECRET | 自行生成的高强度随机值 | 签名session与OAuth state cookie |
SSHWIFTY_KEY_ENCRYPTION_SECRET | 自行生成的高强度随机值 | 加密D1中的SSH私钥 |
对于后两个值,建议生成至少32字节的随机字符串后粘贴到Dashboard,并且它们必须不同。
推荐使用 PSWD by MAZE ,勾选 Include Uppercase Letters, Include Lowercase Letters, Include Numbers 。
轮换
SSHWIFTY_SESSION_SECRET 会使所有用户重新登录。不要丢失或随意轮换
SSHWIFTY_KEY_ENCRYPTION_SECRET。丢失后,D1中已有的托管SSH私钥无法解密。保存变量或secrets后,在Dashboard里重试部署或向GitHub推送一次空提交以创建新的Worker版本。
首次部署后的D1 处理
- 确认最新部署已完成,并且
DB绑定指向正确的sshwiftyD1数据库。 - 打开
https://YOUR_WORKER_DOMAIN/sshwifty/。 - 点击Sign in with GitHub并完成授权。
- OAuth callback会自动执行当前v1 schema的建表自检。
部署验证
- 打开
https://YOUR_WORKER_DOMAIN/sshwifty/。 - 点击
Sign in with GitHub并完成OAuth授权。 - 打开右上角账号菜单,复制Ed25519或RSA公钥。
- 将公钥写入目标服务器用户的
~/.ssh/authorized_keys。 - 新建SSH连接,在Authentication中选择
Saved Key。 - 确认服务器指纹后,验证shell能打开。
- 再次打开连接窗口,确认远程服务器已出现在Connected before;编辑和删除操作应在刷新后保留。
遇到问题
请提交Issue。