AdGuard Home Unbound
Overview
AdGuard Home is a network-wide DNS server that blocks ads, trackers and malicious domains for every device that points its DNS at it. No client software is needed on each device.
This SecureAnyCloud image pairs AdGuard Home 0.107.78 with Unbound, a validating, recursive, caching DNS resolver that acts as AdGuard's private upstream on the loopback address 127.0.0.1:5335. Instead of forwarding lookups to a third-party public resolver, Unbound resolves every query directly from the DNS root servers with DNSSEC validation. No external DNS provider sees your browsing, and every answer is cryptographically verified.
Point a single device or your whole router at this VM on port 53. Its DNS lookups are then filtered by AdGuard, resolved recursively by Unbound, logged, and shown in a web dashboard.
What you get:
- AdGuard Home 0.107.78 managed by systemd, serving DNS on port 53 (UDP and TCP)
- Unbound, a validating recursive resolver bound to
127.0.0.1:5335, set as AdGuard's private upstream - Recursive, DNSSEC-validated resolution directly from the DNS root servers, with no third-party public resolver
- The built-in AdGuard web admin, bound to
127.0.0.1:3000and served on port 80 by an nginx reverse proxy - The AdGuard DNS filter enabled out of the box, so ads and trackers are blocked immediately
- A unique admin username and password generated on the first boot of every VM and recorded in a root-only file
- A dedicated Azure data disk at
/var/lib/adguardhomeholding the configuration, query logs, statistics and filter caches - The systemd-resolved stub listener disabled during the build, so AdGuard owns port 53 on Ubuntu 24.04
unbound.service,AdGuardHome.serviceandnginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size.
Configure the network security group (NSG) with these inbound rules:
22/tcpfrom your management network, for SSH80/tcpfor the web admin53/udpand53/tcp, so devices can use the server for DNS
AdGuard serves the admin over plain HTTP on port 80. For production, terminate TLS in front of it with your own domain (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for AdGuard Home Unbound by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Review the dedicated data disk on the Disks tab, then select Review + create and Create. After deployment, add inbound rules for DNS on UDP 53 and TCP 53 so your devices can query the server.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:adguard-home-unbound-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name adguard-home-unbound \
--image sac1647283583153:adguard-home-unbound-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name adguard-home-unbound --port 80 --priority 1010
az network nsg rule create --resource-group <your-rg> --nsg-name <your-nsg> \
--name allow-dns-udp --priority 1020 --protocol Udp --destination-port-ranges 53 --access Allow
az network nsg rule create --resource-group <your-rg> --nsg-name <your-nsg> \
--name allow-dns-tcp --priority 1030 --protocol Tcp --destination-port-ranges 53 --access AllowStep 3 - Connect to your VM
Connect over SSH as the azureuser administrator account:
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Check that Unbound, AdGuard Home and nginx are all active:
systemctl is-active unbound.service AdGuardHome.service nginx.serviceAll three report active. Each has a distinct role:
- Unbound is the private recursive resolver on
127.0.0.1:5335. - AdGuard Home serves DNS on port 53 (UDP and TCP) and its web admin on the loopback address
127.0.0.1:3000. - nginx serves the admin on port 80.
All AdGuard configuration, query logs and statistics live on the dedicated Azure data disk mounted at /var/lib/adguardhome.
Step 5 - Retrieve your admin login
Your VM generates a unique AdGuard admin username and password on first boot and writes them to a root-only file. Read it as root:
sudo cat /root/adguardhome-credentials.txtThe file contains ADGUARD_USERNAME, ADGUARD_PASSWORD and the URL to open. Store them somewhere safe.
Step 6 - Confirm recursive DNSSEC resolution through Unbound
Unbound resolves every query directly from the DNS root servers and validates DNSSEC signatures. Query it on 127.0.0.1:5335. A signed domain should come back with the ad (Authenticated Data) flag set, which proves DNSSEC validation is working:
dig @127.0.0.1 -p 5335 example.com +short dig @127.0.0.1 -p 5335 +dnssec cloudflare.com | grep -E '^;; flags'The first command returns a normal address. The second shows flags: qr rd ra ad, and the ad flag confirms that Unbound cryptographically validated the answer. AdGuard is configured to send all upstream queries to this resolver.
Now check the health endpoint:
curl -s http://localhost/healthzThe health endpoint returns ok. AdGuard's upstream is set to 127.0.0.1:5335 out of the box, so no third-party public resolver is used.
Step 7 - Verify DNS filtering and authentication from the command line
Confirm that the DNS server resolves a normal domain and blocks a known ad domain:
dig @127.0.0.1 example.com +short dig @127.0.0.1 ad.doubleclick.net +shortexample.com returns a normal address, while the ad domain returns 0.0.0.0 because the AdGuard DNS filter blocks it.
AdGuard also rejects a wrong admin password and issues a session cookie for the correct one. Read the password from Step 5, then post it to the login endpoint. Substitute the value of ADGUARD_PASSWORD for <ADGUARD_PASSWORD>. Because the command embeds your unique password, run it interactively rather than from a script:
curl -s -o /dev/null -w '%{http_code}\n' -c cookies.txt -H 'Content-Type: application/json' -X POST --data '{"name":"admin","password":"<ADGUARD_PASSWORD>"}' http://127.0.0.1/control/login; grep -o 'agh_session' cookies.txt
A correct password returns 200 and prints agh_session (the session cookie was set). A wrong password returns 403 and sets no session cookie.
Step 8 - Sign in to the dashboard
Browse to http://<vm-public-ip>/. AdGuard Home opens its sign-in page. Enter the username and password from Step 5.
After you sign in, the dashboard shows live query statistics: total DNS queries, how many filters blocked, the busiest clients and the average processing time.
Step 9 - Confirm the private Unbound upstream in the dashboard
Open Settings > DNS settings. The Upstream DNS servers box shows 127.0.0.1:5335, the private Unbound resolver. Every lookup is therefore resolved recursively from the root servers with DNSSEC validation, and no third-party resolver is contacted.
Step 10 - Point your devices at the server and watch the query log
On a device or your router, set the DNS server to the VM's public IP. Every lookup from that device now flows through AdGuard.
Open Query Log to see which domains were processed and which were blocked, per client, in real time.
Step 11 - Manage blocklists
Open Filters > DNS blocklists to review the enabled blocklists. The image ships with the AdGuard DNS filter enabled.
Add more blocklists with Add blocklist. Write your own rules under Custom filtering rules, and allow specific domains with an allowlist.
Step 12 - Confirm state lives on the dedicated disk
AdGuard's configuration, query logs and statistics are stored under /var/lib/adguardhome on the dedicated Azure data disk, so they survive OS changes and can be resized independently. Confirm the mount:
findmnt /var/lib/adguardhomeThe mount is backed by a separate Azure data disk captured into the image and re-provisioned on every VM.
Maintenance
- Admin login: the per-VM credentials live in
/root/adguardhome-credentials.txt. To change the password, sign in to the dashboard and use Settings, or reconfigure through the AdGuard admin. - Upstream resolver: AdGuard forwards to the private Unbound resolver on
127.0.0.1:5335. Unbound's configuration is at/etc/unbound/unbound.conf.d/sac-adguardhome.conf. After any change, runsudo systemctl restart unbound. Keep AdGuard's upstream under Settings > DNS settings pointing at127.0.0.1:5335to preserve recursive, DNSSEC-validated resolution. - Blocklists: add and enable blocklists under Filters > DNS blocklists. They update automatically on a schedule.
- Storage: all AdGuard runtime state lives under
/var/lib/adguardhomeon the data disk. Back up that volume to protect your configuration and history. - Services: the units are
unbound.service,AdGuardHome.serviceandnginx.service. After any AdGuard change, runsudo systemctl restart AdGuardHome. - TLS: the admin is served over plain HTTP on port 80. For production, front it with TLS, for example with certbot and your own domain. AdGuard Home can also serve DNS over HTTPS and DNS over TLS once you add a certificate under Settings > Encryption settings.
- Security patches: unattended-upgrades stays enabled, so the OS continues to receive security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
Deploy on Azure
Launch AdGuard Home Unbound on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com