Networking Azure

Zonemaster on Ubuntu 24.04 on Azure User Guide

| Product: Zonemaster on Ubuntu 24.04 LTS on Azure

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.

The Zonemaster graded report for a domain, showing every test module with its per severity result counts

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.service and nginx.service as 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

  1. In the Azure portal, choose Create a resource and search the Marketplace for the cloudimg Zonemaster offer.
  2. Select the plan, then Create.
  3. On the Basics tab pick your subscription, resource group and region, name the VM, and select Standard_B2s (or larger).
  4. Choose SSH public key authentication with admin username azureuser and provide your public key.
  5. On the Networking tab, allow inbound 22/tcp from your management network and 80/tcp for the web interface.
  6. 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.

systemctl reporting docker, zonemaster and nginx active, and the single all in one container running with the GUI bound to loopback only

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

The security round trip: a no auth request returns 401, a wrong password returns 401, the per VM credential authenticates, a real graded test runs, and the backend ports are refused off box

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.

The per VM access notes, with the Zonemaster URL, the admin user name and the password masked

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.

The Zonemaster domain checkup page: enter a domain name and run a complete DNS and DNSSEC checkup

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.

The graded report for zonemaster.net, with the severity level filter showing the Info, Notice, Warning, Error and Critical counts and the test modules below

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.

The test modules of the graded report, each with its per severity result counts: Delegation, DNSSEC, Nameserver, Consistency and the rest

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.

The JSON-RPC API returning the component versions and a real graded DNS and DNSSEC test for zonemaster.net summarised by severity level and module

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.