Deployment guide

WeTTY

Overview

WeTTY is an open-source terminal in the browser. It serves a real, fully interactive shell over HTTP or HTTPS, backed by SSH, so anyone with a browser gets a genuine command line on the server. You need no desktop SSH client, no downloaded key file and no local setup.

The SecureAnyCloud image runs WeTTY as a systemd service that listens only on a private Unix socket (/run/wetty/wetty.sock, with no TCP port at all). nginx fronts it over HTTPS on port 443, and port 80 redirects to 443. After you sign in to the browser, WeTTY opens an SSH session to the local server as your own administrator account, which is the admin username you chose at deployment. Every browser session is a real login on the VM.

The web front end is a complete xterm terminal, so editors, pagers, colours, resizing and long-running commands behave exactly as they do in a native terminal.

Secure by default: no known or default credential ships, and no extra login account is added to the operating system. On the first boot of every instance, a wetty-firstboot.service oneshot generates the following, and only then starts WeTTY and nginx: a unique 32-character browser password (stored by nginx only as a hash), a per-VM SSH key that WeTTY uses to open the shell as your admin account, and a per-VM self-signed TLS certificate. The browser password is written 0600 root:root to /root/wetty-credentials.txt. The WeTTY key is accepted only from the VM itself (from="127.0.0.1,::1"), and SSH password authentication stays disabled for every account.

What you get:

  • WeTTY 3.2.0 (MIT) installed from npm on a Node.js 22 LTS runtime
  • wetty.service running the terminal on the Unix socket /run/wetty/wetty.sock, which only nginx can connect to
  • An nginx reverse proxy that terminates HTTPS on port 443, supports WebSockets and redirects HTTP to HTTPS
  • A per-VM browser password generated at first boot and enforced by nginx
  • A per-VM SSH key that opens the browser shell as your own admin account and is accepted only from loopback
  • A per-VM self-signed TLS certificate generated at first boot in /etc/ssl/sac/
  • wetty-firstboot.service for first-boot credential and certificate generation
  • SSH password authentication disabled for every account
  • An Ubuntu 24.04 LTS base, patched at build time, with unattended security upgrades enabled
  • 24/7 SecureAnyCloud support with a 24h response SLA

Prerequisites

  • An Azure subscription and permission to deploy a virtual machine
  • An SSH key pair to administer the VM as azureuser
  • Inbound TCP 443 (and optionally 80) open to the clients that will use the browser terminal, and TCP 22 open for administration
  • A Standard_B2s VM (2 vCPU, 4 GiB) or larger
1

Deploy from the Azure Portal

  • Open the WeTTY on Ubuntu 24.04 LTS offer on Azure Marketplace, then select Get It Now and Create.
  • Choose your subscription, resource group and region.
  • Set the VM size to Standard_B2s or larger, and provide your SSH public key for the azureuser administrator.
  • On the Networking tab, allow inbound 443 (HTTPS) from the clients that will reach the terminal, and 22 (SSH) for administration.
  • Review and create the VM. When deployment finishes, note the public IP address of the VM.
2

Deploy from the Azure CLI

If prompted, accept the marketplace image terms once per subscription. Then create the VM:

az vm image terms accept --urn sac1647283583153:wetty-ubuntu-24-04:default:latest
az group create --name wetty-rg --location eastus
az vm create \
  --resource-group wetty-rg \
  --name wetty-vm \
  --image sac1647283583153:wetty-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
az vm open-port --resource-group wetty-rg --name wetty-vm --port 443 --priority 900
3

Connect via SSH and read the per-VM password

Connect to the VM as azureuser with your SSH key. Then read the browser terminal password that first boot generated for this instance:

ssh azureuser@<vm-ip>

The per-VM password lives in a root-only file. Read it:

sudo cat /root/wetty-credentials.txt

The file shows the browser sign-in, the per-VM password, the account the shell opens as and the browser URL:

WETTY_URL=https://<vm-ip>/ WETTY_WEB_USER=wetty WETTY_WEB_PASSWORD=<set-at-first-boot> WETTY_SHELL_USER=azureuser NOTE=Open the WeTTY URL in a browser and sign in as WETTY_WEB_USER with WETTY_WEB_PASSWORD.

WETTY_SHELL_USER is the admin username you chose when you deployed the VM.

4

Verify the services are running

systemd manages WeTTY and nginx. Confirm that both are active, that nginx listens on 443, and that WeTTY listens only on its Unix socket, which is closed to every local user except nginx:

systemctl is-active wetty nginx wetty-firstboot
sudo ss -tlnp | grep ':443 '
sudo ss -xlp | grep wetty.sock
sudo stat -c '%n %a %U:%G' /run/wetty /run/wetty/wetty.sock wetty --version ; node --version
5

Secure by default

There is no default password and no extra login account. The browser password is generated uniquely on this VM at first boot, nginx keeps only its hash, and the plain value is in a root-only file. WeTTY opens the shell with a per-VM key that your admin account accepts only from the VM itself. SSH password authentication is off. Verify this with:

sudo stat -c '%n perms=%a owner=%U:%G' /root/wetty-credentials.txt /etc/nginx/sac-wetty.htpasswd grep sac-wetty-browser-terminal ~/.ssh/authorized_keys | cut -c1-60 sudo sshd -T | grep -i '^passwordauthentication'

You should see the credentials file as 600 root:root, the WeTTY key restricted with restrict,pty,from="127.0.0.1,::1" (no forwarding of any kind, loopback only), and passwordauthentication no. The browser terminal always opens as your admin account. nginx ignores any attempt to choose another account through the URL or request headers.

6

Open WeTTY in your browser and sign in

In a browser, go to https://<vm-ip>/. The image ships a per-VM self-signed certificate, so accept the browser warning, or install your own certificate (see Step 11). When the browser asks you to sign in, enter the username wetty and the per-VM password from Step 3. WeTTY then opens a real shell as your admin account, with the SecureAnyCloud message of the day:

7

Use the browser terminal

The session is a genuine interactive shell. Run any command and see real output, exactly as you would in a native terminal.

8

Administer the server from the browser

The browser shell runs as your admin account, which has sudo, so you can administer the whole server from the browser terminal. Treat the browser password with the same care as your SSH key.

9

The stack, nginx and HTTPS

nginx terminates HTTPS on port 443 and proxies to WeTTY on loopback, upgrading the WebSocket that the terminal relies on. Port 80 redirects to HTTPS. Check both with:

nginx -v curl -ks -o /dev/null -w 'GET /wetty (443, no password) -> HTTP %{http_code}\n' https://127.0.0.1/wetty curl -s -o /dev/null -w 'GET / (port 80) -> HTTP %{http_code}\n' http://127.0.0.1/

You should see HTTP 401 for the HTTPS request without the browser password, which shows that sign-in is enforced. You should see HTTP 301 for the port 80 redirect.

10

Persistence and the patch baseline

The units are enabled, so the browser terminal survives a reboot. The first-boot marker confirms that the per-VM password, key and certificate were generated, and the OS security baseline has no held packages. Check them with:

sudo systemctl is-enabled wetty nginx wetty-firstboot test -f /var/lib/sac/data/wetty-firstboot.done && echo "first boot complete"
sudo apt-mark showhold
11

Enable a trusted TLS certificate

The image ships a per-VM self-signed certificate, so HTTPS works out of the box. For a production deployment, point a DNS name at the VM and install a trusted certificate with certbot:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com --email admin@your-domain.example.com --agree-tos --no-eff-email

certbot updates the nginx configuration to use the issued certificate and sets up automatic renewal.

Managing the service

sudo systemctl status wetty --no-pager sudo systemctl restart wetty

To follow the WeTTY logs live, run sudo journalctl -u wetty -f. To rotate the browser password yourself, run printf 'wetty:%s\n' "$(openssl passwd -apr1)" | sudo tee /etc/nginx/sac-wetty.htpasswd >/dev/null && sudo systemctl reload nginx, then record the new value. If you remove the sac-wetty-browser-terminal line from your admin account's authorized_keys, the browser terminal can no longer open a shell.

Support

SecureAnyCloud publishes this image with 24/7 support and a 24-hour response SLA. WeTTY is open-source software licensed under the MIT License. The image bundles it with a hardened base that is patched at build time, and with a secure-by-default configuration. For help with the image or the deployment, contact SecureAnyCloud support.

Deploy on Azure

Launch WeTTY on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure