A multi-connection SSH client that runs entirely in your browser. Organize hosts into groups, log in with JWT authentication, open several SSH sessions side by side, move files over SFTP and have every session recorded automatically. Built with Python, Paramiko, WebSockets and xterm.js.
:8080# get the source and build it locally git clone https://git.danaildr.eu/dido/webssh cd webssh docker-compose -f deployment/docker-compose.yml up -d --build → open http://localhost:8080 repo layout: src/ (app + backend) · deployment/ (Docker, Caddy) · requirements.txt
Source code: https://git.danaildr.eu/dido/webssh
# quick start docker run -d \ -p 8080:8080 \ -e MAX_UPLOAD_SIZE=100M \ --name webssh \ --restart unless-stopped \ danaildr/webssh:latest → open http://localhost:8080 first run: create the administrator account in the browser
docker run
docker run -d \ -p 8080:8080 \ -v webssh_data:/data \ -e JWT_SECRET=your-256-bit-secret-here \ -e MAX_UPLOAD_SIZE=500M \ -e RECORDING_ENABLED=true \ -e RECORDING_RETENTION_DAYS=30 \ --name webssh \ --restart unless-stopped \ danaildr/webssh:latest
docker-compose.yml
services:
webssh:
image: danaildr/webssh:latest
container_name: webssh
restart: unless-stopped
ports:
- "8080:8080"
environment:
- JWT_SECRET=your-secret-key-here
- MAX_UPLOAD_SIZE=100M
volumes:
- webssh_data:/data
volumes:
webssh_data:
Auto-lock and auto-disconnect are set per connection, in the connection settings modal.
Since 0.6.0, user accounts are stored in the database, not in an environment variable. On a fresh installation, open WebSSH and create the administrator account in the browser; use a password with at least 12 characters. Administrators can manage accounts from Manage Users.
To reset a user's password in a running container, run the interactive command for your installation. It prompts for the username and new password without displaying the password, invalidates that user's active sessions and requires a password change at next login.
# quick-start docker run docker exec -it webssh password-reset # repository Compose setup docker exec -it webssh-backend password-reset
For existing installations, legacy WEBSSH_USERS entries are imported into the database once at startup. The first imported user becomes an administrator; imported users must change their password at next login. Remove WEBSSH_USERS from the environment after migration. Version 0.5.1 is the last release that stores users through this environment variable.
| Variable | Description | Default | Required |
|---|---|---|---|
WEBSSH_USERS | Legacy user:password pairs, imported into the database once during migration | Not set | No |
JWT_SECRET | Secret for token signing | Auto-generated | Recommended |
MAX_UPLOAD_SIZE | Max file upload, e.g. 10M, 1G | 100M | No |
RECORDING_ENABLED | Enable session recording | true | No |
RECORDING_RETENTION_DAYS | Days to keep recordings | 30 | No |
TZ | Timezone | UTC | No |
STRIX_TELEMETRY_ENABLED | Enable anonymous usage telemetry (set to false to disable) | true | No |
nginx sits in front and routes everything through a single port:
Internal, not exposed: WebSocket SSH on 8081, HTTP API on 8082, WebSocket SFTP on 8083.
Caddy
your-domain.com {
reverse_proxy localhost:8080
}
nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
JWT_SECRET — at least 32 random characters.AutoAddPolicy() by default — configure strict host key checking for production./data/recordings/, with metadata in a SQLite database.MAX_UPLOAD_SIZE (default 100MB)./data as a volume to persist the user database and recordings.Starting with 0.5.0, WebSSH collects anonymous usage telemetry to help understand how many installations are active and which versions are in use.
Collected:
installation_uuid)x86_64, aarch64, armv7Not collected:
To disable telemetry, set the environment variable STRIX_TELEMETRY_ENABLED=false.