Uw
Security Azure

UUSEC WAF on Ubuntu 24.04 on Azure User Guide

| Product: UUSEC WAF 7.2.5 on Ubuntu 24.04 LTS on Azure

Overview

UUSEC WAF (uuWAF) is an open source, self hosted Web Application Firewall and reverse proxy that protects web applications from attacks and exploits. Rather than relying only on lists of regular expression signatures, it combines a semantic detection engine that parses each request the way the target application would, machine learning anomaly detection and runtime application self protection, so it recognises the intent behind SQL injection, cross site scripting, command injection and path traversal while letting legitimate traffic through. You place a protected site in front of your upstream server, point its domain at the WAF, and every request is inspected before it reaches your application, with attacks answered by an interception page and clean traffic marked with a Server: uuWAF header. The cloudimg image installs UUSEC WAF 7.2.5 as the official Safe3/uusec-waf Docker Compose stack and runs it as a systemd service, so a working management console and WAF are online within minutes of launch.

What is included:

  • UUSEC WAF 7.2.5 (BSD-2-Clause) deployed from the official Safe3/uusec-waf Docker Compose stack, pinned to the uusec/waf:7.2.5 image so the appliance never silently upgrades
  • Docker Engine (Docker CE) and the Docker Compose plugin, installed from the official Docker package repository
  • The uuWAF Compose stack (two containers): uuwaf (the OpenResty/Nginx+Lua WAF engine and the Go management backend, binding the reverse proxy ports 80 and 443 and the management console on HTTPS port 4443) and wafdb (MySQL 5.7, the management database, reachable only on the loopback interface and the internal container network)
  • A per-VM admin console password: UUSEC WAF ships upstream with the shared default admin / #Passw0rd, and the cloudimg image rotates that default away on first boot and proves the default is rejected
  • Two systemd units: uusec-waf.service (a oneshot wrapper around docker compose up -d) and uusec-waf-firstboot.service
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key, and a VNet and subnet. Standard_B2s (2 vCPU / 4 GB RAM) is the recommended size. NSG inbound rules: allow 22/tcp from your management CIDR for SSH, 4443/tcp from the CIDR that needs the UUSEC WAF management console, and 80/tcp and 443/tcp from the internet for the web traffic you want the WAF to protect (uuWAF's reverse proxy binds ports 80 and 443 for the sites you add).

Step 1: Connect over SSH

Replace <vm-ip> with the public IP of your VM. The default login user is azureuser.

ssh azureuser@<vm-ip>

Step 2: Confirm the services are active

sudo systemctl is-active docker uusec-waf
docker --version
docker compose version

You should see active printed twice, the Docker Engine version, and the Docker Compose v2 plugin version.

Docker and UUSEC WAF systemd services active with the uuWAF Compose stack containers running

Step 3: Confirm the UUSEC WAF containers are running

cd /opt/waf && sudo docker compose -f docker-compose.yml --env-file .env ps

You should see the two uuWAF containers — uuwaf (the WAF engine and console) and wafdb (the MySQL database, reported healthy) — in the Up / running state.

Step 4: Confirm the management console is healthy

The management console is served over HTTPS on port 4443. It uses a self signed certificate, so curl is called with -k. A 200 confirms the console is up.

curl -ks -o /dev/null -w "%{http_code}\n" https://localhost:4443/

Step 5: Read the per-VM admin credentials

UUSEC WAF ships upstream with a shared default console login (admin / #Passw0rd). The cloudimg image rotates that default away on the first boot of every instance and writes the unique admin password to a root only file. The default no longer works.

sudo cat /root/uusec-waf-credentials.txt

This file lists uusec-waf.url (where to sign in), uusec-waf.admin.user (admin) and uusec-waf.admin.pass. Store the password somewhere safe.

The per-VM UUSEC WAF admin credentials file, with the password shown on this instance only

Step 6: Sign in to the UUSEC WAF console

Browse to https://<vm-ip>:4443/ in your browser. Because the console uses a self signed certificate, your browser warns once — accept it to continue. You then reach the sign in page, where you log in with the username admin and the uusec-waf.admin.pass from Step 5. Leave the OTP field empty unless you later enable dynamic (one time) passwords.

The UUSEC WAF management console sign in page

After signing in you land on the dashboard, which summarises total visits, blocked attacks, live request metrics, the geographic origin of attack sources and the current system resource usage.

The UUSEC WAF dashboard showing total visits, total blocks and live attack metrics

For extra security, UUSEC WAF recommends creating a new administrator with a hard to guess name, deleting the default admin, and enabling dynamic passwords — all from the console.

Step 7: Protect your first web application

To put UUSEC WAF in front of a web application, open Site Security (Sites) in the console and choose Add Site. Give it the domain (or a match all host), and the upstream address of your origin server (for example 127.0.0.1:8080 or 10.0.0.4:3000) with its scheme. The WAF reverse proxy on ports 80 and 443 then routes requests for that domain to your origin, inspecting every request first. Finally, point the domain's DNS A record at the VM's public IP.

The UUSEC WAF Site Security page listing a protected site defended by the WAF

Step 8: How UUSEC WAF blocks attacks

Once a site is protected, UUSEC WAF passes clean traffic straight through to your origin and intercepts attacks. A benign request returns your application's normal response with a Server: uuWAF header; an obvious SQL injection or cross site scripting probe is answered with an HTTP 403 interception page instead of ever reaching your origin.

A benign request returns HTTP 200 while SQL injection and cross site scripting probes are intercepted with HTTP 403

The visitor who sends the malicious request sees UUSEC WAF's interception page, with the rule id that matched. The blocked event is also logged and surfaced in the console.

The UUSEC WAF interception page shown to a blocked attacker

Secure by default

The management console requires authentication, the MySQL database is bound to the loopback interface and the internal container network only (it is never published on a public interface), and anonymous API calls are rejected. You can confirm which ports are exposed on the host and that the console is healthy at any time.

sudo ss -tlnp | grep -E ':80|:443|:4443|:6612' || true

You will see the WAF proxy on 80 and 443 and the console on 4443 on all interfaces, while MySQL on 6612 is bound to 127.0.0.1 only — the database is not reachable from the network.

UUSEC WAF secure by default: the console is healthy over HTTPS, the database is not exposed on a public interface, and anonymous API calls are rejected

Step 9: Manage the stack

The whole stack is managed by the uusec-waf.service systemd unit, which wraps docker compose under /opt/waf.

sudo systemctl restart uusec-waf.service
sudo systemctl status uusec-waf.service --no-pager

To inspect the logs for a specific service:

cd /opt/waf && sudo docker compose -f docker-compose.yml --env-file .env logs --tail 50 uuwaf

Enabling HTTPS on your own domain

The management console already serves HTTPS on port 4443 with a self signed certificate. For the sites you protect, add your own TLS certificate under Certificates in the console and bind it to the site, or let UUSEC WAF apply for and auto renew a free Let's Encrypt certificate, so the WAF terminates HTTPS for your application on port 443. Add 443/tcp to your NSG inbound rules.

First-boot security model

On the first boot of each VM, uusec-waf-firstboot.service runs once and:

  • Regenerates the MySQL password and initialises the database clean, so no build time database or secret ships in the image
  • Rotates the upstream default admin password (#Passw0rd) to a fresh, strong, per-VM value and writes it to /root/uusec-waf-credentials.txt (root only, mode 0600), then proves the default is rejected
  • Records a sentinel so the stack only starts once the credential has been rotated

No shared or default login and no preexisting protected site ship in the image. The management console is protected by this per-VM credential the moment it comes up.

Support

24/7 technical support is included. Contact cloudimg at support@cloudimg.co.uk for help with deployment, protecting your applications, the semantic detection engine and custom rules, machine learning and RASP defence, bot and CC attack protection, TLS certificates and custom domains, and the UUSEC WAF API.


UUSEC WAF and uuWAF are names of the open source project by Safe3 (github.com/Safe3/uusec-waf), used here nominatively to identify the software this image packages. MySQL is a trademark of Oracle Corporation. Docker is a trademark of Docker, Inc. All other product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.