# StrixWebSSH - Browser-based SSH Client Multi-connection SSH client that runs in your browser with JWT authentication. ## Features - **Multi-connection support**: Manage multiple SSH connections simultaneously - **JWT Authentication**: Secure login system with token-based authentication - **Password & SSH Key auth**: Support for both password and SSH key authentication - **SFTP File Manager**: Built-in file manager with upload/download capabilities - **Terminal emulator**: Uses xterm.js for a full terminal experience - **Connection management**: Sidebar with connection list, status indicators, and quick actions - **Remote load monitoring**: Active SSH connections display the remote Linux 1/5/15-minute load average - **Session Recording**: Automatic recording of SSH sessions in asciinema format with playback and configurable retention - **Dark theme**: Modern dark UI design - **Single port**: All services run through port 8080 (HTTP API + WebSocket) ## Quick Start ### 1. Start the Backend ```bash docker-compose -f deployment/docker-compose.yml up -d --build ``` ### 2. Open the Client Open http://localhost:8080 in your browser. The application is served via a Caddy reverse proxy. ### 3. Login Default credentials: - Username: `admin` - Password: `admin` ## Configuration ### Users Set users via environment variable in `deployment/docker-compose.yml`: ```yaml environment: - STRIXWEBSSH_USERS=user1:pass1,user2:pass2 ``` ### JWT Secret Set custom JWT secret: ```yaml environment: - JWT_SECRET=your-secret-key-here ``` If not set, a random secret is generated on startup. ### Max Upload Size Set maximum file upload size (default: 100MB): ```yaml environment: - MAX_UPLOAD_SIZE=50M ``` Supported formats: `10M`, `100MB`, `1G`, `1GB`, or bytes as integer. ### Session Recording Configure automatic session recording (default: enabled, 30 days retention): ```yaml environment: - RECORDING_ENABLED=true - RECORDING_RETENTION_DAYS=30 ``` - `RECORDING_ENABLED`: Enable/disable session recording (`true` or `false`) - `RECORDING_RETENTION_DAYS`: Number of days to keep recordings before automatic deletion Recordings are stored in `/data/recordings/` in asciinema v2 format (gzip compressed). ## Ports - `8080` - HTTP API and WebSocket (Caddy reverse proxy) All traffic goes through port 8080. Caddy routes: - `/ws` → WebSocket SSH server (internal port 8081) - `/api/` → HTTP API endpoints (internal port 8082) - Everything else → Static files (served from the repository `index.html` + `static/`) ## File Structure ``` web-ssh/ ├── src/ # Application source code │ ├── run.py # Backend entry point │ ├── serve_static.py # Static file server │ ├── index.html # Main client interface │ ├── help.html # Help documentation │ ├── static/ # Frontend assets │ └── webssh_backend/ # Backend package ├── deployment/ # Docker and deployment files │ ├── docker-compose.yml │ ├── Dockerfile │ ├── Caddyfile │ ├── docker-entrypoint.sh │ └── scripts/ ├── requirements.txt # Python dependencies ├── run.py # Compatibility wrapper from repo root ├── serve_static.py # Compatibility wrapper from repo root ├── README.md # This file └── .github/workflows/ # CI/CD ``` ## API Endpoints ### POST /api/login Login and get JWT token. Request: ```json { "username": "admin", "password": "admin" } ``` Response: ```json { "token": "eyJ0eXAiOiJKV1QiLCJhbGc...", "username": "admin", "expires": "2024-01-20T12:00:00+00:00" } ``` ### POST /api/verify Verify JWT token validity. Request: ```json { "token": "eyJ0eXAiOiJKV1QiLCJhbGc..." } ``` Response: ```json { "valid": true, "username": "admin" } ``` ## WebSocket Protocol Connect to `ws://localhost:8080/ws?token=` After connection, send SSH credentials: ```json { "host": "192.168.1.100", "port": 22, "username": "root", "password": "secret", "key": "-----BEGIN OPENSSH PRIVATE KEY-----..." } ``` ## Reverse Proxy Configuration ### Caddy ```caddyfile your-domain.com { reverse_proxy localhost:8080 } ``` ### Caddy ```caddyfile { auto_https off } :8080 { handle_path /ws* { reverse_proxy strixwebssh:8081 } handle_path /api/* { reverse_proxy strixwebssh:8082 } route { root * /srv try_files {path} /index.html file_server } } ``` ## Docker Hub Pre-built multi-arch images available: ```bash docker pull danaildr/strixwebssh:latest docker pull danaildr/strixwebssh:0.3.1 ``` Supported architectures: `linux/amd64`, `linux/arm64` ## Security Notes - Always use HTTPS in production (configure reverse proxy with SSL) - Change default credentials - Set a strong JWT_SECRET - The backend uses `AutoAddPolicy()` for SSH host keys (testing only - change for production) - Token expiry: 8 hours - File upload limit: configurable via MAX_UPLOAD_SIZE (default 100MB) ## Building and Publishing ### Local Build ```bash docker-compose up -d --build ``` ### Build for Docker Hub (Multi-arch) ```bash ./docker-build-and-push.sh --build ``` This builds and pushes both `linux/amd64` and `linux/arm64` images with tags `latest` and version tag. ### Version Management ```bash ./version-manager.sh ``` Interactive script to update version numbers across all files. ## Development ```bash # Install dependencies pip install -r requirements.txt # Run backend directly (for development) python start_backend.py # Note: When running directly, services use internal ports: # - WebSocket SSH: port 8081 # - HTTP API: port 8082 # - WebSocket SFTP: port 8083 # # Use docker-compose for production deployment with Caddy on port 8080 ```