AdGuard Home is a DNS server that blocks ads and trackers, with a clean web interface. Unlike Pi-hole, it can serve encrypted DNS — DNS-over-HTTPS (DoH), DNS-over-TLS (DoT) and DNS-over-QUIC — out of the box. That makes it ideal on a VPS: phones and browsers can use it directly as “Private DNS”, from any network, without a VPN.
Security first: don’t create an open resolver
Plain DNS on port 53 open to the world will be abused for amplification attacks. With AdGuard Home on a VPS:
- Don’t open UDP/TCP 53 publicly — or only to your own static IPs.
- Serve clients over DoH/DoT, which are TCP/TLS based and much harder to abuse.
- Use AdGuard Home’s access settings to allow only known clients (client IDs or IP ranges).
1. Install
The official script installs AdGuard Home as a systemd service in /opt/AdGuardHome:
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
(Review the script first if you prefer; a Docker image adguard/adguardhome is also available.)
2. Initial setup — through an SSH tunnel
The setup wizard runs on port 3000. Don’t open it publicly:
ssh -L 3000:127.0.0.1:3000 user@your-vps
Open http://localhost:3000:
- Admin web interface: listen on
127.0.0.1, port8080(you’ll reach it through a tunnel or reverse proxy). - DNS server: listen on all interfaces port
53for now — we’ll lock it down with the firewall. - Create the admin username and a strong password.
On Ubuntu, if port 53 is busy, disable systemd-resolved’s stub listener (DNSStubListener=no in /etc/systemd/resolved.conf, then restart it).
3. Firewall
sudo ufw allow 443/tcp # DoH (and HTTPS)
sudo ufw allow 853/tcp # DoT
sudo ufw allow 853/udp # DoQ (optional)
# Do NOT allow 53 to the world. If needed, only from your own IP:
sudo ufw allow from 198.51.100.25 to any port 53
4. Certificate for encrypted DNS
Point a hostname such as dns.example.com to the VPS, then get a certificate. If nothing else uses port 80:
sudo apt install certbot
sudo certbot certonly --standalone -d dns.example.com
In AdGuard Home: Settings → Encryption settings:
- Enable encryption, server name
dns.example.com. - HTTPS port
443, DNS-over-TLS port853, DNS-over-QUIC853. - Certificate path:
/etc/letsencrypt/live/dns.example.com/fullchain.pem - Private key path:
/etc/letsencrypt/live/dns.example.com/privkey.pem
Add a deploy hook to restart AdGuard Home after renewal:
echo -e '#!/bin/sh\nsystemctl restart AdGuardHome' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/adguard.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/adguard.sh
If Nginx already uses 443 for websites, either give AdGuard Home its own IP, use a different HTTPS port, or proxy /dns-query from Nginx to AdGuard Home’s HTTP listener.
5. Allow only your clients
Settings → DNS settings → Access settings: under Allowed clients, add ClientIDs (for example phone-alice, laptop-bob). With an allow list set, AdGuard Home refuses everyone else.
Each device then uses its ClientID in the address:
- DoT (Android “Private DNS”):
phone-alice.dns.example.com— ClientIDs go in the subdomain, so you need a wildcard DNS record*.dns.example.comand a wildcard certificate (how). - DoH (browsers, iOS profiles):
https://dns.example.com/dns-query/phone-alice.
6. Configure devices
- Android 9+: Settings → Network → Private DNS → hostname
phone-alice.dns.example.com. - iOS / macOS: install a DNS configuration profile (AdGuard Home’s setup guide page can generate one) using the DoH URL.
- Firefox / Chrome: Secure DNS settings → custom provider → your DoH URL.
- Windows 11: Network settings → DNS → enable DNS over HTTPS with the template URL.
7. Blocklists and rules
Filters → DNS blocklists: the AdGuard DNS filter is enabled by default; add others carefully to avoid false positives. Custom filtering rules let you block or allow specific domains (@@||example.com^ allows). The Query Log shows what was blocked and why.
Upstream DNS servers: use encrypted upstreams (e.g. https://dns.quad9.net/dns-query, tls://1.1.1.1) so queries stay encrypted beyond your VPS too.
8. Reverse proxy for the admin UI (optional)
Proxy 127.0.0.1:8080 through Nginx with HTTPS and an IP allow-list, or simply keep using an SSH tunnel.
Maintenance
- Updates: the web UI shows when a new version is available and can update itself; or rerun the install script with
-rto reinstall. - Back up
/opt/AdGuardHome/AdGuardHome.yamland thedata/directory. - Check the dashboard for unexpected clients — a sign your access control isn’t tight enough.
AdGuard Home vs Pi-hole
Both block well. AdGuard Home’s built-in encrypted DNS and per-client access control make it easier to run safely on a public VPS; Pi-hole is usually paired with a VPN — see Pi-hole on a VPS.
DNS is latency-sensitive: choose a location close to you — Hong Kong, Tokyo or one of our USA data centers.