DMARC Report Viewer on Ubuntu 24.04 on Azure User Guide
Overview
DMARC Report Viewer is a lightweight, standalone viewer for DMARC aggregate reports and SMTP TLS reports. It is a single Rust binary that combines a report parser, an IMAP client and an embedded HTTP server: it connects to a mailbox, fetches the report emails that mail receivers send back to you, parses the XML and JSON, and renders an analytics web dashboard with per domain and per organisation summaries, SPF and DKIM pass and fail counts, and ranked source IP addresses. It keeps no external database; report data is held in memory and refreshed from the mailbox on a schedule, which makes it simple to run and reason about.
This cloudimg image runs the viewer bound to the loopback interface behind nginx, which serves the dashboard over HTTPS with HTTP Basic Authentication. A local Dovecot IMAP server on the same VM provides an on-box inbox for your DMARC reports, and you can just as easily point the viewer at your own mailbox instead. Every deployed VM mints its own dashboard password, its own inbox password and its own TLS certificate on first boot, and the image ships with an empty inbox and no seeded data.

What is included:
- DMARC Report Viewer 2.6.0, the official prebuilt release binary (MIT licensed), installed at
/opt/dmarc-report-viewer/dmarc-report-viewerand run by thedmarc-report-viewer.servicesystemd unit as an unprivileged service account. - A local Dovecot IMAP server bound to
127.0.0.1:143that acts as the on-box DMARC inbox. - nginx as an HTTPS reverse proxy on port 443 (per-VM self-signed certificate), forwarding to the viewer on
127.0.0.1:8080. Port 80 redirects to 443. - A one-shot first-boot service that generates a unique dashboard password, a unique inbox password and a unique TLS certificate for each VM, and writes the login to
/root/dmarc-report-viewer-credentials.txt(mode 0600). - A start-time guard that refuses to start the viewer if a placeholder or example credential is ever in effect, and a built-in self-test that proves the full parse pipeline on the running VM.
1. Launch the VM
From the Azure Marketplace
- Open the cloudimg DMARC Report Viewer on Ubuntu 24.04 LTS offer in the Azure Marketplace and select Create.
- Choose a resource group and region, and a VM size.
Standard_B2sis the recommended minimum and is comfortable for this workload. - Under Inbound port rules, allow SSH (22) and HTTPS (443). Do not expose any other port; the viewer and the IMAP server are bound to loopback and are never reachable from the network.
- Create or select an SSH key pair, then review and create.
From the Azure CLI
az vm create \
--resource-group my-dmarc-rg \
--name dmarc-report-viewer \
--image <cloudimg-dmarc-report-viewer-urn> \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
az vm open-port --resource-group my-dmarc-rg --name dmarc-report-viewer --port 443 --priority 900
2. Retrieve the per-VM dashboard login
Each VM generates its own dashboard credentials on first boot and writes them to a root-only file. SSH in and read them:
sudo cat /root/dmarc-report-viewer-credentials.txt
You will see the dashboard URL, the username (admin), the generated dashboard password, and the local inbox details. Two VMs deployed from the same image never share these values.
Confirm the stack is healthy — all three services should report active, and the app and IMAP server should be listening on loopback only:
systemctl is-active dmarc-report-viewer dovecot nginx
ss -ltn | grep -E ':8080|:143|:443|:80 ' | sort

3. Sign in
Open https://<your-vm-ip>/ in a browser. Because the certificate is a per-VM self-signed certificate, your browser will warn once — accept it (or install your own certificate, see section 7). Sign in with the username admin and the password from the credentials file.
On a fresh VM the dashboard loads with an empty inbox — zero reports — which is expected: no report data ships in the image. The next section gets your reports flowing.
4. Get your DMARC reports into the viewer
You have two options, and you can use either or both.
Option A — deliver reports to the on-box inbox. The image runs a local Dovecot IMAP server. Configure your domain's DMARC record (rua=) or a forwarding rule so that the aggregate report emails are delivered to the on-box mailbox, and the viewer will pick them up automatically on its next check.
Option B — point the viewer at your own mailbox. If you already receive DMARC reports in an existing mailbox, point the viewer straight at it by editing the environment file and restarting the service (see section 6). This is the most common production setup.
See the pipeline working now
The image ships with a built-in self-test that injects a set of genuine sample DMARC reports into the on-box inbox, confirms the viewer fetches and parses them and renders them in the dashboard, and then removes them again — so you can watch the whole pipeline end to end before wiring up your own mail flow:
sudo /usr/local/sbin/drv-selftest.sh roundtrip
It authenticates to the dashboard API, injects three real sample reports, asserts the parsed report count is non-zero, and restores the empty inbox. The parsed summary looks like this:

To keep the sample reports on screen while you explore the dashboard, run sudo /usr/local/sbin/drv-selftest.sh inject, look around, then sudo /usr/local/sbin/drv-selftest.sh cleanup to empty the inbox again.
5. Read the dashboard
DMARC Reports lists every parsed report with its reporting organisation, the domain it covers, and any SPF, DKIM or DMARC problems:

Open a report to see its full detail — the published policy, the date range, and every record with its source IP and evaluation result. You can also export the raw XML or JSON:

Mail Sources ranks the source IP addresses seen across your reports, with the count, the domain, and a flag for any source with authentication issues — the quickest way to spot an unauthorised or misconfigured sender:

The Dashboard rolls all of this up into summary charts of organisations, domains, and SPF and DKIM pass and fail rates, with a time span and per domain filter.
6. Point the viewer at your own mailbox
The viewer's configuration lives in /etc/dmarc-report-viewer/drv.env. To read your reports from a remote mailbox instead of the on-box inbox, set the IMAP host, user and password to your provider's values and switch to TLS (port 993). For example:
# /etc/dmarc-report-viewer/drv.env
IMAP_HOST=imap.your-mail-provider.com
IMAP_PORT=993
IMAP_USER=dmarc@your-domain.com
IMAP_PASSWORD=your-mailbox-password
IMAP_FOLDER=INBOX
IMAP_CHECK_INTERVAL=1800
HTTP_SERVER_BINDING=127.0.0.1
HTTP_SERVER_PORT=8080
HTTP_SERVER_USER=admin
HTTP_SERVER_PASSWORD=your-dashboard-password
Remove the --imap-disable-tls flag from the service if you set a remote host — TLS is the default and should always be used for a remote mailbox. Then restart the service:
sudo systemctl restart dmarc-report-viewer.service
7. Security model
- Per-VM secrets. The dashboard password and the on-box inbox password are generated with
openssl randon first boot and written only to/etc/dmarc-report-viewer/drv.env(mode 0640) and the root-only credentials file (mode 0600). Nothing is baked into the image, and no two VMs share a credential. - Start-time guard. The service refuses to start if the dashboard or inbox secret is empty, too short, or a known example value, so a misconfigured redeploy can never bring the dashboard up with a weak credential.
- Loopback isolation. The viewer (
8080) and the IMAP server (143) bind to127.0.0.1only; the sole network-facing service is nginx on443.
sudo /usr/local/sbin/drv-guard.sh
ls -l /root/dmarc-report-viewer-credentials.txt

Production TLS with a real certificate
The image ships a per-VM self-signed certificate so the dashboard is encrypted out of the box. For a browser-trusted certificate, either replace /etc/dmarc-report-viewer/tls/server.crt and server.key with your own and reload nginx, or front the VM with a certificate-terminating load balancer or a reverse proxy such as Caddy. The viewer also supports automatic Let's Encrypt certificates directly if you assign it a public DNS name and expose port 443.
8. Maintenance
The image boots fully patched and keeps unattended security updates enabled. Check the OS baseline and the running services at any time:
systemctl is-enabled dmarc-report-viewer dovecot nginx dmarc-report-viewer-firstboot
apt-get -s -o APT::Get::Always-Include-Phased-Updates=true dist-upgrade | grep -c '^Inst ' || true

Because the viewer holds no database, there is nothing to back up beyond your configuration in /etc/dmarc-report-viewer/drv.env; the report data always comes fresh from the mailbox. To upgrade the viewer, replace the binary at /opt/dmarc-report-viewer/dmarc-report-viewer with a newer release and restart the service.
Support
This image is built and maintained by cloudimg. If you need help, contact cloudimg support with your VM details and the output of systemctl status dmarc-report-viewer.service.