Sozu HTTP Reverse Proxy / Load Balancer on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of Sozu on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Sozu (pronounced sou-zou) is an HTTP reverse proxy and load balancer written in Rust. It is fast, memory-safe, and — its defining feature — reconfigurable at runtime with no downtime: you add or remove clusters, frontends, backends and TLS certificates on a live proxy without dropping a single connection.
The image installs Sozu 2.2.0 from the pinned upstream crate, so the exact version is reproducible. Sozu runs under systemd as the unprivileged sozu user. Unattended security upgrades keep the base OS patched.
Serves a real response out of the box. The appliance ships a tiny self-contained local backend (a static server bound to 127.0.0.1:8000) and a default cluster that proxies to it, so an on-box curl http://localhost/ returns a real HTTP body through Sozu the moment the VM boots. You then point Sozu at your own backends with one config edit or a runtime CLI command.
Secure by design.
- Sozu runs as the unprivileged
sozuuser and binds the privileged ports :80 and :443 using only theCAP_NET_BIND_SERVICELinux capability — never as root. - The Sozu command/control channel is a local Unix socket only (
/run/sozu/sozu.sock, mode0750). It is never exposed on a TCP port, so the proxy cannot be reconfigured from the network. ThesozuCLI over SSH is the sole admin path. - A per-VM self-signed TLS certificate is generated on first boot into
/etc/sozu/tls/— it is never baked into the image, so every VM has unique TLS material.
What is included:
-
Sozu 2.2.0 installed from the pinned upstream crate, run under systemd as the unprivileged
sozuuser (sozu.service) -
An HTTP listener on :80 and an HTTPS listener on :443 (per-VM TLS), both proxying to a default cluster
-
A built-in local backend (
sozu-backend.serviceon127.0.0.1:8000) so the appliance answers a real request out of the box -
A local Unix-socket-only command channel — the proxy is never controllable from the network
-
A per-VM TLS certificate generated on first boot, documented in
/root/sozu-info.txt(0600)
Prerequisites
-
Active Azure subscription, SSH public key, VNet + subnet in target region
-
Subscription to the Sozu listing on Azure Marketplace
-
Network Security Group rules allowing TCP 22 (admin) and, for the traffic you want to proxy, TCP 80 and/or TCP 443
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for a light edge proxy. Higher throughput deployments should use Standard_D2s_v5 or larger.
Step 1: Deploy from the Azure Portal
Search Sozu in Marketplace, select the cloudimg publisher, and click Create. Configure the Network Security Group to allow TCP 80 and/or TCP 443 from the clients that will reach the proxy, and TCP 22 for administration.
Step 2: Deploy from the Azure CLI
RG="sozu-prod"; LOCATION="eastus"; VM_NAME="sozu1"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/sozu-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$GALLERY_IMAGE_ID" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 80 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 443 --priority 1002
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1003
Step 3: First boot
On first boot the image generates a per-VM self-signed TLS certificate into /etc/sozu/tls/, writes /root/sozu-info.txt, then systemd starts the local backend and Sozu. This completes within a few seconds. SSH in as azureuser and read the appliance info:
sudo cat /root/sozu-info.txt
Step 4: Confirm the services are running
sozu.service runs under systemd as the unprivileged sozu user. ss confirms Sozu is listening on :80 and :443, and the local backend on loopback 127.0.0.1:8000.
systemctl is-active sozu.service sozu-backend.service
ps -o user= -C sozu | head -1
ss -tlnp | grep -E ':80 |:443 |127.0.0.1:8000 '

Step 5: A real request flows through Sozu out of the box
The appliance proxies to its built-in local backend, so a request to http://localhost/ returns a real HTML body through Sozu. The default demo vhost sozu.appliance.local and the HTTPS listener (using the per-VM certificate) serve the same backend.
# Plain HTTP through Sozu on :80
curl -s http://localhost/ | head -3
# The documented demo vhost on :80
curl -s -H 'Host: sozu.appliance.local' http://localhost/ | grep -o 'cloudimg sozu appliance backend'
# HTTPS on :443 using the per-VM self-signed certificate
curl -sk --resolve sozu.appliance.local:443:127.0.0.1 https://sozu.appliance.local/ | grep -o 'cloudimg sozu appliance backend'

Step 6: The control channel is a local Unix socket only
Sozu is administered with the sozu CLI over its command socket, which is a local Unix socket (/run/sozu/sozu.sock) — it is never exposed on a TCP port, so the proxy cannot be reconfigured from the network. sozu status queries the live proxy over that socket, and ss confirms the only network listeners are the proxy's own :80/:443 and SSH.
ls -l /run/sozu/sozu.sock
sudo sozu --config /etc/sozu/config.toml status
# No control port on the network — only :80, :443 (proxy) and :22 (ssh) listen off-loopback
ss -tlnp | awk 'NR>1 {print $4}' | grep -vE '^(127\.|\[::1\])'

Step 7: Review the per-VM TLS material and the secure-by-default config
A unique self-signed TLS certificate is generated on this VM at first boot. Nothing is baked into the image. The config shows the Unix-socket command channel and the default cluster wired to the local backend.
sudo openssl x509 -in /etc/sozu/tls/cert.pem -noout -subject -fingerprint -sha256
grep -E '^command_socket|^\[\[listeners\]\]|^protocol|^address' /etc/sozu/config.toml
sudo stat -c '%n %a %U:%G' /etc/sozu/tls/key.pem /root/sozu-info.txt

Step 8: Point Sozu at your own backend
Replace the built-in demo backend with your own. Edit /etc/sozu/config.toml: add a frontend for your hostname and a backend pointing at your application, then reload Sozu with no downtime. In this example we route the hostname app.example.com to a backend on 10.0.0.10:8080.
sudo tee -a /etc/sozu/config.toml >/dev/null <<'EOF'
[clusters.my-app]
protocol = "http"
load_balancing = "ROUND_ROBIN"
frontends = [
{ address = "0.0.0.0:80", hostname = "app.example.com" },
]
backends = [
{ address = "10.0.0.10:8080", backend_id = "app-1" },
]
EOF
sudo systemctl reload sozu
Sozu re-reads the configuration and applies the new routing on the running proxy. Add more backends to the backends array for load balancing, and choose the algorithm with load_balancing (ROUND_ROBIN, RANDOM, LEAST_LOADED, POWER_OF_TWO).
Step 9: Reconfigure a live proxy at runtime with the CLI
Sozu's signature feature is hot reconfiguration: add clusters, frontends and backends to a running proxy over the command socket, with no restart and no dropped connections. For example, add a cluster and a backend at runtime:
sudo sozu -c /etc/sozu/config.toml cluster add --id runtime-app --load-balancing-policy round_robin
sudo sozu -c /etc/sozu/config.toml frontend http add --address 0.0.0.0:80 --hostname runtime.example.com id runtime-app
sudo sozu -c /etc/sozu/config.toml backend add --id runtime-app --backend-id b1 --address 10.0.0.20:8080
sudo sozu -c /etc/sozu/config.toml frontend list
Persist runtime changes across restarts by saving the live state: sudo sozu -c /etc/sozu/config.toml state save -f /etc/sozu/state.json and set saved_state = "./state.json" in the config.
Step 10: Enable HTTPS for your own domain
The image ships a per-VM self-signed certificate so HTTPS works out of the box for testing. For production, install your CA-issued certificate and key, reference them from the HTTPS listener (or a specific HTTPS frontend) in /etc/sozu/config.toml, and reload. Replace the paths with your own PEM files:
sudo install -o root -g sozu -m 0640 /path/to/your-cert.pem /etc/sozu/tls/cert.pem
sudo install -o root -g sozu -m 0640 /path/to/your-key.pem /etc/sozu/tls/key.pem
sudo systemctl reload sozu
Step 11: Security recommendations
-
Restrict the NSG. Allow TCP 80/443 only from the networks that should reach the proxy, and TCP 22 for administration only.
-
Keep the command channel local. The Sozu command socket ships as a local Unix socket; never point it at a TCP address. Administer over SSH with the
sozuCLI. -
Use your own TLS certificate in production. The per-VM certificate is self-signed for out-of-box testing; install a CA-issued certificate for public traffic.
-
Scope your frontends. Route only the hostnames you serve; a frontend only matches requests whose
Hostheader equals itshostname. -
Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Step 12: Support and Licensing
Sozu is developed by the Sozu project (Clever Cloud and contributors) and distributed under the GNU Affero General Public License v3.0 (AGPL-3.0). The full licence text ships on the image at /usr/share/doc/sozu/LICENSE. This cloudimg image installs the unmodified upstream Sozu 2.2.0. cloudimg provides the packaging, the secure default configuration, the per-VM TLS automation, security patching, and 24/7 support with a guaranteed 24 hour response SLA.
cloudimg is not affiliated with or endorsed by the Sozu project. Sozu is a mark of its respective owner and is used here only to identify the software.
Deploy on Azure
Find Sozu HTTP Reverse Proxy / Load Balancer on Ubuntu 24.04 LTS on the Azure Marketplace, published by cloudimg. Deploy from the Portal or the Azure CLI as shown above.
Need Help?
Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.