Krab logoKrab
应用

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/socket WebSocket 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数据库

  1. 登录Cloudflare Dashboard。
  2. 打开 存储与数据库,进入 D1 SQLite数据库
  3. 点击 创建数据库,名称填写 sshwifty
  4. 创建完成后复制数据库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仓库

  1. 打开 Workers & Pages
  2. 点击创建应用,选择 Continue with Github
  3. 授权Cloudflare访问GitHub,选择包含本项目的仓库。
  4. 进入构建配置,填写以下内容:
配置项
项目名称sshwifty-plus
根目录/
构建命令npm run generate
部署命令npx wrangler deploy
  1. 保存并启动首次部署。

部署后,在Worker的 绑定 中确认存在:

  • 类型:D1数据库
  • 名称:DB
  • 值:sshwifty

在GitHub创建OAuth App

在对应Worker的中复制生产URL,或添加一个自定义域。

  1. 打开GitHub的 Settings → Developer settings → OAuth Apps
  2. 点击 New OAuth App
  3. 将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
推荐使用自定义域。
  1. 点击 Generate a new client secret,记录GitHub OAuth App的Client ID与Client Secret,下一步要填写到Cloudflare Dashboard。

在Dashboard填写Variables和Secrets

首次部署后,打开对应Worker的 设置变量与密钥,填写以下值。

普通变量

这些变量已经在 wrangler.jsonc 内声明,不需要手动添加,你可以根据需要修改。
名称说明
SSHWIFTY_AUTH_MODEgithub要求GitHub登录
SSHWIFTY_DIAL_TIMEOUT120SSH连接超时,单位秒
SSHWIFTY_HEARTBEAT_TIMEOUT10心跳间隔,单位秒
SSHWIFTY_ALLOWED_HOSTS例如 ssh.example.com:22,10.0.0.10:2222填写后只能连接指定的主机和端口,暂不支持通配符和网段
SSHWIFTY_PUBLIC_ACCESStrue允许无需密码即可进入Sshwifty入口
SSHWIFTY_PRESETS[]SSH preset JSON
SSHWIFTY_SERVER_MESSAGE任意提示文本可选

为避免Dashboard值与仓库配置不一致,建议将长期固定的非敏感值提交到 wrangler.jsonc;将环境专属值通过Dashboard管理。

Secrets

不要在任何地方暴露这些值,更不要将这些值写入 wrangler.jsonc

使用 添加密钥 添加以下值:

名称值来源用途
GITHUB_CLIENT_IDGitHub OAuth App的Client IDGitHub登录必需
GITHUB_CLIENT_SECRETGitHub OAuth App的Client SecretGitHub登录必需
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 处理

  1. 确认最新部署已完成,并且 DB 绑定指向正确的 sshwifty D1数据库。
  2. 打开 https://YOUR_WORKER_DOMAIN/sshwifty/
  3. 点击Sign in with GitHub并完成授权。
  4. OAuth callback会自动执行当前v1 schema的建表自检。

部署验证

  1. 打开 https://YOUR_WORKER_DOMAIN/sshwifty/
  2. 点击 Sign in with GitHub 并完成OAuth授权。
  3. 打开右上角账号菜单,复制Ed25519或RSA公钥。
  4. 将公钥写入目标服务器用户的 ~/.ssh/authorized_keys
  5. 新建SSH连接,在Authentication中选择 Saved Key
  6. 确认服务器指纹后,验证shell能打开。
  7. 再次打开连接窗口,确认远程服务器已出现在Connected before;编辑和删除操作应在刷新后保留。

遇到问题

请提交Issue

Copyright © 2026 Krab. Some rights reserved.
Built with Docus.