Sshwifty Plus
Repository: https://github.com/krab-lab/sshwifty-plus
SSHWIFTY_KEY_ENCRYPTION_SECRET can decrypt the database at any time and obtain your server addresses and SSH private keys. Deploy the service yourself and protect it with appropriate Zero Trust access controls.Feature Changes
The following changes have been made on top of the upstream Sshwifty project.
Workers and Static Assets
- A Cloudflare Worker hosts the static UI and handles
/sshwifty/socketWebSocket SSH traffic. - Only SSH is supported. Telnet, server hooks, SOCKS5, and server-side
file://private-key loading are not available. - The SSH client uses
ssh2with an algorithm set compatible with Cloudflare Workers.
GitHub Sign-In and Account Keys
GitHub OAuth is required when SSHWIFTY_AUTH_MODE is set to github.
- Each GitHub account receives an Ed25519 key pair and an RSA 4096-bit key pair on first sign-in.
- Users can view and copy public keys from the account window.
- Private keys are encrypted with
SSHWIFTY_KEY_ENCRYPTION_SECRETand stored in Cloudflare D1. - SSH Authentication supports
Saved Key; selecting it uses the managed key to connect to the remote server. - When
Saved Keyis selected, the Worker tries the Ed25519 key first and then the RSA key.
Remote Server Records
The Connected before list is stored in D1 for each GitHub account.
- Remote records are saved automatically after a successful SSH connection.
- Users can edit or delete saved records.
- Passwords, uploaded private keys, and other connection credentials are not stored in remote records.
Deployment
You need the following:
- A Cloudflare account with Workers and D1 enabled.
- A fork of this repository in your own GitHub account.
Create a D1 Database in the Cloudflare Dashboard
- Sign in to the Cloudflare Dashboard.
- Open Storage & Databases, then select D1 SQL Database.
- Click Create database and name it
sshwifty. - Copy the database ID after creation. It is a UUID such as
84fa53bb-3b6b-4d23-9f28-bfdcc23aa243.
Check the Repository Configuration
Deployment is configured through the root wrangler.jsonc. Before connecting the repository, confirm that the D1 binding looks like this:
"d1_databases": [
{
"binding": "DB",
"database_name": "sshwifty",
"database_id": "YOUR_D1_DATABASE_ID",
"migrations_dir": "worker/migrations"
}
]
Write the database ID from the previous step into database_id and commit it to the deployment branch. You can edit and commit wrangler.jsonc in the GitHub web editor.
wrangler.jsonc is the configuration source for Git deployments. Do not configure conflicting databases for the same binding in both the Dashboard and the repository.Connect the GitHub Repository in Cloudflare
- Open Workers & Pages.
- Create an application and select
Continue with GitHub. - Authorize Cloudflare to access GitHub and select the repository containing this project.
- In the build configuration, enter the following values:
| Setting | Value |
|---|---|
| Project name | sshwifty-plus |
| Root directory | / |
| Build command | npm run generate |
| Deploy command | npx wrangler deploy |
- Save the settings and start the first deployment.
After deployment, confirm that the following binding exists in the Worker's Bindings settings:
- Type: D1 database
- Name:
DB - Value:
sshwifty
Create a GitHub OAuth App
Copy the production URL from the Worker's Domains settings, or add a custom domain.
- Open GitHub Settings -> Developer settings -> OAuth Apps.
- Click
New OAuth App. - Set the Authorization callback URL to:
https://YOUR_WORKER_DOMAIN/sshwifty/auth/github/callback
For example, if the Worker is available at https://sshwifty.example.com, the callback URL must be:
https://sshwifty.example.com/sshwifty/auth/github/callback
- Click
Generate a new client secretand record the GitHub OAuth App Client ID and Client Secret. They are entered in the Cloudflare Dashboard in the next step.
Set Variables and Secrets in the Dashboard
After the first deployment, open the Worker's Settings -> Variables and Secrets and configure the following values.
Variables
wrangler.jsonc; you do not need to add them manually. You can change them when needed.| Name | Value | Description |
|---|---|---|
SSHWIFTY_AUTH_MODE | github | Requires GitHub sign-in |
SSHWIFTY_DIAL_TIMEOUT | 120 | SSH connection timeout in seconds |
SSHWIFTY_HEARTBEAT_TIMEOUT | 10 | Heartbeat interval in seconds |
SSHWIFTY_ALLOWED_HOSTS | For example, ssh.example.com:22,10.0.0.10:2222 | When set, only the listed hosts and ports may be connected to; wildcards and CIDR ranges are not supported |
SSHWIFTY_PUBLIC_ACCESS | true | Allows entry to Sshwifty without a passphrase |
SSHWIFTY_PRESETS | [] | SSH preset JSON |
SSHWIFTY_SERVER_MESSAGE | Any message | Optional |
To avoid differences between Dashboard values and repository configuration, commit long-lived non-sensitive values to wrangler.jsonc and manage environment-specific values in the Dashboard.
Secrets
wrangler.jsonc.Use Add -> Secret to add the following values:
| Name | Value source | Purpose |
|---|---|---|
GITHUB_CLIENT_ID | GitHub OAuth App Client ID | Required for GitHub sign-in |
GITHUB_CLIENT_SECRET | GitHub OAuth App Client Secret | Required for GitHub sign-in |
SSHWIFTY_SHARED_KEY | A password you choose | Optional. When SSHWIFTY_PUBLIC_ACCESS is disabled, users must enter this passphrase before using Sshwifty |
SSHWIFTY_SESSION_SECRET | A strong random value you generate | Signs session and OAuth state cookies |
SSHWIFTY_KEY_ENCRYPTION_SECRET | A strong random value you generate | Encrypts SSH private keys stored in D1 |
For the last two values, generate random strings of at least 32 bytes and paste them into the Dashboard. They must be different.
PSWD by MAZE is recommended. Enable Include Uppercase Letters, Include Lowercase Letters, and Include Numbers.
SSHWIFTY_SESSION_SECRET signs out all active users.SSHWIFTY_KEY_ENCRYPTION_SECRET. If it is lost, existing managed SSH private keys in D1 cannot be decrypted.After saving variables or secrets, retry the deployment in the Dashboard or push an empty commit to GitHub to create a new Worker version.
D1 Handling After the First Deployment
- Confirm that the latest deployment is complete and that the
DBbinding points to the correctsshwiftyD1 database. - Open
https://YOUR_WORKER_DOMAIN/sshwifty/. - Select Sign in with GitHub and complete authorization.
- The OAuth callback automatically runs the current v1 schema initialization check.
Deployment Verification
- Open
https://YOUR_WORKER_DOMAIN/sshwifty/. - Select
Sign in with GitHuband complete GitHub OAuth authorization. - Open the account menu and copy the Ed25519 or RSA public key.
- Add the public key to the destination server user's
~/.ssh/authorized_keysfile. - Create a new SSH connection and select
Saved Keyunder Authentication. - Confirm the server fingerprint and verify that the shell opens.
- Reopen the connection dialog and confirm that the remote appears in Connected before. Edit and delete actions should persist after a reload.
Issues
Please open an Issue.