A network-traversing, web-based terminal emulator. ShellFromBrowser works everywhere a browser can open a website — airports, train stations, corporate networks, anywhere. It uses standard HTTPS on port 443: no firewall can tell it apart from a regular web visit.
A modern, cross-platform terminal emulator written in Go. Spiritual successor to ShellInBox — rebuilt from scratch with WebSocket, xterm.js, SSH client support, multi-sessions, file transfer, and session recording.
| Feature | Description |
|---|---|
| Browser-based terminal | Full xterm.js emulation — 256 colors, Unicode, mouse support, clipboard |
| Multi-session tabs | Open multiple terminal sessions in one browser window, switch between them |
| SSH client | Connect to remote hosts directly from the browser (user@host:port) |
| Authentication | JWT-based auth with bcrypt password hashing, configurable per-user |
| TLS/HTTPS | Built-in TLS support — just provide cert and key paths |
| File transfer | Upload/download files through the web interface with path traversal protection |
| Session recording | Record and replay terminal sessions in asciicast v2 format (asciinema-compatible) |
| Cross-platform | Runs natively on Linux, macOS, and Windows (ConPTY) |
| Single binary | Zero runtime dependencies — frontend, assets, everything embedded via go:embed |
| Docker ready | Multi-stage Dockerfile + docker-compose included |
The fastest way to try ShellFromBrowser. Works on Windows, macOS, and Linux — Go handles the cross-platform differences automatically.
git clone https://github.com/valorisa/ShellFromBrowser.git
cd ShellFromBrowser
# Launch directly without installing (compiles and runs in one step)
go run ./cmd/shellfbThen open http://localhost:4200 in your browser. You should see an interactive terminal (xterm.js).
This does not install anything on your system. It compiles a temporary binary and runs it. Stop it with
Ctrl+C.
Installs the shellfb binary into your $GOPATH/bin (or %GOPATH%\bin on Windows), making it available system-wide.
go install github.com/valorisa/ShellFromBrowser/cmd/shellfb@latest
# Run with defaults (no auth, port 4200)
shellfb
# Run with custom address
shellfb --addr :3000
# Run with configuration file
shellfb --config config.yaml
# Display version
shellfb --versionThen open http://localhost:4200 (or your custom port) in your browser. Stop it with Ctrl+C.
The default docker-compose.yml exposes ports 80/443 with auto-TLS — designed for deployment on restricted networks (airports, train stations, corporate firewalls) where only standard HTTPS traffic passes through.
git clone https://github.com/valorisa/ShellFromBrowser.git
cd ShellFromBrowser
# Create your configuration
cp config.example.yaml config.yaml
# Edit config.yaml: set your domain, auth, etc.
docker compose up -dOpen https://your-domain.com — the terminal is ready. To stop: docker compose down.
Local testing with Docker? You can run without TLS:
docker build -t shellfb . docker run --rm --name shellfb-test -p 4200:4200 shellfbThen open http://localhost:4200. Stop it with
Ctrl+C, or from another terminal:docker stop shellfb-test.
Compiles the binary into ./bin/shellfb. Useful for development or packaging.
git clone https://github.com/valorisa/ShellFromBrowser.git
cd ShellFromBrowser
# Build the binary
make build
# Run it
./bin/shellfb
# Run the test suite
make testThen open http://localhost:4200 in your browser. Stop it with Ctrl+C.
Copy config.example.yaml to config.yaml and customize:
server:
addr: ":4200"
tls:
enabled: true
cert: "/path/to/cert.pem"
key: "/path/to/key.pem"
auth:
enabled: true
jwt_secret: "generate-a-random-string-here"
users:
- username: admin
password_hash: "$2a$10$..."
- username: developer
password_hash: "$2a$10$..."
shell:
# Leave empty for system default (SHELL on Unix, COMSPEC on Windows)
command: ""
env:
- "TERM=xterm-256color"
sessions:
max_per_user: 10
idle_timeout: "30m"
ssh:
enabled: true
known_hosts: "~/.ssh/known_hosts"
recording:
enabled: true
dir: "./recordings"shellfb hash-password
# Enter password: ********
# $2a$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxCopy the output into your config.yaml under password_hash.
| Flag | Default | Description |
|---|---|---|
--addr |
:4200 |
Listen address (overrides config file) |
--config |
none | Path to YAML configuration file |
--version |
— | Print version and exit |
Subcommands:
| Command | Description |
|---|---|
hash-password |
Generate a bcrypt hash for use in config |
Connect to remote hosts directly from the browser by opening a WebSocket connection to /ws/ssh:
ws://localhost:4200/ws/ssh?target=user@host.com:22&password=secret&token=JWT_TOKEN
Parameters:
target(required): SSH target in formatuser@host:port(port defaults to 22)password: Password authenticationkey: Path to private key file (server-side)token: JWT authentication token
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/login |
No | Authenticate and receive JWT token |
| GET | /api/sessions |
Yes | List active terminal sessions |
| DELETE | /api/sessions?id=X |
Yes | Destroy a specific session |
| POST | /api/upload |
Yes | Upload a file (multipart) |
| GET | /api/download?file=X |
Yes | Download a file |
| GET | /api/recordings |
Yes | List recorded sessions |
| GET | /api/recordings/get?id=X |
Yes | Get recording data (asciicast v2) |
| WS | /ws |
Yes | Terminal WebSocket (local shell) |
| WS | /ws/ssh |
Yes | SSH WebSocket (remote host) |
- Authentication: JWT tokens with configurable expiry (24h default)
- Rate limiting: Login endpoint limited to 5 attempts per minute per IP
- Security headers: CSP, X-Frame-Options (DENY), X-Content-Type-Options, Referrer-Policy
- Path traversal protection: All file operations validated against base directory
- No eval(): No inline scripts, no dynamic code execution in frontend
- TLS: Built-in HTTPS support — no reverse proxy required
- WebSocket auth: All WebSocket connections require valid JWT token when auth is enabled
ShellFromBrowser/
├── cmd/shellfb/ # Entry point, CLI
├── internal/
│ ├── auth/ # JWT + bcrypt authentication
│ ├── config/ # YAML configuration
│ ├── recording/ # Asciicast v2 session recording
│ ├── server/ # HTTP server, WebSocket, middleware
│ ├── ssh/ # SSH client wrapper
│ ├── terminal/ # PTY session management (Unix + Windows)
│ └── transfer/ # File upload/download
├── web/
│ └── static/ # Embedded frontend (xterm.js, CSS, JS)
├── config.example.yaml # Example configuration
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Ready-to-use deployment
└── Makefile # Build automation
MIT — Copyright (c) 2026 valorisa