446 lines
No EOL
17 KiB
Markdown
446 lines
No EOL
17 KiB
Markdown
# WebSSH2 - Web SSH Client
|
|
|
|

|
|
|
|
WebSSH2 is an HTML5 web-based terminal emulator and SSH client. It uses SSH2 as a client on a host to proxy a Websocket / Socket.io connection to an SSH2 server.
|
|
|
|

|
|
|
|

|
|
|
|
## Table of Contents
|
|
|
|
- [Requirements](#requirements)
|
|
- [Breaking Changes](#breaking-changes)
|
|
- [Installation](#installation)
|
|
- [Docker Setup](#docker-setup)
|
|
- [Usage](#usage)
|
|
- [Configuration](#configuration)
|
|
- [Features](#features)
|
|
- [Routes](#routes)
|
|
- [Client-Side Module](#client-side-module)
|
|
- [Tips](#tips)
|
|
- [Support](#support)
|
|
|
|
## Requirements
|
|
|
|
- Node.js 6.9.1
|
|
|
|
## Breaking Changes
|
|
- See [CONFIG.md](./CONFIG.md) for a list of breaking changes to the config.json file.
|
|
- See [DEPRECATED.md](./DEPRECATED.md) for a list of deprecated options.
|
|
|
|
## Installation
|
|
|
|
1. Clone the repository:
|
|
```
|
|
git clone https://github.com/billchurch/webssh2.git
|
|
cd webssh2
|
|
```
|
|
|
|
2. Install dependencies:
|
|
```
|
|
npm install --production
|
|
```
|
|
For development purposes, use `npm install` instead.
|
|
|
|
3. Configure the application by editing `config.json` if needed.
|
|
|
|
4. Start the server:
|
|
```
|
|
npm start
|
|
```
|
|
|
|
## Docker Setup
|
|
|
|
1. Build and run the Docker container (with debug messages):
|
|
```bash
|
|
docker build -t webssh2 .
|
|
docker run --name webssh2 --rm -it -p 2222:2222 -e "DEBUG=webssh2*,-webssh2:ssh2" webssh2
|
|
```
|
|
|
|
### Important Note About Configuration Files
|
|
|
|
As of recent versions, the configuration file location has moved from `/usr/src` to `/usr/src/app` in the Docker container. This change improves organization but requires attention when mounting custom configuration files.
|
|
|
|
To use a custom configuration file with the Docker container, mount your `config.json` to the new location using:
|
|
|
|
```bash
|
|
docker run -it --rm --name webssh2 \
|
|
-p 2222:2222 \
|
|
-e DEBUG="webssh2*" \
|
|
-v "$(pwd)/config.json:/usr/src/app/config.json" \
|
|
billchurch/webssh2:bigip-server
|
|
```
|
|
|
|
Note:
|
|
- If you previously mounted your configuration file to `/usr/src/config.json`, it will not be detected. The container will silently fall back to default configuration.
|
|
- The new location at `/usr/src/app/config.json` is the only valid path for custom configuration files.
|
|
- The default configuration provides basic functionality, so missing custom configurations may not be immediately apparent.
|
|
|
|
## Usage
|
|
|
|
Access the web client by navigating to:
|
|
|
|
```
|
|
http://localhost:2222/ssh
|
|
```
|
|
|
|
You'll be prompted for host details and SSH credentials.
|
|
|
|
Alternatively you may use the `/ssh/host/<host>` route:
|
|
|
|
```
|
|
http://localhost:2222/ssh/host/127.0.0.1
|
|
```
|
|
|
|
You'll be prompted for SSH credentials via HTTP Basic Authentication.
|
|
P
|
|
## Configuration
|
|
|
|
### GET Parameters
|
|
|
|
- `port=` - _integer_ - SSH server port (default: `22`)
|
|
- `header=` - _string_ - Optional header text
|
|
- `headerBackground=` - _string_ - Optional background color (default: `"green"`)
|
|
- `sshterm=` - _string_ - Terminal type for pty (default: xterm-color)
|
|
|
|
### Config File Options
|
|
|
|
Edit `config.json` to customize the following options:
|
|
|
|
- `listen.ip` - _string_ - IP address to listen on (default: `"127.0.0.1"`)
|
|
- `listen.port` - _integer_ - Port to listen on (default: `2222`)
|
|
- `http.origins` - _array_ - CORS origins for socket.io (default: `["*:*"]`)
|
|
- `user.name` - _string_ - Default SSH username (default: `null`)
|
|
- `user.password` - _string_ - Default SSH password (default: `null`)
|
|
- `ssh.host` - _string_ - Default SSH host (default: `null`)
|
|
- `user.privateKey` - _string_ - Default SSH private key (default: `null`)
|
|
- `ssh.port` - _integer_ - Default SSH port (default: `22`)
|
|
- `ssh.term` - _string_ - Terminal emulation (default: `"xterm-color"`)
|
|
- `ssh.readyTimeout` - _integer_ - SSH handshake timeout in ms (default: `20000`)
|
|
- `ssh.keepaliveInterval` - _integer_ - SSH keepalive interval in ms (default: `120000`)
|
|
- `ssh.keepaliveCountMax` - _integer_ - Max SSH keepalive packets (default: `10`)
|
|
- `ssh.disableInteractiveAuth` - _boolean_ - When set to `true`, prevents interactive authentication through the web interface. Users must use Basic Authentication via the `/ssh/host/<host>` route. (default: `false`)
|
|
- `ssh.algorithms.cipher` - _array_ - Supported cipher algorithms (default: `["aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm", "aes128-gcm@openssh.com", "aes256-gcm", "aes256-gcm@openssh.com", "aes256-cbc"]`)
|
|
- `ssh.algorithms.compress` - _array_ - Supported compression methods (default: `["none", "zlib@openssh.com", "zlib"]`)
|
|
- `ssh.algorithms.hmac` - _array_ - Supported HMAC algorithms (default: `["hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"]`)
|
|
- `ssh.algorithms.kex` - _array_ - Supported key exchange methods (default: `["ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group-exchange-sha256", "diffie-hellman-group14-sha1"]`)
|
|
- `ssh.algorithms.serverHostKey` - _array_ - Supported host key types (default: `["ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "ssh-rsa"]`)
|
|
- `header.text` - _string_ - Header text (default: `null`)
|
|
- `header.background` - _string_ - Header background color (default: `"green"`)
|
|
- `session.name` - _string_ - Session cookie name (default: `"webssh2.sid"`)
|
|
- `session.secret` - _string_ - Session secret key (default: `crypto.randomBytes(32).toString("hex")`)
|
|
- `options.challengeButton` - _boolean_ - Enable challenge button (default: `true`)
|
|
- `options.autoLog` - _boolean_ - Enable auto-logging (default: `false`)
|
|
- `options.allowReauth` - _boolean_ - Allow reauthentication (default: `true`)
|
|
- `options.allowReconnect` - _boolean_ - Allow reconnection (default: `true`)
|
|
- `options.allowReplay` - _boolean_ - Allow credential replay (default: `true`)
|
|
|
|
For detailed SSH algorithm configurations, refer to the full config file.
|
|
|
|
## Features
|
|
|
|
### Keyboard Interactive Authentication
|
|
|
|
Keyboard Interactive authentication provides a flexible way to handle various authentication scenarios, including multi-factor authentication.
|
|
|
|
#### How it works
|
|
|
|
1. When the SSH server requests Keyboard Interactive authentication, WebSSH2 can handle it in two ways:
|
|
a) Automatically (default behavior)
|
|
b) By prompting the user through the web interface
|
|
|
|
2. In automatic mode:
|
|
- If all prompts contain the word "password" (case-insensitive), WebSSH2 will automatically respond using the password provided during the initial connection attempt.
|
|
- If any prompt doesn't contain "password", all prompts will be forwarded to the web client for user input.
|
|
|
|
3. When prompts are sent to the web client:
|
|
- A dialog box appears in the user's browser, displaying all prompts from the SSH server.
|
|
- The user can input responses for each prompt.
|
|
- Responses are sent back to the SSH server to complete the authentication process.
|
|
|
|
#### Configuration Options
|
|
|
|
You can customize the Keyboard Interactive authentication behavior using the following option in your `config.json`:
|
|
|
|
```json
|
|
{
|
|
"ssh": {
|
|
"alwaysSendKeyboardInteractivePrompts": false
|
|
}
|
|
}
|
|
```
|
|
|
|
- `alwaysSendKeyboardInteractivePrompts` (boolean, default: false):
|
|
- When set to `true`, all Keyboard Interactive prompts will always be sent to the web client, regardless of their content.
|
|
- When set to `false` (default), WebSSH2 will attempt to automatically handle password prompts and only send non-password prompts to the web client.
|
|
|
|
#### Use Cases
|
|
|
|
1. **Simple Password Authentication**:
|
|
With default settings, if the SSH server uses Keyboard Interactive for password authentication, WebSSH2 will automatically handle it without additional user interaction.
|
|
|
|
2. **Multi-Factor Authentication**:
|
|
For SSH servers requiring additional factors (e.g., OTP), WebSSH2 will present prompts to the user through the web interface.
|
|
|
|
3. **Always Prompt User**:
|
|
By setting `alwaysSendKeyboardInteractivePrompts` to `true`, you can ensure that users always see and respond to all authentication prompts, which can be useful for security-sensitive environments or for debugging purposes.
|
|
|
|
#### Security Considerations
|
|
|
|
- The automatic password handling feature is designed for convenience but may not be suitable for high-security environments. Consider setting `alwaysSendKeyboardInteractivePrompts` to `true` if you want users to explicitly enter their credentials for each session.
|
|
- Ensure that your WebSSH2 installation uses HTTPS to protect the communication between the web browser and the WebSSH2 server.
|
|
|
|
For more information on SSH keyboard-interactive authentication, refer to [RFC 4256](https://tools.ietf.org/html/rfc4256).
|
|
|
|
### SSH Private Key Authentication
|
|
|
|
WebSSH2 supports SSH private key authentication when using the `/ssh/host/` endpoint with a private key configured in the server settings or via the interactive method with the `/ssh/` endpoint.
|
|
|
|
#### Configuration
|
|
|
|
Private key authentication can only be configured through the `config.json` file:
|
|
|
|
```json
|
|
{
|
|
"user": {
|
|
"name": "myuser",
|
|
"privateKey": "-----BEGIN RSA PRIVATE KEY-----\nYour-Private-Key-Here\n-----END RSA PRIVATE KEY-----",
|
|
"password": "optional-fallback-password"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Key Requirements
|
|
|
|
- Only `ssh-rsa` type keys are supported
|
|
- Passphrase encryption is supported, and if used the `passphrase` must be provided
|
|
- The private key must be in PEM format
|
|
- The key in `config.json` must be on a single line with `\n` as line separators
|
|
- Must include the appropriate header and footer:
|
|
```
|
|
-----BEGIN RSA PRIVATE KEY-----\n[... key content ...]\n-----END RSA PRIVATE KEY-----
|
|
```
|
|
or for encrypted keys:
|
|
```
|
|
-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-128-CBC,5930F19760F7FBBC865400940A89D954\n\n[... key content ...]\n-----END RSA PRIVATE KEY-----
|
|
```
|
|
#### Generating a Private Key
|
|
To generate a new SSH private key, you can use the following command:
|
|
|
|
```bash
|
|
ssh-keygen -m PEM -t rsa -b 4096 -f ~/.ssh/id_rsa
|
|
```
|
|
|
|
#### Converting Your Private Key
|
|
|
|
Keys uploaded or pasted using the interactive mode through the `/ssh` endpoint can work as-is, however if using a key with `config.json` you must convert your existing SSH private key into the correct format (single line). A bash one-liner you can to accomplish this is:
|
|
|
|
```bash
|
|
echo ' "privateKey": "'$(cat ~/.ssh/id_rsa | tr '\n' '~' | sed 's/~/\\n/g')'"'
|
|
```
|
|
|
|
This command:
|
|
1. Reads your private key file
|
|
2. Converts newlines to temporary characters
|
|
3. Replaces those characters with `\n`
|
|
4. Wraps the result in quotes
|
|
5. Outputs the key in a format ready to paste into your `config.json`
|
|
|
|
#### Authentication Process
|
|
|
|
1. When connecting through the `/ssh/host/` endpoint, WebSSH2 will first attempt to authenticate using the private key specified in `config.json`
|
|
2. If key authentication fails and `user.password` is configured, the system will automatically attempt password authentication
|
|
3. If both authentication methods fail, you'll receive an authentication error
|
|
|
|
#### Endpoint Support
|
|
|
|
- `/ssh/host/:host` - Supports private key authentication configured via `config.json`
|
|
- `/ssh` - Does NOT support private key authentication
|
|
|
|
#### Security Considerations
|
|
|
|
- Store private keys securely in your server configuration
|
|
- Use appropriate file permissions for your `config.json` file
|
|
- Consider using encrypted private keys for additional security
|
|
- Always use HTTPS when accessing the WebSSH2 service
|
|
|
|
#### Example Usage
|
|
|
|
1. Convert and configure your private key:
|
|
```bash
|
|
# First, convert your key
|
|
echo '"'$(cat ~/.ssh/id_rsa | tr '\n' '~' | sed 's/~/\\n/g')'"'
|
|
|
|
# Copy the output and paste it into config.json
|
|
```
|
|
|
|
2. Configure `config.json`:
|
|
```json
|
|
{
|
|
"user": {
|
|
"name": "myuser",
|
|
"privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpA...[rest of key]...Yh5Q==\n-----END RSA PRIVATE KEY-----",
|
|
"password": "fallback-password"
|
|
}
|
|
}
|
|
```
|
|
|
|
3. Access the service via the `/ssh/host/` endpoint:
|
|
```
|
|
https://your-server:2222/ssh/host/target-server
|
|
```
|
|
|
|
#### Troubleshooting
|
|
|
|
If key authentication fails, check:
|
|
- Key type is `ssh-rsa`
|
|
- Key format in `config.json` is properly escaped with `\n` line separators
|
|
- Key permissions on the target SSH server
|
|
- Server's `authorized_keys` file configuration
|
|
- SSH server logs for specific authentication failure reasons
|
|
|
|
For additional support or troubleshooting, please open an issue on the GitHub repository.
|
|
|
|
### Environment Variables via URL
|
|
|
|
WebSSH2 supports passing environment variables through URL parameters, allowing you to customize the SSH session environment. This feature enables scenarios like automatically opening specific files or setting custom environment variables.
|
|
|
|
#### Server Configuration
|
|
|
|
Before using this feature, you must configure your SSH server to accept the environment variables you want to pass. Edit your `/etc/ssh/sshd_config` file to include the desired variables in the `AcceptEnv` directive:
|
|
|
|
```bash
|
|
# Allow client to pass locale environment variables and custom vars
|
|
AcceptEnv LANG LC_* VIM_FILE CUSTOM_ENV
|
|
```
|
|
|
|
Remember to restart your SSH server after making changes:
|
|
```bash
|
|
sudo systemctl restart sshd # For systemd-based systems
|
|
# or
|
|
sudo service sshd restart # For init.d-based systems
|
|
```
|
|
|
|
#### Usage
|
|
|
|
Pass environment variables using the `env` query parameter:
|
|
|
|
```bash
|
|
# Single environment variable
|
|
http://localhost:2222/ssh/host/example.com?env=VIM_FILE:config.txt
|
|
|
|
# Multiple environment variables
|
|
http://localhost:2222/ssh/host/example.com?env=VIM_FILE:config.txt,CUSTOM_ENV:test
|
|
```
|
|
|
|
#### Security Considerations
|
|
|
|
To maintain security, environment variables must meet these criteria:
|
|
|
|
- Variable names must:
|
|
- Start with a capital letter
|
|
- Contain only uppercase letters, numbers, and underscores
|
|
- Be listed in the SSH server's `AcceptEnv` directive
|
|
- Variable values cannot contain shell special characters (;, &, |, `, $)
|
|
|
|
Invalid environment variables will be silently ignored.
|
|
|
|
#### Example Usage
|
|
|
|
1. Configure your SSH server as shown above.
|
|
|
|
2. Create a URL with environment variables:
|
|
```
|
|
http://localhost:2222/ssh/host/example.com?env=VIM_FILE:settings.conf,CUSTOM_ENV:production
|
|
```
|
|
|
|
3. In your remote server's `.bashrc` or shell initialization file:
|
|
```bash
|
|
if [ ! -z "$VIM_FILE" ]; then
|
|
vim "$VIM_FILE"
|
|
fi
|
|
|
|
if [ ! -z "$CUSTOM_ENV" ]; then
|
|
echo "Running in $CUSTOM_ENV environment"
|
|
fi
|
|
```
|
|
|
|
#### Troubleshooting
|
|
|
|
If environment variables aren't being set:
|
|
|
|
1. Verify the variables are permitted in `/etc/ssh/sshd_config`
|
|
2. Check SSH server logs for any related errors
|
|
3. Ensure variable names and values meet the security requirements
|
|
4. Test with a simple variable first to isolate any issues
|
|
|
|
## Routes
|
|
|
|
WebSSH2 provides two main routes:
|
|
|
|
### 1. `/ssh`
|
|
|
|
- **URL:** `http(s)://your-webssh2-server/ssh`
|
|
- **Features:**
|
|
- Interactive login form
|
|
|
|
<img width="341" alt="image" src="https://github.com/user-attachments/assets/829d1776-3bc5-4315-b0c6-9e96a648ce06">
|
|
- Terminal configuration options
|
|
|
|
<img width="341" alt="image" src="https://github.com/user-attachments/assets/bf60f5ba-7221-4177-8d64-946907aed5ff">
|
|
|
|
### 2. `/ssh/host/:host`
|
|
|
|
- **URL:** `http(s)://your-webssh2-server/ssh/host/:host`
|
|
- **Authentication:** HTTP Basic Auth
|
|
- **Features:**
|
|
- Quick connections to specific hosts
|
|
- Optional `port` parameter (e.g., `?port=2222`)
|
|
|
|
## Client-Side Module
|
|
WebSSH2 uses a companion module called `webssh2_client` which provides the browser-side terminal interface and WebSocket communication layer.
|
|
|
|
### About webssh2_client
|
|
|
|
- **Repository**: [https://github.com/billchurch/webssh2_client](https://github.com/billchurch/webssh2_client)
|
|
- **Purpose**: Provides the browser-based terminal emulator and WebSocket client
|
|
- **Integration**: Automatically included as a dependency in package.json
|
|
- **Version**: The compatible version is managed through the package.json dependency
|
|
|
|
### Features
|
|
|
|
The client module provides:
|
|
- Terminal emulation using xterm.js
|
|
- WebSocket communication with the WebSSH2 server
|
|
- User interface for SSH connections
|
|
- Terminal configuration and customization
|
|
- Session management
|
|
- File transfer capabilities
|
|
|
|
### Client-Server Communication
|
|
|
|
The server integrates with the client module by:
|
|
1. Serving the client's static files from `/client/public`
|
|
2. Injecting server configuration into the client via `window.webssh2Config`
|
|
3. Managing WebSocket connections for terminal I/O
|
|
4. Handling authentication and session management
|
|
|
|
### Customization
|
|
|
|
More to follow...
|
|
|
|
## Tips
|
|
|
|
- For security, use HTTPS when transmitting credentials via HTTP Basic Auth.
|
|
- Terminal settings for `/ssh/host/:host` can be customized after login via `Menu | Settings` and persist across sessions.
|
|
- You can enable debug from the console by passing the `DEBUG` environment variable to your start script: `DEBUG=webssh*,-webssh2:ssh2 npm run start`. The `webssh2:ssh2` namespace is very chatty and shows all of the SSH protocol information, the `-webssh2:ssh2` excludes that namespace from the line above, otherwise `DEBUG=webssh*` will capture all of the WebSSH2 specific bits. You may also debug Socket.IO and Express related events with `engine`, `socket` and `express` namespaces, or go for broke and debug everything with `DEBUG=*`.
|
|
- For development information see [DEVELOPMENT.md](./DEVELOPMENT.md).
|
|
|
|
For more detailed information on configuration and usage, please refer to the full documentation or open an issue on GitHub.
|
|
|
|
## Support
|
|
If you like what I do, and want to support me you can [buy me a coffee](https://www.buymeacoffee.com/billchurch)!
|
|
|
|
[](https://www.buymeacoffee.com/billchurch) |