Self-host AdGuard Home on a VPS
Run AdGuard Home on a VPS as a private ad-blocking DNS server for your devices, over WireGuard, Tailscale or DNS-over-HTTPS, without an open resolver.
To self-host AdGuard Home on a VPS, install it with AdGuard's official script, finish its setup without exposing the wizard, and let only your own devices query it, over a VPN or DNS-over-HTTPS. On VPSNine the AdGuard Home one-click app does all of that and leaves you to choose how your devices connect.
The part that matters most is who may ask it questions. A DNS server that answers anyone on the internet is an open resolver, and open resolvers get abused for attacks. Ours answers only private, VPN and loopback addresses until you add yours.
What you need
- The Budget plan is plenty for a personal or family resolver. AdGuard publishes no minimum; blocklists and the query log are what use memory, so keep the log's retention modest on Budget. The plans page has the specs.
- A way for your devices to reach it: WireGuard, Tailscale, or a domain for DNS-over-HTTPS such as
dns.example.com.
A server across the internet adds a little delay to every lookup. That's fine for your phone and laptop wherever you are; for a whole home network, a small computer at home does the job better.
Install it with the one-click app
Order a server with the AdGuard Home app. It installs AdGuard Home with AdGuard's script to /opt/AdGuardHome as a systemd service, completes the first-run setup through its API while port 3000 is closed to the internet, and writes the admin password to a file only root can read. The web interface then listens on 127.0.0.1:3000, and DNS on port 53 resolves only for 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, Tailscale's address range, private IPv6 (unique local) addresses and loopback.
From your computer, open an SSH tunnel to the web interface:
ssh -L 3000:127.0.0.1:3000 root@203.0.113.10In that session, run
cat /root/adguard-admin.txtfor the password, then openhttp://localhost:3000and log in asadmin.Choose how your devices reach it:
- WireGuard: a server gets one app, so add WireGuard by hand with our WireGuard tutorial and set the clients' DNS to
10.9.0.1. The tunnel's addresses are already allowed. - Tailscale: install Tailscale on the server and join your tailnet (our Tailscale guide uses Tailscale's own install script), then point your tailnet's DNS at the server's Tailscale address. Tailscale's range is already allowed.
- Your home's IP address: add it in Settings, DNS settings, Access settings, under allowed clients.
- DNS-over-HTTPS from your own domain: see the next section.
- WireGuard: a server gets one app, so add WireGuard by hand with our WireGuard tutorial and set the clients' DNS to
To check it's running, systemctl status AdGuardHome on the server should show it active.
Put it on your domain with HTTPS
DNS-over-HTTPS works on phones and browsers anywhere, with no VPN. Point an A record for dns.example.com at the server, allow ports 80 and 443 in the panel firewall, then run:
vps9-https dns.example.comIt installs Caddy, which gets and renews the certificate and passes requests to AdGuard Home on 127.0.0.1:3000. Before that, its AdGuard step changes one setting in /opt/AdGuardHome/AdGuardHome.yaml so AdGuard Home accepts DNS-over-HTTPS over plain HTTP from Caddy on the same server, and restarts the service. The web interface is then also at https://dns.example.com, behind the admin password.
Next, in Settings, DNS settings, Access settings, add a ClientID for each device (a short name such as laptop) to the allowed clients. Each device then uses its own address:
https://dns.example.com/dns-query/laptopA device that leaves off the ClientID, or uses one you haven't allowed, gets no answers.
Doing it by hand on another server
The AdGuard Home README gives the automated install:
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -vIt installs AdGuard Home as a service with its setup wizard on port 3000. Keep 3000 closed to the internet and reach the wizard through an SSH tunnel, as above, because whoever finishes it sets the admin password. In the wizard, put the web interface on 127.0.0.1 and DNS on port 53.
On Ubuntu, systemd-resolved already holds port 53; the fix is in the troubleshooting below. Then, before anything else, restrict Access settings to your own clients so you're not running an open resolver, and close port 53 in your firewall to everyone you don't need.
Updates and backups
Update from the web interface when it offers a new version, or on the server:
/opt/AdGuardHome/AdGuardHome --updateThe one-click app turns on the operating system's automatic security updates. The whole configuration is /opt/AdGuardHome/AdGuardHome.yaml and the data folder next to it, so back up both and copy them off the server. Backups you should run shows how to schedule it.
The query log is on by default and stays on your server. Turn it off, or shorten how long it keeps entries, in Settings, General settings.
When it goes wrong
Your queries get no answer: your address isn't an allowed client. From home,
dig @203.0.113.10 example.comtimes out until you add your public IP in Access settings. If your home IP changes often, use WireGuard, Tailscale or DNS-over-HTTPS with a ClientID instead.bind: address already in useon port 53: systemd-resolved's stub listener holds it. The one-click app already applies AdGuard's fix; by hand, create/etc/systemd/resolved.conf.d/adguardhome.confwith the lines below, then runln -sf /run/systemd/resolve/resolv.conf /etc/resolv.confandsystemctl reload-or-restart systemd-resolved.[Resolve] DNS=127.0.0.1 DNSStubListener=noDNS-over-HTTPS fails on one device: the ClientID in its address isn't in the allowed list, or DNS for
dns.example.comdoesn't point at the server yet. Check withgetent hosts dns.example.comon the server and runvps9-https dns.example.comagain once it resolves.