We
Developer Tools Azure

WeTTY on Ubuntu 24.04 on Azure User Guide

| Product: WeTTY on Ubuntu 24.04 LTS on Azure

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.service running the terminal, bound to 127.0.0.1:3000
  • nginx reverse proxy terminating HTTPS on port 443, WebSocket aware, with an HTTP to HTTPS redirect
  • A dedicated wettyterm login 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.service for 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_B2s VM (2 vCPU, 4 GiB) or larger.

Step 1: Deploy from the Azure Portal

  1. Open the WeTTY on Ubuntu 24.04 LTS offer on Azure Marketplace and select Get It Now, then Create.
  2. Choose your subscription, resource group and region.
  3. Set the VM size to Standard_B2s or larger, and provide your SSH public key for the azureuser administrator.
  4. On the Networking tab, allow inbound 443 (HTTPS) from the clients that will reach the terminal, and 22 (SSH) for administration.
  5. 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

WeTTY, nginx and the first boot service all active, WeTTY bound to loopback 127.0.0.1:3000 and nginx listening on port 443, running WeTTY 3.2.0 on Node.js 22

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

The SSH match rule enabling password authentication only for the wettyterm account, and the per VM credentials file stored 0600 root:root

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:

The WeTTY browser terminal after logging in as wettyterm with the per VM password, showing the cloudimg message of the day and an interactive shell prompt

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:

The WeTTY browser terminal running uname, whoami and uptime and showing their real output in an interactive session

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:

The WeTTY browser terminal listing the filesystem and checking service status, demonstrating full administrative shell access from the browser

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.

nginx serving WeTTY over HTTPS returning 200, the port 80 request returning a 301 redirect to HTTPS, and the per VM self signed certificate subject

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

The WeTTY, nginx and first boot units enabled, the first boot marker present, and an intact OS patch baseline with no held packages

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.