{"id":48581300,"url":"https://github.com/cc1a2b/shellgate","last_synced_at":"2026-04-08T17:01:12.230Z","repository":{"id":340842511,"uuid":"1167860641","full_name":"cc1a2b/shellgate","owner":"cc1a2b","description":"Instant web-based terminal access from a single binary","archived":false,"fork":false,"pushed_at":"2026-02-26T19:12:56.000Z","size":165,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-27T01:17:21.858Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cc1a2b.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T19:04:40.000Z","updated_at":"2026-02-26T19:13:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cc1a2b/shellgate","commit_stats":null,"previous_names":["cc1a2b/shellgate"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cc1a2b/shellgate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cc1a2b%2Fshellgate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cc1a2b%2Fshellgate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cc1a2b%2Fshellgate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cc1a2b%2Fshellgate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cc1a2b","download_url":"https://codeload.github.com/cc1a2b/shellgate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cc1a2b%2Fshellgate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31564915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-08T17:01:11.251Z","updated_at":"2026-04-08T17:01:12.220Z","avatar_url":"https://github.com/cc1a2b.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ShellGate\n\n**Your server is one click away.**\n\u003cimg width=\"3840\" height=\"2016\" alt=\"image\" src=\"https://github.com/user-attachments/assets/5d43a45b-16ec-4174-b5d6-3289d7a0c0d0\" /\u003e\n\nInstant web-based terminal access to any server from a single binary. Install with one command, get a secure browser terminal in seconds.\n\n[![CI](https://github.com/cc1a2b/shellgate/actions/workflows/ci.yml/badge.svg)](https://github.com/cc1a2b/shellgate/actions/workflows/ci.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/cc1a2b/shellgate)](https://goreportcard.com/report/github.com/cc1a2b/shellgate)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n---\n\n## Why ShellGate?\n\n- **Zero dependencies** — Single binary, embedded web assets. No Node.js, no Python, no runtime.\n- **Secure by default** — Auto-generated auth token, TLS support, fail2ban, GeoIP filtering. Never runs open.\n- **Telegram control plane** — Open/close your server, generate one-time access links, get real-time alerts — all from Telegram.\n- **Stealth mode** — Server starts silent. One Telegram command opens it on a random port with a one-time token, auto-closes after a TTL.\n- **Production-ready** — Session recording, sharing, audit logging, Prometheus metrics, webhook notifications.\n\n## Quick Start\n\n```bash\n# Install\ncurl -sL https://raw.githubusercontent.com/cc1a2b/shellgate/main/scripts/install.sh | bash\n\n# Run (auto-generates auth token)\nshellgate\n\n# Or with Go\ngo install github.com/cc1a2b/shellgate/cmd/shellgate@latest\nshellgate\n```\n\nOpen `http://your-server:8080?token=\u003cprinted-token\u003e` in your browser.\n\n## Usage\n\n```bash\n# Basic (auto token auth)\nshellgate\n\n# Password auth with TLS\nshellgate --auth password --password mysecret --tls\n\n# With Let's Encrypt\nshellgate --tls --domain myserver.example.com\n\n# Record sessions + enable sharing\nshellgate --record --share\n\n# Stealth mode with Telegram bot\nshellgate --stealth --telegram \\\n  --telegram-token \"$SHELLGATE_TELEGRAM_TOKEN\" \\\n  --telegram-users \"123456789\" \\\n  --external-host myserver.com --tls\n\n# GeoIP filtering (allow only specific countries)\nshellgate --geoip --geoip-db /path/to/GeoLite2-Country.mmdb \\\n  --allowed-countries \"US,GB,SA\"\n\n# Time-restricted access window\nshellgate --access-window-start 09:00 --access-window-end 17:00 \\\n  --access-window-tz \"Asia/Riyadh\"\n\n# Audit logging + Prometheus metrics\nshellgate --audit-log /var/log/shellgate.jsonl --metrics\n\n# Full hardened setup\nshellgate --tls --stealth --telegram \\\n  --telegram-token \"$SHELLGATE_TELEGRAM_TOKEN\" \\\n  --telegram-users \"123456789\" \\\n  --external-host myserver.com \\\n  --max-failed-attempts 5 --ban-duration 1h \\\n  --geoip --geoip-db /path/to/GeoLite2-Country.mmdb \\\n  --allowed-countries \"SA\" \\\n  --access-window-start 08:00 --access-window-end 22:00 \\\n  --access-window-tz \"Asia/Riyadh\" \\\n  --audit-log /var/log/shellgate.jsonl --metrics \\\n  --auto-close 2h --random-port\n```\n\n## Telegram Bot\n\nThe killer feature. Control ShellGate entirely from Telegram — no SSH, no open ports, no exposed surface.\n\n### Setup\n\n1. Create a bot via [@BotFather](https://t.me/BotFather) and get the token.\n2. Get your Telegram user ID (send `/start` to [@userinfobot](https://t.me/userinfobot)).\n3. Set the token as an environment variable:\n   ```bash\n   export SHELLGATE_TELEGRAM_TOKEN=\"your-bot-token\"\n   ```\n4. Start ShellGate with Telegram enabled:\n   ```bash\n   shellgate --telegram --telegram-users \"YOUR_USER_ID\" --external-host your-server.com --tls --stealth\n   ```\n\n### Commands\n\n| Command | Description |\n|---------|-------------|\n| `/open [duration]` | Start listener, generate one-time access link (e.g. `/open 2h`) |\n| `/close` | Stop listener, kill all sessions, revoke all tokens |\n| `/status` | Show server status, uptime, sessions, TLS, banned IPs |\n| `/sessions` | List active sessions with ID, IP, duration |\n| `/kill \u003cid\u003e` | Kill a specific session |\n| `/whitelist [ip]` | Add IP/CIDR to whitelist or list current |\n| `/unwhitelist \u003cip\u003e` | Remove IP/CIDR from whitelist |\n| `/ban [ip]` | Ban an IP or list banned IPs |\n| `/unban \u003cip\u003e` | Remove ban |\n| `/record` | Toggle session recording on/off |\n| `/share \u003cid\u003e` | Generate read-only share link for a session |\n| `/port [num]` | Show or change listening port |\n| `/help` | Show all commands |\n\n### `/open` Flow\n\n```\nYou send: /open 2h\n\nShellGate responds:\n  Server open on port 34821\n  https://myserver.com:34821/?token=a3f8c9...\n  Auto-closes in 2h\n\n→ Click the link from any device\n→ Full terminal in your browser\n→ Auto-closes and cleans up after 2h\n```\n\n### Real-Time Notifications\n\nThe bot sends alerts for:\n- New connections (IP, user-agent)\n- Disconnections (session duration)\n- Failed auth attempts\n- IP bans (fail2ban triggers)\n- Server start/stop\n\n## Stealth Mode\n\nStart the server without opening any ports. The listener only activates when you send `/open` via Telegram.\n\n```bash\nshellgate --stealth --random-port --auto-close 1h --telegram ...\n```\n\n- `--stealth` — Don't listen on startup. Wait for Telegram `/open`.\n- `--random-port` — Pick a random port (10000-65000) on each `/open`.\n- `--auto-close 1h` — Automatically close after the TTL expires.\n- `--port-range-min` / `--port-range-max` — Custom port range.\n\n## Security\n\nShellGate is designed with security as a first-class concern:\n\n- **Never runs without auth** unless you explicitly pass `--auth none --i-know-what-im-doing`\n- **Token auth**: 256-bit random token, constant-time comparison\n- **Password auth**: bcrypt hashing, rate-limited login (5 attempts/min/IP)\n- **TOTP 2FA**: RFC 6238 compatible, works with Google Authenticator/Authy\n- **One-time tokens**: 32-byte crypto random, single use, short TTL (via Telegram `/open`)\n- **TLS**: Self-signed (ED25519), Let's Encrypt auto-TLS, or custom certificates\n- **Session cookies**: HttpOnly, Secure, SameSite=Strict, HMAC-SHA256 signed\n- **Security headers**: CSP, X-Frame-Options, X-Content-Type-Options\n- **Fail2ban**: Auto-ban IPs after N failed auth attempts (configurable threshold and duration)\n- **GeoIP filtering**: Allow/block by country code using MaxMind GeoLite2\n- **Time-window access**: Restrict access to specific hours and timezone\n- **Dynamic IP whitelist**: Add/remove CIDRs at runtime via Telegram\n- **Stealth mode**: Zero attack surface when not in use\n\nSee [SECURITY.md](SECURITY.md) for the full security policy.\n\n## Audit \u0026 Monitoring\n\n### Audit Log\n\nJSON-lines structured audit log:\n\n```bash\nshellgate --audit-log /var/log/shellgate.jsonl\n```\n\n```json\n{\"timestamp\":\"2026-02-26T20:00:00Z\",\"event\":\"session_create\",\"session_id\":\"abc123\",\"client_ip\":\"1.2.3.4\",\"country\":\"SA\",\"detail\":\"new session\"}\n{\"timestamp\":\"2026-02-26T20:05:00Z\",\"event\":\"auth_failure\",\"client_ip\":\"5.6.7.8\",\"country\":\"CN\",\"detail\":\"invalid credentials\"}\n```\n\nEvents: `auth`, `auth_failure`, `session_create`, `session_close`, `session_kill`, `connect`, `disconnect`, `ip_banned`, `server_start`, `server_stop`\n\n### Prometheus Metrics\n\n```bash\nshellgate --metrics\n# GET /metrics\n```\n\n```\nshellgate_connections_total 42\nshellgate_auth_success_total 38\nshellgate_auth_failure_total 4\nshellgate_sessions_active 2\nshellgate_sessions_created_total 15\nshellgate_sessions_closed_total 13\nshellgate_banned_ips 1\nshellgate_ws_messages_in_total 1024\nshellgate_ws_messages_out_total 8192\n```\n\n### Webhook Notifications\n\nForward audit events to Slack, Discord, or any HTTP endpoint:\n\n```bash\nshellgate --webhook-url \"https://hooks.slack.com/services/...\" \\\n  --webhook-events \"auth_failure,ip_banned,connect,disconnect\"\n```\n\n## All Flags\n\n### Server\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--host` | `0.0.0.0` | Bind address |\n| `--port` | `8080` | Listen port |\n| `--shell` | `$SHELL` | Shell to spawn |\n| `--verbose` | `false` | Debug logging |\n\n### Authentication\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--auth` | `token` | Auth mode: `none\\|token\\|password\\|otp` |\n| `--token` | auto | Static auth token (env: `SHELLGATE_TOKEN`) |\n| `--password` | | Password for web login |\n| `--allow-ip` | | Initial CIDR whitelist (comma-separated) |\n| `--rate-limit` | `10` | Requests/sec per IP (0=disable) |\n| `--i-know-what-im-doing` | `false` | Acknowledge running without auth |\n\n### TLS\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--tls` | `false` | Enable TLS |\n| `--domain` | | Domain for Let's Encrypt auto-TLS |\n| `--cert` | | Custom TLS cert path |\n| `--key` | | Custom TLS key path |\n\n### Sessions\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--max-sessions` | `5` | Max concurrent sessions |\n| `--timeout` | `30m` | Session timeout (0=no timeout) |\n| `--idle-timeout` | `10m` | Idle timeout (0=no timeout) |\n| `--record` | `false` | Enable asciicast v2 recording |\n| `--record-dir` | `~/.shellgate/recordings` | Recording directory |\n| `--share` | `false` | Enable session sharing |\n| `--share-ttl` | `1h` | Share link TTL |\n| `--share-max-viewers` | `10` | Max viewers per share |\n\n### Access Control\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--max-failed-attempts` | `10` | Auth failures before IP ban (0=disable) |\n| `--ban-duration` | `15m` | Duration of IP bans |\n| `--geoip` | `false` | Enable GeoIP filtering |\n| `--geoip-db` | | Path to MaxMind GeoLite2 `.mmdb` file |\n| `--allowed-countries` | | Allowed country codes (comma-separated) |\n| `--blocked-countries` | | Blocked country codes (comma-separated) |\n| `--access-window-start` | | Access window start time (`HH:MM`) |\n| `--access-window-end` | | Access window end time (`HH:MM`) |\n| `--access-window-tz` | | Access window timezone (e.g. `Asia/Riyadh`) |\n\n### Stealth Mode\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--stealth` | `false` | Don't listen on startup (wait for `/open`) |\n| `--random-port` | `false` | Random port on each `/open` |\n| `--port-range-min` | `10000` | Min port for random selection |\n| `--port-range-max` | `65000` | Max port for random selection |\n| `--auto-close` | | Auto-close listener after duration (e.g. `1h`) |\n\n### Telegram\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--telegram` | `false` | Enable Telegram bot |\n| `--telegram-token` | | Bot token (env: `SHELLGATE_TELEGRAM_TOKEN`) |\n| `--telegram-users` | | Allowed user IDs (comma-separated) |\n| `--external-host` | | External hostname for access links |\n\n### Audit \u0026 Monitoring\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--audit-log` | | Path to audit log file (JSON lines) |\n| `--webhook-url` | | Webhook URL for event notifications |\n| `--webhook-events` | | Event types to forward (comma-separated) |\n| `--metrics` | `false` | Enable `/metrics` endpoint (Prometheus) |\n\n## Subcommands\n\n```bash\nshellgate                    # Start server (default)\nshellgate serve              # Explicit start\nshellgate setup-otp          # Configure TOTP 2FA\nshellgate sessions           # List active sessions\nshellgate version            # Version info\nshellgate completion bash    # Shell completions\n```\n\n## Configuration\n\nConfig file at `~/.shellgate/config.yaml`:\n\n```yaml\nhost: 0.0.0.0\nport: 8080\nshell: /bin/bash\nauth: token\nrate-limit: 10\nmax-sessions: 5\ntimeout: 30m\nidle-timeout: 10m\n```\n\nEnvironment variables: `SHELLGATE_PORT`, `SHELLGATE_TOKEN`, `SHELLGATE_TELEGRAM_TOKEN`, etc.\n\nPriority: CLI flags \u003e environment \u003e config file \u003e defaults.\n\n## Comparison\n\n| Feature | ShellGate | ttyd | gotty | wetty |\n|---------|-----------|------|-------|-------|\n| Single binary | Yes | Yes | Yes | No |\n| Telegram control | Yes | No | No | No |\n| Stealth mode | Yes | No | No | No |\n| Fail2ban / GeoIP | Yes | No | No | No |\n| Session sharing | Yes | No | Read-only | No |\n| Session recording | Yes | No | No | No |\n| Auto TLS | Yes | No | No | No |\n| 2FA/OTP | Yes | No | No | No |\n| Audit log | Yes | No | No | No |\n| Prometheus metrics | Yes | No | No | No |\n| Auth built-in | Token/Password/OTP | Basic | Basic | SSH |\n| Config file | Yes | No | No | Yes |\n\n## Architecture\n\n```\n                          Telegram Bot (out-of-band)\n                               |\n                          Bot Commands\n                               |\nBrowser (xterm.js) \u003c--WS--\u003e ShellGate Binary \u003c---\u003e Audit Logger\n                               |                      |\n                  +------------+------------+    Webhook / Metrics\n                  |            |            |\n               HTTP Srv    PTY Mgr    Session Ctrl\n                  |            |            |\n               Auth + TLS + ACL + Rate Limit + Recording\n                  |\n         Fail2ban + GeoIP + Time Windows\n```\n\nAll frontend assets are embedded in the binary via `embed.FS`.\n\n## Building from Source\n\n```bash\ngit clone https://github.com/cc1a2b/shellgate.git\ncd shellgate\nmake build\n./shellgate\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcc1a2b%2Fshellgate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcc1a2b%2Fshellgate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcc1a2b%2Fshellgate/lists"}