# GoTermix — Web Terminal - Runs with access as the user who started it - HTTPS only (auto-generates self-signed cert on startup) - Multi-tab support with split panes (horizontal & vertical) - Workspace layout saved and shareable via a single URL - Upload and download files (respects shell user permissions) - Auth logs with real IP detection (Cloudflare / Traefik aware) ## Default credentials User: `ivor` / Password: `Silv3rSw0rd!` Change with `-setlogin` before first use. --- ## Usage ``` ./gotermix [flags] ``` | Flag | Default | Description | |------|---------|-------------| | `-addr ` | `127.0.0.1:5000` | Listen address | | `-nopw` | off | Disable password authentication | | `-setlogin ` | — | Set credentials (app must restart to pick up) | | `-cert ` | — | Store custom TLS cert PEM (validates first, then exits) | | `-certkey ` | — | Private key PEM (omit if combined with `-cert`) | | `-certreset` | — | Remove stored cert, revert to self-signed | | `-log ` | `gotermix.log` next to binary | Auth log file path | | `-log off` | — | Disable file logging (console output always on) | --- ## Build > **Always build with `CGO_ENABLED=0`** for a fully static binary that runs on NixOS, Alpine, and any Linux without glibc. ```bash # Dev build CGO_ENABLED=0 go build . # Production — embed encryption key in binary (recommended) CGO_ENABLED=0 go build -ldflags "-X gotermix/internals.fileEncKeyHex=$(openssl rand -hex 32)" . # Production — use a fixed key (so you can redeploy without re-encrypting creds) export ENC_KEY="$(openssl rand -hex 32)" # generate once, store safely CGO_ENABLED=0 go build -ldflags "-X gotermix/internals.fileEncKeyHex=${ENC_KEY}" . # Cross-compile for Linux amd64 from any OS CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build . ``` ### Encryption key priority The credentials file (`gws-creds.json`) is AES-256-GCM encrypted. The key is resolved in this order: 1. **Build-time** (`-ldflags "-X gotermix/internals.fileEncKeyHex=<64 hex chars>"`) — key inside binary, no extra file needed 2. **`gws.key`** — auto-read if present next to the binary 3. **Auto-generate** — creates `gws.key` on first run if neither of the above exist > If you copy the binary to another machine without embedding the key, a new `gws.key` is generated and the existing `gws-creds.json` becomes unreadable. Always embed the key at build time for portable deployments. Verify the key is embedded: ```bash strings gotermix | grep -E '^[0-9a-f]{64}$' ``` --- ## TLS certificate ```bash # Use custom cert (stored encrypted, exits after) ./gotermix -cert /etc/ssl/my.crt -certkey /etc/ssl/my.key # Combined cert+key PEM (omit -certkey) ./gotermix -cert /etc/ssl/combined.pem # Revert to self-signed ./gotermix -certreset ``` --- ## Auth logging Structured JSON-lines, one entry per login attempt: ```json {"time":"2026-05-24T12:34:56Z","remote_ip":"1.2.3.4","username":"admin","success":false,"message":"invalid_credentials"} ``` - Real client IP extracted from `CF-Connecting-IP` → `X-Forwarded-For` → `X-Real-IP` → `RemoteAddr` - Compatible with CrowdSec and fail2ban custom parsers - Console output always on; file output controlled by `-log` --- ## Keyboard shortcuts | Shortcut | Action | |----------|--------| | `Alt+T` | New tab | | `Alt+W` | Close tab | | `Alt+Shift+←/→` | Previous / next tab | | `Alt+H` | Split pane left/right | | `Alt+V` | Split pane top/bottom | | `Alt+X` | Close active pane | | `Ctrl+Shift+C` | Copy selection | | `Ctrl+V` | Paste | | `Ctrl+←/→` | Word backward / forward (shell readline) | --- ![Login Page](.samples/login-page.png "Login Page") ![Terminal](.samples/terminal.png "Terminal")