Zonemaster on Ubuntu 24.04 on Azure User Guide
Overview
Zonemaster is an open source DNS delegation and DNSSEC quality and health checker, maintained jointly by The Swedish Internet Foundation (IIS) and AFNIC. Give it a domain and it runs the full Zonemaster test suite across the Address, Basic, Connectivity, Consistency, Delegation, DNSSEC, Nameserver, Syntax, System and Zone modules, then returns a graded report with info, notice, warning, error and critical findings so you can see exactly what is right and wrong with a zone's delegation and DNSSEC. The cloudimg image runs Zonemaster the officially supported way, as the upstream all in one container (CLI, Backend, GUI and Engine) pinned by digest and captured into the VM, so your instance starts in seconds. Because Zonemaster has no built in login, cloudimg fronts the web GUI with a unique HTTP Basic Auth credential generated for each VM on first boot, and keeps the backend, test agent and results database inside the container, never exposed on a routable port. Backed by 24/7 cloudimg support.
Zonemaster is a project of The Swedish Internet Foundation and AFNIC. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the Zonemaster project. It ships the free and open source BSD 2-Clause software, unmodified.

What is included:
- The official Zonemaster all in one container (Zonemaster CLI, Backend, GUI and Engine), pinned by image digest
- A web GUI for running tests and a JSON-RPC API for automation, both on one VM
- Docker Engine (Docker CE) with the container published to the loopback interface only, fronted by nginx on port
80 zonemaster.service,zonemaster-firstboot.serviceandnginx.serviceas systemd units, enabled and active on boot- A unique HTTP Basic Auth credential generated per VM on first boot, never baked into the image
- A clean, empty results database on first boot: no default account, no shipped secret, no prior test data
- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable fit: the all in one container uses roughly 300 MiB and leaves over 3 GiB free even while running several domain tests at once. NSG inbound: allow 22/tcp from your management network and 80/tcp (and 443/tcp once you add TLS) for the web interface. The web GUI is served over plain HTTP on port 80 behind HTTP Basic Auth; for production, put it behind TLS with your own domain (see the final section).
Step 1 - Deploy from the Azure Marketplace
- In the Azure portal, choose Create a resource and search the Marketplace for the cloudimg Zonemaster offer.
- Select the plan, then Create.
- On the Basics tab pick your subscription, resource group and region, name the VM, and select Standard_B2s (or larger).
- Choose SSH public key authentication with admin username
azureuserand provide your public key. - On the Networking tab, allow inbound
22/tcpfrom your management network and80/tcpfor the web interface. - Review and create. When the VM is running, note its public IP address.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group my-zonemaster-rg \
--name zonemaster \
--image cloudimg:zonemaster:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
# Open the port the web interface needs (SSH is opened by default):
az vm open-port --resource-group my-zonemaster-rg --name zonemaster --port 80 --priority 900
Step 3 - Connect to your VM
Replace <vm-ip> with your VM's public IP address:
ssh azureuser@<vm-ip>
Step 4 - Confirm the services are running
Docker, the Zonemaster all in one container and nginx all come up automatically on first boot. Confirm they are active:
sudo systemctl is-active docker zonemaster nginx
Expected output:
active
active
active
The whole stack runs as a single official container. The web GUI is published only to the loopback interface (127.0.0.1:8080), with nginx in front on port 80; the backend JSON-RPC API (:5000), the test agent and the SQLite results database never leave the container network.

Step 5 - Secure by default: a unique credential and closed internal ports
Zonemaster has no built in login, and its public instances are open. On a public server that is a risk. The cloudimg image closes it. On first boot, before the port is reachable, a unique HTTP Basic Auth credential (user admin plus a random password) is generated for this VM, so the web GUI is protected from the moment it is reachable. A request with no credential is rejected, a wrong password is rejected, and only the per VM credential is accepted, while the backend API and results database are never reachable on a routable port:
sudo /usr/local/sbin/zonemaster-roundtrip.sh
Expected output (an OK line proving the whole model, then a no auth request rejected):
OK zonemaster: no-auth 401; per-VM cred authenticates; wrong-cred 401; anon /api 401; zonemaster.net graded report 84 results across 10 modules; internal :5000/:8080 refused off-box
no-auth GET / -> 401

Step 6 - Read your per-VM credential
Read your unique web credential (it is written to a root only file):
sudo cat /root/zonemaster-credentials.txt
The file holds the web URL, the user name (admin) and the per VM password. Keep it safe.

Step 7 - Sign in to the web GUI
Open http://<vm-ip>/ in your browser. Your browser prompts for the HTTP Basic Auth credential: sign in with user admin and the password from the credentials file. You are then met with the Zonemaster domain checkup page.

Step 8 - Run your first domain test
Type a domain into the box, for example zonemaster.net, and select Run test. Zonemaster investigates the zone from the root of the DNS tree down to the domain's own authoritative nameservers, then presents a graded report. The Filter severity levels row summarises the findings as Info, Notice, Warning, Error and Critical, with a count beside each level, so you can see the health of the zone at a glance.

Step 9 - Read the graded report by module
The report groups its findings into the Zonemaster test modules: System, Basic, Address, Connectivity, Consistency, Delegation, DNSSEC, Nameserver, Syntax and Zone. Each module carries a badge with its per severity result counts, and expands to show the individual test cases with their severity and an explanation. Use Expand all modules to open them all, or the search box to find a specific message.

Step 10 - Automate with the JSON-RPC API
The same backend that powers the GUI exposes a JSON-RPC API behind the same Basic Auth, so you can drive tests from scripts. Read your credential, ask for the component versions, start a test and fetch its graded results:
U=$(sudo grep '^ZONEMASTER_USER=' /root/zonemaster-credentials.txt | cut -d= -f2)
P=$(sudo grep '^ZONEMASTER_PASSWORD=' /root/zonemaster-credentials.txt | cut -d= -f2)
curl -s -u "$U:$P" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"version_info"}' http://127.0.0.1/api/
Expected output (the baked component versions):
{"result":{"zonemaster_backend":"12.1.1","zonemaster_engine":"v9.0.0","zonemaster_ldns":"5.1.0"},"id":1,"jsonrpc":"2.0"}
Start a test for a domain and note the returned test id, poll test_progress until it reaches 100, then call get_test_results with that id to retrieve the graded report as JSON.

Step 11 - Production: your own domain with TLS
The web GUI is served over plain HTTP on port 80 behind HTTP Basic Auth. For production, point a DNS record at the VM and add TLS. A common approach is to add a certificate to nginx with Certbot:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d zonemaster.example.com
To change the web credential, set a new password for the admin user and reload nginx:
sudo htpasswd -bB /etc/nginx/.zonemaster.htpasswd admin '<new-password>'
sudo systemctl reload nginx
Support
Every cloudimg image includes 24/7 support. If you have any questions about deploying or operating Zonemaster on Azure, contact the cloudimg team through the Azure Marketplace listing or at www.cloudimg.co.uk.