WeTTY on Ubuntu 24.04 on Azure User Guide
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 with no desktop SSH client, no downloaded key file and no local setup. The web front end is a complete xterm terminal, so editors, pagers, colours, resizing and long running commands all behave exactly as they do in a native terminal, and every browser session is a normal SSH login under the hood.
The cloudimg image runs WeTTY as a systemd service bound only to loopback 127.0.0.1:3000, and fronts it with nginx over HTTPS on port 443 (port 80 redirects to 443). WeTTY connects to the local SSH server, so the browser session authenticates as a real operating system user.
Secure by default: WeTTY's authentication is the SSH login, and no known or default credential ships. A dedicated browser terminal login account, wettyterm, is created with its password locked. On the first boot of every instance a wetty-firstboot.service oneshot generates a unique 24 character password, sets it on that account, generates a per VM self signed TLS certificate, and only then starts WeTTY and nginx. The password is written 0600 root:root to /root/wetty-credentials.txt. Password authentication is enabled only for wettyterm through an SSH match rule, so every other account keeps the image's key based policy.
What is included:
- WeTTY 3.2.0 (MIT) installed from npm on a Node.js 22 LTS runtime
wetty.servicerunning the terminal, bound to127.0.0.1:3000- nginx reverse proxy terminating HTTPS on port 443, WebSocket aware, with an HTTP to HTTPS redirect
- A dedicated
wettytermlogin account whose password is generated per VM at first boot - Per VM self signed TLS certificate generated at first boot in
/etc/ssl/cloudimg/ wetty-firstboot.servicefor first boot credential and certificate generation- SSH match rule enabling password authentication only for the terminal account
- Ubuntu 24.04 LTS base, fully patched, unattended security upgrades enabled
- 24/7 cloudimg support, 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 for administration.
- A
Standard_B2sVM (2 vCPU, 4 GiB) or larger.
Step 1: Deploy from the Azure Portal
- Open the WeTTY on Ubuntu 24.04 LTS offer on Azure Marketplace and select Get It Now, then Create.
- Choose your subscription, resource group and region.
- Set the VM size to
Standard_B2sor larger, and provide your SSH public key for theazureuseradministrator. - On the Networking tab, allow inbound 443 (HTTPS) from the clients that will reach the terminal, and 22 (SSH) for administration.
- Review and create. When deployment finishes, note the VM's public IP address.
Step 2: Deploy from the Azure CLI
Accept the marketplace image terms once per subscription if prompted, then create the VM:
az vm image terms accept --urn cloudimg: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 cloudimg: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
Step 3: Connect via SSH and read the per VM password
Administer 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
You will see the terminal login account, the per VM password and the browser URL:
WETTY_URL=https://<vm-ip>/
WETTY_TERMINAL_USER=wettyterm
WETTY_SSH_PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOTE=Open the WeTTY URL in a browser, then log in as WETTY_TERMINAL_USER with WETTY_SSH_PASSWORD.
Step 4: Verify the services are running
WeTTY and nginx are managed by systemd. Confirm both are active and that WeTTY listens on loopback while nginx listens on 443:
sudo systemctl is-active wetty nginx wetty-firstboot
sudo ss -tlnp | grep -E ':443 |127.0.0.1:3000'
wetty --version

Step 5: Secure by default, SSH is the authentication
There is no default password. Password authentication is enabled only for the wettyterm terminal account through an SSH match rule, and the account's password is generated uniquely on this VM at first boot and stored in a root only file:
sudo cat /etc/ssh/sshd_config.d/60-cloudimg-wetty.conf
sudo stat -c '%n perms=%a owner=%U:%G' /root/wetty-credentials.txt

Step 6: Open WeTTY in your browser and log 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 10). WeTTY connects to the local SSH server and prompts you to authenticate. Log in as wettyterm with the per VM password from Step 3. A real shell opens in the browser, with the cloudimg message of the day:

Step 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:

Step 8: Administer the server from the browser
The wettyterm account is a member of the sudo group, so you can administer the whole server from the browser terminal. Elevated commands still require the same per VM password, so no privilege is granted without it:

Step 9: The stack, nginx and HTTPS
nginx terminates HTTPS on port 443 and proxies to WeTTY on loopback, upgrading the WebSocket the terminal relies on. Port 80 redirects to HTTPS:
nginx -v
curl -ks -o /dev/null -w 'GET /wetty (443) -> 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 200 for the HTTPS request and HTTP 301 for the port 80 redirect.

Step 10: Persistence and the patch baseline
The units are enabled so the browser terminal survives a reboot, the first boot marker confirms the per VM secret and certificate were generated, and the OS security baseline has no held packages:
sudo systemctl is-enabled wetty nginx wetty-firstboot
test -f /var/lib/cloudimg/wetty-firstboot.done && echo "first boot complete"
sudo apt-mark showhold

Step 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 terminal password yourself, run sudo passwd wettyterm and record the new value.
Support
This image is published by cloudimg with 24/7 support and a 24 hour response SLA. WeTTY is open source software licensed under the MIT License; this image bundles it with a hardened, fully patched base and secure by default configuration. For help with the image or the deployment, contact cloudimg support.