-
-
Notifications
You must be signed in to change notification settings - Fork 43
Architecture and Runtime Lifecycle
WebSSH is a Flask application with authenticated HTTP and Socket.IO interfaces, Paramiko SSH/SFTP channels, SQLite persistence, and a bounded threaded runtime.
Browser
|-- HTTPS/forms/API --------> Flask routes and blueprints
|-- Socket.IO controls -----> authenticated socket events
|-- streamed transfers -----> HTTP transfer routes
|
v
ownership and quota checks
|
+------------+-------------+
| |
SSH manager persistent storage
| SQLite + per-user files
Paramiko channels
|
SSH/SFTP servers
Bulk file content is streamed over HTTP. Socket.IO carries terminal traffic, control events, and bounded editor content rather than whole bulk-transfer payloads.
-
start.pycreates the application throughcreate_app()inapp/__init__.py. - Focused blueprints implement transfers, host keys, audit export, backup/restore, recovery codes, WebAuthn, OIDC, LDAP, and health/readiness.
-
app/socket_events.pydefines authenticated real-time contracts for terminal, SFTP, profiles, keys, commands, diagnostics, and transfers. -
app/ssh_manager.pyowns process-local SSH state. -
app/paramiko_channels.pycentralizes bounded Paramiko channel creation.
Production uses:
gunicorn --worker-class gthread --workers 1 --threads 64 \
--bind 0.0.0.0:5000 start:appExactly one worker is supported. Live Paramiko objects, session coordination, and parts of resource admission are process-local. Multiple workers would create isolated views of live state and can violate ownership, quota, cleanup, and routing assumptions.
Redis-backed rate limiting externalizes counters only. It does not externalize SSH channels or turn the application into a multi-worker architecture.
app/socket_capacity.py limits admitted sockets globally and per user. Capacity must leave at least four Gunicorn threads for ordinary HTTP work:
GUNICORN_THREADS - MAX_SOCKET_CONNECTIONS >= 4
The default is 64 threads and 48 sockets, with at most eight sockets per user. Socket.IO uses native threading and simple-websocket; Eventlet, greenlets, and monkey patching are not part of the supported runtime.
app/runtime_lifecycle.py owns a bounded ThreadPoolExecutor. Jobs have cancellation state, ownership, and explicit terminalization. LDAP cache cleanup, transfers, SSH/SFTP helper work, and other background tasks must share this bounded lifecycle instead of creating unlimited thread loops.
SSH connections belong to an authenticated user and consume quotas. Paramiko channels are created through existing helpers with timeouts and cancellation. Quick SFTP connections used by the file workspace remain alive while queued or active transfers still reference them, then disconnect when ownership can safely end.
Persistent tmux metadata survives a browser disconnect, but the underlying remote tmux session lives on the SSH server. WebSSH's local connection objects do not survive a process restart.
On shutdown WebSSH:
- closes admission for new runtime work;
- signals cancellable jobs;
- stops or terminalizes owned operations within the configured window;
- closes SSH/SFTP and Socket.IO resources;
- exits so the process supervisor can complete replacement or restart.
Readiness reports failure once the runtime is no longer accepting work. Keep the proxy/load-balancer drain period aligned with RUNTIME_SHUTDOWN_GRACE_SECONDS.
Restore operations enter maintenance mode before replacing persistent state. /health stays a liveness check, while /ready fails so traffic can be drained. Restore then terminates the process intentionally to guarantee a clean application state after replacement.
The frontend uses vanilla JavaScript and CSS without a build-time application framework. Browser libraries are pinned in package.json, vendored locally, and checked for integrity. Runtime CDN dependencies are intentionally absent so the frontend remains offline-capable and compatible with the Content Security Policy.
WebSSH documentation - Project - Issues - Discussions - Security
WebSSH Wiki
Install and operate
- Installation from Source
- Docker and Docker Compose
- Production Deployment
- Reverse Proxy and Subfolder Deployment
- Upgrading, Rollback, and FAQ
Identity and access
- Users and Account Management
- Authentication Overview
- LDAP and Active Directory
- OpenID Connect
- Passkeys and Recovery Codes
SSH and files
- SSH Connections and Host Keys
- Profiles, Jump Hosts, and Commands
- Terminal and Persistent tmux Sessions
- SFTP File Workspace and Transfers
- Tailscale SSH
Reference and administration