Umami - Hardened Self-Hosted Privacy-Friendly Web Analytics
por Lynxroute
Umami 3.1.0 - CIS Level 1 hardened, privacy-friendly web analytics on Ubuntu 24.04 with SBOM
What is Umami
Umami is a privacy-friendly, open-source web analytics platform. It tracks pageviews, sessions, events, referrers, devices, and custom events without setting cookies and without storing personal data, which removes the need for cookie consent banners on most jurisdictions (GDPR, CCPA, PECR). Owners manage multiple sites in one dashboard, share read-only public pages, define custom event tracking, and build their own dashboards via Boards. Backed by PostgreSQL 15. MIT license, no vendor lock-in.
Why self-host Umami
Self-hosting puts your visitor data, event stream, and dashboards entirely under your control - no per-pageview SaaS pricing, no third-party tracking pixel, and no risk of an account suspension cutting off analytics across all your sites. Ideal for organisations with data residency requirements (GDPR, HIPAA, ISO 27001), regulated industries, public-sector sites, and operators who need predictable infrastructure costs instead of usage-based analytics pricing.
What this VM image adds
Security hardening:
- Default admin password rotated at first boot - the seeded upstream password is replaced with a random 24-character password via the official Umami password-change API before the VM accepts external traffic, then verified to no longer authenticate. The new password is written to /root/umami-credentials.txt.
- Umami app bound to 127.0.0.1:3000 - reachable only through the Nginx reverse proxy with TLS, never directly exposed on the host network
- PostgreSQL 15 inside the Docker compose bridge - no host port mapping, no exposure on TCP 5432
- Per-instance database password generated at first boot - random 32-char alphanumeric, written to /root/umami-credentials.txt
- Per-instance APP_SECRET generated at first boot for session cookie signing
- Nginx reverse proxy with TLS - HTTP to HTTPS redirect, hardened cipher suite, security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy)
- Trivy CVE + secret scan - every image is scanned for vulnerabilities and leaked credentials before release
- UFW firewall - only ports 22 (SSH), 80, and 443 open
- fail2ban - SSH brute-force protection
- AppArmor - mandatory access control
- Certbot pre-installed - one command issues a Let's Encrypt certificate after you point a domain at the VM
OS hardening (CIS Level 1):
- CIS Level 1 hardened - CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
- auditd - system call auditing for critical paths
- SSH hardening - PasswordAuthentication disabled, key-only access
- Kernel hardening - SYN cookies, ASLR, rp_filter, TCP BBR
- /tmp as tmpfs - nosuid, nodev, noexec
- Azure IMDS endpoints - egress rules pre-configured (169.254.169.254, 168.63.129.16)
Compliance artifacts (inside the VM):
- SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json
- CIS Conformance Report - OpenSCAP HTML at /etc/lynxroute/cis-report.html
- Tailored CIS profile - /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
- Server credentials file - /root/umami-credentials.txt with public IP, web UI URL, the per-instance admin password, and the per-instance PostgreSQL password
Quick Start
- Deploy VM from Azure Marketplace (Standard_D2s_v3 or larger recommended)
- Open NSG: TCP 443 from your client networks, TCP 22 from your management IPs only
- SSH: ssh -i key.pem <username>@<PUBLIC_IP> (username set during VM creation, default: azureuser)
- Read connection details: sudo cat /root/umami-credentials.txt - contains web UI URL, admin password, and the PostgreSQL password
- Open https://<PUBLIC_IP> in your browser, accept the self-signed certificate, log in as admin
- Add a website in Settings -> Websites -> Add, then paste the generated tracking snippet into the <head> of your site
- Issue a public TLS certificate (recommended before sharing dashboards): sudo certbot --nginx -d your.domain.com
The image ships with a self-signed certificate so the web UI works on first boot - replace it with a CA-signed certificate before exposing the server to end users.