convert wetty from submodule to normal directory

This commit is contained in:
douboer@gmail.com
2026-03-03 16:07:18 +08:00
parent 1db76701a6
commit 0d185d2b3c
131 changed files with 15543 additions and 1 deletions

90
wetty/docs/API.md Normal file
View File

@@ -0,0 +1,90 @@
## WeTTY
Create WeTTY server
- [WeTTy](#module_WeTTy)
- [start](#module_WeTTy..start) ⇒ `Promise`
- [connection](#event_connection)
- [spawn](#event_spawn)
- [exit](#event_exit)
- [disconnect](#event_disconnect)
- [server](#event_server)
### WeTTy.start ⇒ `Promise`
Starts WeTTY Server
**Kind**: inner property of [`WeTTy`](#module_WeTTy)
**Returns**: `Promise` - Promise resolves once server is running
| Param | Type | Default | Description |
| :------------------------ | --------- | ------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [ssh] | `Object` | | SSH settings |
| [ssh.user] | `string` | `"''"` | default user for ssh |
| [ssh.host] | `string` | `"localhost"` | machine to ssh too |
| [ssh.auth] | `string` | `"password"` | authtype to use |
| [ssh.port] | `number` | `22` | port to connect to over ssh |
| [ssh.pass] | `string` | | Optional param of a password to use for ssh |
| [ssh.key] | `string` | | path to an optional client private key (connection will be password-less and insecure!) |
| [ssh.config] | `string` | | Specifies an alternative ssh configuration file. For further details see "-F" option in ssh(1) |
| [serverConf] | `Object` | | Server settings |
| [serverConf.base] | `Object` | `'/wetty/'` | Server settings |
| [serverConf.port] | `number` | `3000` | Port to run server on |
| [serverConf.host] | `string` | `'0.0.0.0'` | Host address for server |
| [serverConf.title] | `string` | `'WeTTY'` | Title of the server |
| [serverConf.bypasshelmet] | `boolean` | `false` | if helmet should be disabled on the sever |
| [command] | `string` | `"''"` | The command to execute. If running as root and no host specified this will be login if a host is specified will be ssh |
| [forcessh] | `boolean` | `false` | Connecting through ssh even if running as root |
| [ssl] | `Object` | | SSL settings |
| [ssl.key] | `string` | | Path to ssl key |
| [ssl.cert] | `string` | | Path to ssl cert |
### "connection"
**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
| Name | Type | Description |
| ---- | -------- | --------------------------- |
| msg | `string` | Message for logs |
| date | `Date` | date and time of connection |
### "spawn"
Terminal process spawned
**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
| Name | Type | Description |
| ------- | -------- | -------------------------------------- |
| msg | `string` | Message containing pid info and status |
| pid | `number` | Pid of the terminal |
| address | `string` | address of connecting user |
### "exit"
Terminal process exits
**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
| Name | Type | Description |
| ---- | -------- | -------------------------------------- |
| code | `number` | the exit code |
| msg | `string` | Message containing pid info and status |
### "disconnect"
**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
### "server"
**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
| Name | Type | Description |
| ---------- | -------- | ------------------------------- |
| msg | `string` | Message for logging |
| port | `number` | port sever is on |
| connection | `string` | connection type for web traffic |

39
wetty/docs/README.md Normal file
View File

@@ -0,0 +1,39 @@
# Docs
![WeTTY](./terminal.png?raw=true)
- [AtoZ](./atoz.md)
- [Running as daemon](./service.md)
- [HTTPS Support](./https.md)
- [Using NGINX](./nginx.md)
- [Using Apache](./apache.md)
- [Automatic Login](./auto-login.md)
- [Downloading Files](./downloading-files.md)
- [Development Docs](./development.md)
## API
For WeTTY options and event details please refer to the [api docs](./API.md)
### Getting started
WeTTY is event driven. To Spawn a new server call `wetty.start()` with no
arguments.
```javascript
import { start } from 'wetty';
start(/* server settings, see Options */)
.then((wetty) => {
console.log('server running');
wetty
.on('exit', ({ code, msg }) => {
console.log(`Exit with code: ${code} ${msg}`);
})
.on('spawn', (msg) => console.log(msg));
/* code you want to execute */
})
.catch((err) => {
console.error(err);
});
```

151
wetty/docs/apache.md Normal file
View File

@@ -0,0 +1,151 @@
## Run WeTTY behind nginx or apache
As said earlier you can use a proxy to add https to WeTTY.
**Note** that if your proxy is configured for https you should run WeTTY without
SSL
If your proxy uses a base path other than `/wetty`, specify the path with the
`--base` flag, or the `BASE` environment variable.
The following confs assume you want to serve WeTTY on the url
`example.com/wetty` and are running WeTTY with the default base and serving it
on the same server
Put the following configuration in apache's conf:
```apache
RewriteCond %{REQUEST_URI} ^/wetty/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /wetty/socket.io/(.*) ws://localhost:3000/wetty/socket.io/$1 [P,L]
<LocationMatch ^/wetty(.*)>
DirectorySlash On
Require all granted
ProxyPassMatch http://127.0.0.1:3000
ProxyPassReverse /wetty/
</LocationMatch>
```
## SAML2 integration to auth users
This conf is using apache2 (as for nginx, SAML2 integration is not available on
the community version, only pro).
Main idea is to propagate the SAML2 validated user identity into the
`remote-user` HTTP header. You need to have the user id returned within the
SAML2 NameID matching the username defined on the platform WeTTY is running.
E.g: You can ask the Idp to return a sAMAccountName within the SAML2Response
NameID, and provision beforehand those allowed users on the OS WeTTY is running
on.
### SAML2 Metadata generation
SAML2 metadata needs to be generated for this new service on the server and
exchanged with the Idp. We will use the script provided at
https://raw.githubusercontent.com/bitsensor/saml-proxy/master/mellon_create_metadata.sh
```
$ mellon_create_metadata.sh urn:https://foo.bar.tlz https://foo.bar.tld/mellon
```
Then we move the generated files over `/etc/apache2/saml2/foo.{xml,key,cert}`.
You need to put here additionally the metadata from your SAML2 provider, named
here `idp.xml` and exchange you foo.xml with it.
### Apache2 conf
```apache
<VirtualHost *:443>
ServerName foo.bar.tld
ServerAdmin admin@bar.tld
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/foo.pem
SSLCertificateKeyFile /etc/apache2/ssl/foo.key
RedirectMatch ^/$ /wetty/
ProxyPass "/wetty" "http://127.0.0.1:3000/wetty"
<Location / >
AuthType Mellon
MellonEnable info
# this propagates to apache2 (and thus to access log) the proper user id, and not
# the transient nameid that is taken by default
# it has no impact on the backend as we propagate identify via remote-user header there
MellonUser "NameID"
MellonEndpointPath /mellon/
MellonSPMetadataFile /etc/apache2/saml2/foo.xml
MellonSPPrivateKeyFile /etc/apache2/saml2/foo.key
MellonSPCertFile /etc/apache2/saml2/foo.cert
MellonIdPMetadataFile /etc/apache2/saml2/idp.xml
# the identity propagated to WeTTY (as HTTP header 'remote-user: xxxxx')
# is retrieved from SAMLResponse NameID attribute
RequestHeader set remote-user %{MELLON_NAMEID}e
</Location>
<Location /wetty>
AuthType Mellon
MellonEnable auth
Require valid-user
</Location>
# security hazard for switching between users, disabled if remote-user set as recent github commit
# but not yet published via npm, so we put here a double security belt
<Location /wetty/ssh/>
Deny from all
</Location>
</VirtualHost>
```
### Auto login
If you want to have a seamless login by trusting your IdP for authentication,
you can create password-less users on the WeTTY platform and have them trust an
SSH key used by the NodeJS, owned by the dedicated WeTTY OS user.
WeTTY instantiation with proper parameters, especially the SSH private key is
done via the following systemd service `/etc/systemd/system/wetty.service`:
```
[Unit]
Description=WeTTY Web Terminal
After=network.target
[Service]
User=wetty
Type=simple
WorkingDirectory=/home/wetty/.node_modules/wetty/
ExecStart=/usr/bin/node . -p 3000 --host 127.0.0.1 --ssh-key /home/wetty/.ssh/wetty --ssh-auth publickey --force-ssh --title "Foo bar terminal services"
TimeoutStopSec=20
KillMode=mixed
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
```
For your new users to be automatically trusting this SSH key when provisioning,
you may add the pubkey to `/etc/skel/.ssh/authorized_keys`.
### Security precautions
You probably don't want local users to impersonate each other, for that you need
to make sure that:
1. NodeJS is listening only to localhost: provided by `wetty.service`
2. **Only** the apache2 process can join the WeTTY port. Else local users will
be able to connect and forge a `remote-user` header: provided by
`iptables -A OUTPUT -o lo -p tcp --dport 3000 -m owner \! --uid-owner www-data -j DROP`
3. Validate your WeTTY version does not allow access to `/wetty/ssh/` else again
you will be able to impersonate anyone: provided by either:
1. WeTTY version 2.0.3 and beyond implements this by disabling this feature
in case of `remote-user` presence
2. apache2 conf as provided in previous section (containing the
`<Location /wetty/ssh/>`)

View File

@@ -0,0 +1,3 @@
:root {
--content-max-width: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,19 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

678
wetty/docs/atoz.md Normal file
View File

@@ -0,0 +1,678 @@
# Introduction
This is an A to Z guide that will help you get WeTTY up and running on a Debian
based system. It covers the key configuration areas by using copy and paste
commands. This will help you install this application and get it securely up and
running with minimal system interference and reversible changes. It should also
provide enough information to allow you to understand and extend that
configuration for your personal requirements.
**Note:** Some of these configurations are optional, such as self signed SSL and
public key authentication. The purpose of the guide is to show you how to
correctly understand, configure, install and use these options should you wish
to use them but they are not required to use WeTTY in general.
## Required dependencies
`Node` - WeTTY requires node v20 or greater. We will install this locally for a
non root user later in the guide.
`python` - This should be installed by default but we will include it in our
`apt-get` command to be safe.
`build-essential` - We need this specifically for `node-gyp` to build packages
when using `npm` to install packages.
As the `root` or `sudo` user run these commands:
```bash
sudo apt update
sudo apt install -y build-essential curl python
```
If you have no root access and just want to check the dependencies are installed
you can use these commands:
```bash
dpkg -s python | grep Status:
dpkg -s build-essential | grep Status:
```
If the package is installed you will see this result:
```bash
Status: install ok installed
```
## Create a local user account
For this guide, unless specifically stated, you should not use a `root` account
to install and run WeTTY. Please use an existing local account or create one
now.
**Note:** Whichever user runs WeTTY should be the same user you wish to
authenticate with via `ssh` to keep this guide simple.
If you need to create a local user account you can run this command:
**Important note:** replace `username` with a user name of your choosing and
create a password when prompted
```bash
adduser --gecos "" username
```
Switch to your local user now and open an `ssh` session to continue with this
guide.
## Install node locally
To install and manage `node` as a local user we are going to use
[Node Version Manager](https://github.com/nvm-sh/nvm). This is an established
solution for installing and managing multiple versions of node without needing
`root` access. This will allow you to install and use multiple versions of
`node` at the same time.
This command will download and install `nvm` and reload our shell.
```bash
curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash && source ~/.profile
```
This command will install the latest version of the v20 branch, which is the
minimum required version for WeTTY.
```bash
nvm install 20
```
You can now call `node` to check it works using this command.
```bash
node -v
```
Your result should look something like this.
```bash
v20.2.0
```
**Note:** There is an important consideration with the `nvm` method. `node` is
only in the local user's path through sourcing of the `~/.nvm/nvm.sh` which is
done when the user logs in and the shell sources the user's `.bashrc` file. So
for some applications who are not aware of this local shell environment `node`
will not be usable unless we provide a full path and `nvm` commands will also be
unavailable. The way we over come this issue for the needs of this guide is by
using this command substitution to provide the full path, where applicable:
```bash
$(source ~/.nvm/nvm.sh && nvm which 20)
```
**Why?** This command will always provide us with the path to the most current
version of `node 20` installed via `nvm` regardless of other versions of `node`
installed with `nvm`.
## Generate OpenSSL certificates
**Why?** So that later we can configure WeTTY to work with `https` and make sure
we interact with WeTTY over a secure connection at all times.
Make the required directory using this command:
```bash
mkdir -p ~/.ssl
```
Generate the self signed `openssl` certificates we will use to encrypt our web
traffic when using WeTTY using this command:
**Note:** we are using `ecdsa` using the `secp384r1` curve. Tested to be
compatible with Chrome and Firefox browsers.
```bash
openssl req -x509 -nodes -days 1095 -newkey ec:<(openssl ecparam -name secp384r1) -subj "/C=GB/ST=None/L=None/O=None/OU=None/CN=None" -out ~/.ssl/wetty.crt -keyout ~/.ssl/wetty.key
```
Now give these file and folders the correct permissions using these commands:
```bash
chmod 700 ~/.ssl
chmod 644 ~/.ssl/wetty.crt
chmod 600 ~/.ssl/wetty.key
```
This is all we need to do for now in regards to https.
## Generate the ssh key file
**Why?** So that later we can set up automatic login via `ssh`. Our instance
will authorize using this key file stored locally.
Make the required directory, if it does not exist, using this command:
```bash
mkdir -p ~/.ssh
```
Create the `ssh` private key using `ed25519` that we need to authorize our local
connection, using this command:
```bash
ssh-keygen -q -C "wetty-keyfile" -t ed25519 -N '' -f ~/.ssh/wetty 2>/dev/null <<< y >/dev/null
```
**Important Note:** You must add the public key to your `authorized_keys` file
in order to be able to log in using your `ssh` key file when accessing WeTTY via
a web browser.
Copy the key to our `~/.ssh/authorized_keys` file, using this command:
```bash
cat ~/.ssh/wetty.pub >> ~/.ssh/authorized_keys
```
Now give these file and folders the correct permissions, using these commands:
```bash
chmod 700 ~/.ssh
chmod 644 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/wetty
```
**Optional:** A housekeeping command. If you need to remove all entries of the
WeTTY public key with the comment `wetty-keyfile` from the
`~/.ssh/authorized_keys` file use this command. Otherwise ignore this.
```bash
sed -r '/^ssh-ed25519(.*)wetty-keyfile$/d' -i ~/.ssh/authorized_keys
```
## Install WeTTY
**Note:** we are using `-g` for `npm` along with `--prefix ~/` so that the
application's symbolic link is installed to our `~/bin` directory and available
in our local user's `PATH`.
As your local user run these commands:
To make sure the local user's `~/bin` directory exists and is in the `PATH`
please run the following command.
```bash
mkdir -p ~/bin && source ~/.profile
```
Then use `npm` to install `wetty`.
```bash
npm -g i wetty --prefix ~/
```
Once successfully installed the application should be available in your local
user's `PATH`. To test the installation was successful please use this command:
```bash
wetty -h
```
## Accessing the web interface via our external IP
If you are using your external IP and not a domain to access WeTTY this step
needs to be done here because it is not easy to do in the next steps if WeTTY is
running in the terminal.
This command will generate the correct URL you need to visit after using the
start up commands in the following section.
```bash
echo https://$(curl -s4 icanhazip.com):3000
```
_Please make a note of this URL now._
## Running WeTTY
Now we have all the ground work done we can focus on our WeTTY server
configuration settings.
For example, the below command would provide a `https` instance with automatic
`ssh` authorization using our `wetty` private key on port `3000` accessible at
`https://IP:3000` .
**Important note:** This command will run in your current terminal session and
not in the background. The key combination of `CTRL` + `c` will exit the
application.
```bash
wetty --host 0.0.0.0 --port 3000 --title wetty --base / --ssh-key ~/.ssh/wetty --ssh-host localhost --ssh-user $(whoami) --ssh-port 22 --ssh-auth publickey --ssl-key ~/.ssl/wetty.key --ssl-cert ~/.ssl/wetty.crt
```
Since you may not need all these settings we will look through what each one
does below so that you can decide how to best configure your instance.
### Environment settings explained
Let's break it down so that we can understand what's being done and why.
```bash
--host 0.0.0.0 --port 3000 --title wetty --base /
```
`--host 0.0.0.0` - defines the interface we want to bind to. Using `0.0.0.0`
means that we bind to all available interfaces so using this setting just works.
When we use nginx we can change this to `--host 127.0.0.1` in order to prevent
generic port access to the application and force traffic through our nginx
reverse proxy URL.
`--port 3000` - defines the local listening port. You will use this port to
connect via the remotely accessible web server or when configuring a reverse
proxy through nginx.
`--title wetty` - an optional setting to set the window title for this `wetty`
session.
`--base /` - changes the default base URL setting from `/wetty/` to define the
remote URL. We use `--base /` to make `wetty` accessible on the URL format
`https://IP:3000` instead of `https://IP:3000/wetty` but we would change this
back if we use nginx to reverse proxy the application.
### SSH settings explained
These settings are all specific to `ssh` and will enable you to automatically
log into you `ssh` session for the selected user.
```bash
--ssh-key ~/.ssh/wetty --ssh-host localhost --ssh-user $(whoami) --ssh-port 22 --ssh-auth publickey
```
`--ssh-key ~/.ssh/wetty` - we are telling WeTTY to load our `ssh` key file that
we generated earlier.
`--ssh-host localhost` - optional setting telling WeTTY to connect the host
`localhost`
`--ssh-user $(whoami)` - defines our `ssh` username. In this case via the
command substitution of `whoami` which will not require your input of a
username.
`--ssh-port 22` - optional setting to set the `ssh` port we need to connect to.
`--ssh-auth publickey` defines the accepted authentication types. You do not
have to use the key file and you can instead require a password but setting this
to `--sshauth password`. You can specify both `--sshauth publickey,password`
`--ssh-config configfile` - (not used for this guide) alternative ssh
configuration file. From ssh(1):
> If a configuration file is given on the command line, the system-wide
> configuration file (/etc/ssh/ssh_config) will be ignored. The default for the
> per-user configuration file is ~/.ssh/config.
### SSL settings explained
These settings are specific to `openssl` to make WeTTY load https webserver so
that all data is transmitted over a secure connection.
```bash
--ssl-key ~/.ssl/wetty.key --ssl-cert ~/.ssl/wetty.crt
```
`--ssl-key ~/.ssl/wetty.key` - tells WeTTY to load our `openssl` generated key
file.
`--ssl-cert ~/.ssl/wetty.crt` - tells WeTTY to load our `openssl` generates
certificate file.
### Optional - load settings via a configuration file
As of WeTTY v2 there is official support for a configuration file used with the
flag `--conf` to specify the location of this file.
Create the directory where we will store this configuration file.
```bash
mkdir -p ~/.config/wetty
```
Use `nano` to open a file for editing.
```bash
nano ~/.config/wetty/config.json
```
Here is the template `config.json` you need to use.
**Note:** To be [validated json](https://codebeautify.org/jsonvalidator) the
below json example should have the `// ...` comments removed. With all comments
removed the example is valid json. They are in the example to help explain the
options and won't stop WeTTY from loading if you leave them in place. Lines you
do not need can be commented out but should be removed if you want the json to
pass validation.
```json
"ssh": {
"user": "username", // default user to use when ssh-ing
"host": "localhost", // Server to ssh to
"auth": "publickey,password", // shh authentication, method. Defaults to "password", you can use "publickey,password" instead'
"pass": "password", // Password to use when ssh-ing
"key": "/home/username/.ssh/wetty", // path to an optional client private key, connection will be password-less and insecure!
"port": 22, // Port to ssh to
"knownHosts": "/dev/null" // ssh knownHosts file to use
},
"server": {
"base": "/wetty/", // URL base to serve resources from
"port": 3000, // Port to listen on
"host": "0.0.0.0", // listen on all interfaces or can be 127.0.0.1 with nginx
"title": "WeTTY - The Web Terminal Emulator", // Page title
"bypassHelmet": false // Disable Helmet security checks
},
"forceSSH": false, // Force sshing to local machine over login if running as root
"command": "login", // Command to run on server. Login will use ssh if connecting to different server
"ssl": {
"key": "/home/username/.ssl/wetty.key",
"cert": "/home/username/.ssl/wetty.crt"
}
}
```
Press `ctrl` + `x` and then press `y` to save then press `enter` to confirm and
exit `nano`.
## System Environment Variables
**Note:** We will not be using this section to configure WeTTY. We are simply
documenting it.
There are some environment variables you can export that can be used by WeTTY to
configure an instance.
```bash
BASE
PORT
TITLE
SSHUSER
SSHHOST
SSHAUTH
SSHPASS
SSHKEY
SSHPORT
KNOWNHOSTS
FORCESSH
COMMAND
ALLOWIFRAME
```
These can be used in the following way
```bash
export PORT=3000
```
There are currently no environment settings for variables not listed above.
## Systemd service settings
We will use a local user `systemd` service file to manage the `wetty` service.
First, create the required directory, if it does not exist.
```bash
mkdir -p ~/.config/systemd/user
```
### Systemd service
Here is an example template of how to use service file with hardcoded values you
can set in the `wetty.service` file with all options enabled.
Use `nano` to open a file for editing.
```bash
nano ~/.config/systemd/user/wetty.service
```
Then copy and paste this code.
**Note:** This is an example service file based on all the options documented
and configured so far. You may not want all these option enabled so please
remove or modify the `ExecStart` command based on your needs.
```bash
[Unit]
Description=WeTTY
After=network-online.target
[Service]
Type=simple
ExecStart=/bin/bash -c "$$(source /home/$$(whoami)/.nvm/nvm.sh && nvm which 12) /home/$$(whoami)/bin/wetty --host 0.0.0.0 -p 3000 --title wetty --base / --ssh-key /home/$$(whoami)/.ssh/wetty --ssh-host localhost --ssh-user $$(whoami) --ssh-port 22 --ssh-auth publickey --ssl-key /home/$$(whoami)/.ssl/wetty.key --ssl-cert /home/$$(whoami)/.ssl/wetty.crt"
Restart=always
RestartSec=2
TimeoutStopSec=5
SyslogIdentifier=wetty
[Install]
WantedBy=default.target
```
Press `ctrl` + `x` and then press `y` to save then press `enter` to confirm and
exit `nano`.
### Optional - Systemd service with config file
Here is the example using our pseudo configuration file. All modifications to
the start up of `wetty` will be done by editing the `~/.config/Wetty/config`
file and then reloading the `wetty.service`.
Use `nano` to open the file for editing.
```bash
nano ~/.config/systemd/user/wetty.service
```
Then copy and paste this code.
**Note:** This `ExecStart` assumes the location of your `config.json` to be
`~/.config/wetty/config.json`. Please make sure you use the correct location for
this file.
```bash
[Unit]
Description=WeTTY
After=network-online.target
[Service]
Type=simple
ExecStart=/bin/bash -c "$$(source /home/$$(whoami)/.nvm/nvm.sh && nvm which 20) /home/$$(whoami)/bin/wetty --conf /home/$$(whoami)/.config/wetty/config.json"
Restart=always
RestartSec=2
TimeoutStopSec=5
SyslogIdentifier=wetty
[Install]
WantedBy=default.target
```
Press `ctrl` + `x` and then press `y` to save then press `enter` to confirm and
exit `nano`.
### Activating your service
Then you can enable and start your service.
```bash
systemctl --user enable --now wetty
```
### Managing your services
These commands will help you manage your service.
```bash
systemctl --user daemon-reload
systemctl --user status wetty
systemctl --user start wetty
systemctl --user stop wetty
systemctl --user restart wetty
systemctl --user disable --now wetty
systemctl --user enable --now wetty
```
## Nginx reverse proxy
If you want to use nginx as a reverse proxy here is the configuration file you
can use.
Please modify these specific environment settings:
**Why?** This will disable generic port access to the application and force
traffic via the nginx reverse proxy.
```bash
--host 127.0.0.1
```
**Why?** This change is so that our application does not attempt to load as the
web root of `/` for nginx.
```bash
--base /wetty/
```
Now you can use this nginx configuration file.
**Note:** we are using `https` with `https://127.0.0.1:3000/wetty;` because we
configured `wetty` to run via `https` using our self signed ssl certificates. If
you chose not to run WeTTY with a self signed certificate you should changes
this to `http://127.0.0.1:3000/wetty;`
Then copy and paste this into the `https` server block of your enable server
configuration file.
```nginx
location /wetty {
proxy_pass https://127.0.0.1:3000/wetty;
#
proxy_pass_request_headers on;
#
proxy_set_header Host $host;
#
proxy_http_version 1.1;
#
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-NginX-Proxy true;
#
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_read_timeout 43200000;
proxy_set_header X-Forwarded-Ssl on;
#
proxy_redirect off;
proxy_buffering off;
}
```
Press `ctrl` + `x` and then press `y` to save then press `enter` to confirm and
exit `nano`
Now you would need to reload nginx service using this command:
```bash
systemctl restart nginx
```
### Accessing the web interface via nginx
Visit the URL format `https://YourIPorDomain/wetty` and you can access WeTTY.
This command will generate the correct URL you need to visit it you are not
using a domain.
```bash
echo https://$(curl -s4 icanhazip.com)/wetty
```
## Protecting your instance of WeTTY
**Disclaimer:** It is not recommended by this guide that you run an instance of
WeTTY on your server with no access control in place.
If you chose to not use a password to login in you should protect your instance
behind either:
1:
[Nginx basic auth](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/)
2: [Authelia](https://github.com/authelia/authelia)
## Configuration reference
`wetty -h` configuration options for reference.
```bash
--help, -h Print help message [boolean]
--version Show version number [boolean]
--conf config file to load config from [string]
--ssl-key path to SSL key [string]
--ssl-cert path to SSL certificate [string]
--ssh-host ssh server host [string] [default: "localhost"]
--ssh-port ssh server port [number] [default: 22]
--ssh-user ssh user [string] [default: ""]
--title window title [string] [default: "WeTTY - The Web Terminal Emulator"]
--ssh-auth defaults to "password", you can use "publickey,password"
instead [string] [default: "password"]
--ssh-pass ssh password [string]
--ssh-key path to an optional client private key (connection will be
password-less and insecure!) [string]
--ssh-config Specifies an alternative ssh configuration file. For further
details see "-F" option in ssh(1) [string] [default: ""]
--force-ssh Connecting through ssh even if running as root [boolean] [default: false]
--known-hosts path to known hosts file [string]
--base, -b base path to wetty [string] [default: "/wetty/"]
--port, -p wetty listen port [number] [default: 3000]
--host wetty listen host [string] [default: "0.0.0.0"]
--command, -c command to run in shell [string] [default: "login"]
--allow-iframe Allow wetty to be embedded in an iframe, defaults to allowing
same origin [boolean] [default: false]
```
## Updating WeTTY
```bash
npm -g update wetty --prefix ~/
```
To update or downgrade to a specific version you use this command:
```bash
npm -g i wetty@2.7.0 --prefix ~/
```
Now restart your `wetty` service.
## Updating nvm
The proper way to update NVM is to use git. The `.nvm` directory is a git repo.
These commands will update NVM to the latest version of the script and load it
to your shell.
```bash
cd ~/.nvm
git fetch --tags
git checkout $(git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1))
source ~/.nvm/nvm.sh
```
## Updating node
You can use the same command you used to install it with `nvm`
```bash
nvm install 20
```

22
wetty/docs/auto-login.md Normal file
View File

@@ -0,0 +1,22 @@
# Auto Login
WeTTY Supports a form of auto login by passing a users password though url
params.
This is not a required feature and the security implications for passing the
password in the url will have to be considered by the user.
## Requirements
For auto-login feature you'll need sshpass installed
- `apt-get install sshpass` (debian eg. Ubuntu)
- `yum install sshpass` (red hat flavours eg. CentOs)
## Usage
You can also pass the ssh password as an optional query parameter to auto-login
the user like this (Only while running WeTTY as a non root account or when
specifying the ssh host):
`http://yourserver:3000/wetty/ssh/<username>?pass=<password>`

25
wetty/docs/development.md Normal file
View File

@@ -0,0 +1,25 @@
# Installation from Source
WeTTY can be installed from source or from npm.
To install from source run:
```bash
$ git clone https://github.com/butlerx/wetty.git
$ cd wetty
$ pnpm install
$ pnpm build
```
## Development Env
To run WeTTY in dev mode you can run `pnpm dev`.
WeTTY will then be served from `http://localhost:3000/wetty` on your machine.
The server will be using the [`conf/config.json5`](../conf/config.json5) config
file and be pointing at `localhost` on port `22` .
The Dev server will rebuild WeTTY when ever a file is edited and restart the
server with the new build. Any current ssh session in WeTTY will be killed and
the user logged out.

27
wetty/docs/docker.md Normal file
View File

@@ -0,0 +1,27 @@
# Dockerized Version
WeTTY can be run from a container to ssh to a remote host or the host system.
This is handy for quick deployments. Just modify `docker-compose.yml` for your
host and run:
```sh
$ docker-compose up -d
```
This will start 2 containers, one will be WeTTY container running ssh client the
other will be a container running ssh server.
Visit the appropriate URL in your browser
(`[localhost|$(boot2docker ip)]:PORT`).
The default username is `term` and the password is `term`, if you did not modify
`SSHHOST`
In the docker version all flags can be accessed as environment variables such as
`SSHHOST` or `SSHPORT`.
If you don't want to build the image yourself just remove the line `build; .`
If you wish to use the WeTTY container in prod just modify the WeTTY container
to have `SSHHOST` point to the server you want to ssh to and remove the ssh
server container.

View File

@@ -0,0 +1,44 @@
# File Downloading
WeTTY supports file downloads by printing terminal escape sequences between a
base64 encoded file. The name of the downloaded file can optionally be provided,
also base64 encoded, before the encoded file contents with a `:` separating them.
The terminal escape sequences used are `^[[5i` and `^[[4i` (VT100 for "enter
auto print" and "exit auto print" respectively -
https://vt100.net/docs/tp83/appendixc.html).
To take advantage add the following bash function to your `.bashrc`
```bash
function wetty-download() {
file=${1:-/dev/stdin}
nameprefix=""
if [[ -f "$file" ]]; then
nameprefix="$(basename "$file" | base64 -w 0):"
fi
if [[ -f "$file" || "$file" == "/dev/stdin" ]]; then
printf "\033[5i"$nameprefix$(cat "$file" | base64 -w 0)"\033[4i"
else
echo "$file does not appear to be a file"
fi
}
```
You are then able to download files via WeTTY!
```bash
wetty-download my-pdf-file.pdf
```
or you can still use the classic style:
```bash
$ cat my-pdf-file.pdf | wetty-download
```
WeTTY will then issue a popup like the following that links to a local file
blob: `Download ready: file-20191015233654.pdf`

38
wetty/docs/flags.md Normal file
View File

@@ -0,0 +1,38 @@
# Flags
WeTTY can be run with the `--help` flag to get a full list of flags.
## Server Port
WeTTY runs on port `3000` by default. You can change the default port by
starting with the `--port` or `-p` flag.
## SSH Host
If WeTTY is run as root while the host is set as the local machine it will use
the `login` binary rather than ssh. If no host is specified it will use
`localhost` as the ssh host.
If instead you wish to connect to a remote host you can specify the host with
the `--ssh-host` flag and pass the IP or DNS address of the host you want to
connect to.
## Default User
You can specify the default user used to ssh to a host using the `--ssh-user`.
This user can overwritten by going to
`http://yourserver:3000/wetty/ssh/<username>`. If this is left blank a user will
be prompted to enter their username when they connect.
## SSH Port
By default WeTTY will try to ssh to port `22`, if your host uses an alternative
ssh port this can be specified with the flag `--ssh-port`.
## WeTTY URL
If you'd prefer an HTTP base prefix other than `/wetty`, you can specify that
with `--base`.
**Do not set this to `/ssh/${something}`, as this will break username matching
code.**

21
wetty/docs/https.md Normal file
View File

@@ -0,0 +1,21 @@
# HTTPS
Always use HTTPS especially with a terminal to your server. You can add HTTPS by
either using WeTTY behind a proxy or directly.
See docs for [NGinX](./nginx.md) and [Apache](./apache.md) for running behind a
proxy.
To run WeTTY directly with SSL use both the `--ssl-key` and `--ssl-cert` flags
and pass them the path too your cert and key as follows:
```bash
wetty --ssl-key key.pem --ssl-cert cert.pem
```
If you don't have SSL certificates from a CA you can create a self signed
certificate using this command:
```bash
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 30000 -nodes
```

96
wetty/docs/index.html Normal file
View File

@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover"
/>
<meta name="description" content="WeTTY" />
<title>WeTTY = Web + TTY</title>
<link
rel="apple-touch-icon"
sizes="180x180"
href="assets/img/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="assets/img/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="assets/img/favicon-16x16.png"
/>
<link rel="manifest" href="assets/img/site.webmanifest" />
<!-- Theme -->
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable/dist/css/theme-simple.css"> -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/docsify-themeable/dist/css/theme-simple.css"
/>
<link rel="stylesheet" href="assets/css/main.css" />
<script src="https://cdn.jsdelivr.net/npm/docsify-edit-on-github"></script>
</head>
<body>
<div id="app">Please wait...</div>
<script>
window.$docsify = {
// GENERAL
// -----------------------------------------------------------------
name: 'WeTTY = Web + TTY',
repo: 'https://github.com/butlerx/wetty',
homepage: 'README.md',
loadSidebar: true,
loadSidebar: 'sidebar.md',
auto2top: true,
executeScript: true,
mergeNavbar: true,
maxLevel: 3,
subMaxLevel: 3,
// PLUGINS
// -----------------------------------------------------------------
plugins: [
EditOnGithubPlugin.create(
'https://github.com/butlerx/wetty/tree/master/docs/',
),
],
search: {
noData: {
'/': 'No results!',
},
paths: 'auto',
placeholder: {
'/': 'Search',
},
},
tabs: {
persist: true, // default
sync: true, // default
theme: 'classic', // default
tabComments: true, // default
tabHeadings: true, // default
},
themeable: {
readyTransition: true, // default
responsiveTables: true, // default
},
};
</script>
<script src="https://cdn.jsdelivr.net/npm/docsify"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify-tabs"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify-copy-code"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify-themeable"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify-prism"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/autoloader/prism-autoloader.min.js"></script>
</body>
</html>

34
wetty/docs/nginx.md Normal file
View File

@@ -0,0 +1,34 @@
## Run WeTTY behind nginx
As said earlier you can use Nginx to add https to WeTTY.
**Note** that if your proxy is configured for https you should run WeTTY without
SSL
If you configure nginx to use a base path other than `/wetty`, then specify that
path with the `--base` flag, or the `BASE` environment variable.
The following confs assume you want to serve WeTTY on the url
`example.com/wetty` and are running WeTTY with the default base and serving it
on the same server
For a more detailed look see the
[nginx.conf](https://github.com/butlerx/wetty/blob/main/conf/nginx.template)
used for testing
Put the following configuration in your nginx conf:
```nginx
location ^~ /wetty {
proxy_pass http://127.0.0.1:3000/wetty;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 43200000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}
```

32
wetty/docs/service.md Normal file
View File

@@ -0,0 +1,32 @@
## Run WeTTY as a service daemon
WeTTY can be run as a daemon on your service init confs and systemd services are
bundled with the npm package to make this easier.
### init.d
```bash
$ npm -g i wetty
$ sudo cp ~/.node_modules/wetty/conf/wetty.conf /etc/init
$ sudo start wetty
```
### systemd
```bash
$ yarn global add wetty
$ cp ~/.node_modules/wetty/conf/wetty.service ~/.config/systemd/user/
$ systemctl --user enable wetty
$ systemctl --user start wetty
```
This will start WeTTY on port 3000. If you want to change the port or redirect
stdout/stderr you should change the last line in `wetty.conf` file, something
like this:
```systemd
exec sudo -u root wetty -p 80 >> /var/log/wetty.log 2>&1
```
Systemd requires an absolute path for a unit's WorkingDirectory, consequently
`$HOME` will need updating to an absolute path in the `wetty.service` file.

11
wetty/docs/sidebar.md Normal file
View File

@@ -0,0 +1,11 @@
- [Home](README.md)
- [Apache](apache.md)
- [API](API.md)
- [AtoZ](atoz.md)
- [auto-login](auto-login.md)
- [development](development.md)
- [downloading-files](downloading-files.md)
- [flags](flags.md)
- [https](https.md)
- [nginx](nginx.md)
- [service](service.md)

BIN
wetty/docs/terminal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB