AdGuard Home as a DNS Server
Why AdGuard Home for DNS?
If you need a self-hosted DNS server with built-in support for every encrypted DNS protocol — DNS-over-HTTPS, DNS-over-TLS, DNS-over-QUIC, and DNSCrypt — AdGuard Home is the most complete option. While Pi-hole requires external tools to handle encrypted DNS, AdGuard Home supports all four protocols natively. This guide covers those DNS features rather than ad blocking, which is covered in the AdGuard Home setup guide.
AdGuard Home’s DNS capabilities go well beyond forwarding. It supports DNS rewrites (custom local records), upstream routing rules (different resolvers for different domains), parallel upstream querying, and DNSSEC — all configurable through its web interface.
Prerequisites
- AdGuard Home deployed and running (AdGuard Home setup guide)
- Docker and Docker Compose installed (guide)
- A domain name with SSL certificates (for DoH/DoT server functionality)
- Understanding of DNS concepts (DNS Explained)
Docker Compose Configuration
For users who haven’t deployed AdGuard Home yet, here’s a DNS-focused configuration:
services:
adguard-home:
image: adguard/adguardhome:v0.107.55
container_name: adguard-home
ports:
- "53:53/tcp" # Plain DNS
- "53:53/udp" # Plain DNS
- "80:80/tcp" # Web UI (initial setup)
- "443:443/tcp" # DNS-over-HTTPS
- "443:443/udp" # DNS-over-QUIC (HTTP/3)
- "853:853/tcp" # DNS-over-TLS
- "3000:3000/tcp" # Web UI (setup wizard)
volumes:
- adguard-work:/opt/adguardhome/work
- adguard-conf:/opt/adguardhome/conf
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
volumes:
adguard-work:
adguard-conf:
Start the stack:
docker compose up -d
Access the setup wizard at http://your-server-ip:3000 on first run.
Configuring Upstream DNS
Via Web UI
Go to Settings > DNS settings > Upstream DNS servers.
Upstream Formats
AdGuard Home supports multiple upstream formats:
| Format | Example | Protocol |
|---|---|---|
| Plain | 1.1.1.1 | UDP/TCP (unencrypted) |
| DNS-over-TLS | tls://dns.quad9.net | TLS (encrypted) |
| DNS-over-HTTPS | https://dns.cloudflare.com/dns-query | HTTPS (encrypted) |
| DNS-over-QUIC | quic://dns.adguard-dns.com | QUIC (encrypted, low latency) |
| DNSCrypt | sdns://... | DNSCrypt (encrypted) |
Recommended Upstream Configurations
Maximum privacy (no third party):
# Local Unbound for recursive resolution
192.168.1.10:53
Encrypted upstream (Cloudflare DoH):
https://cloudflare-dns.com/dns-query
Encrypted upstream (Quad9 DoT with malware filtering):
tls://dns.quad9.net
Parallel upstream (fastest response wins):
https://cloudflare-dns.com/dns-query
tls://dns.quad9.net
https://dns.google/dns-query
AdGuard Home queries all listed upstreams in parallel and uses the fastest response by default.
Bootstrap DNS
When using hostname-based upstreams (like tls://dns.quad9.net), AdGuard Home needs a plain IP to resolve the upstream hostname itself. Configure bootstrap DNS under Settings > DNS settings > Bootstrap DNS servers:
1.1.1.1
9.9.9.9
DNS Rewrites (Local DNS)
AdGuard Home’s DNS rewrites replace the need for editing hosts files across your network.
Via Web UI
Go to Filters > DNS rewrites and add entries:
| Domain | Answer |
|---|---|
nas.home.lan | 192.168.1.100 |
proxmox.home.lan | 192.168.1.50 |
*.home.lan | 192.168.1.10 |
jellyfin.local | 192.168.1.10 |
Wildcard Rewrites
AdGuard Home supports wildcard DNS rewrites — a feature Pi-hole lacks without custom dnsmasq configs:
*.apps.home.lan → 192.168.1.10
Every subdomain of apps.home.lan resolves to your Docker host. Combined with a reverse proxy, this gives each service its own subdomain without individual DNS entries.
CNAME Rewrites
Point one domain to another:
| Domain | Answer |
|---|---|
cloud.yourdomain.com | docker.home.lan |
Upstream Routing (Split DNS)
Route different domains to different resolvers — essential for split DNS setups:
Via Configuration File
Edit AdGuardHome.yaml (in the conf volume):
dns:
upstream_dns:
- https://cloudflare-dns.com/dns-query
upstream_dns_file: ""
# Domain-specific upstreams
upstream_dns:
- "[/corp.example.com/]10.0.0.53"
- "[/home.lan/]192.168.1.1"
- https://cloudflare-dns.com/dns-query
Via Web UI
Under Upstream DNS servers, use the bracket syntax:
[/corp.example.com/]10.0.0.53
[/home.lan/]192.168.1.1
https://cloudflare-dns.com/dns-query
Queries for corp.example.com go to your corporate DNS. Queries for home.lan go to your router. Everything else goes to Cloudflare over HTTPS.
See Split DNS Setup for detailed patterns.
Serving Encrypted DNS
DNS-over-TLS (DoT)
Requires an SSL certificate. Mount your certificate into the container:
volumes:
- adguard-work:/opt/adguardhome/work
- adguard-conf:/opt/adguardhome/conf
- /etc/letsencrypt/live/dns.yourdomain.com:/certs:ro
Configure in Settings > Encryption settings:
- Enable encryption: Yes
- Server name:
dns.yourdomain.com - Certificate path:
/certs/fullchain.pem - Private key path:
/certs/privkey.pem
Clients connect to tls://dns.yourdomain.com on port 853.
DNS-over-HTTPS (DoH)
Same certificate setup. Clients use: https://dns.yourdomain.com/dns-query
DNS-over-QUIC (DoQ)
Same certificate setup. AdGuard Home serves DoQ on port 443/UDP. Clients that support DoQ (AdGuard apps, Firefox nightly) use: quic://dns.yourdomain.com
Supported Encrypted Protocol Comparison
| Protocol | Port | Transport | Latency | Browser Support |
|---|---|---|---|---|
| DNS-over-TLS (DoT) | 853/TCP | TLS | Low | Android native, iOS |
| DNS-over-HTTPS (DoH) | 443/TCP | HTTPS | Medium | All modern browsers |
| DNS-over-QUIC (DoQ) | 443/UDP | QUIC | Lowest | Limited (AdGuard, Firefox) |
| DNSCrypt | 5443/TCP+UDP | Custom | Low | Dedicated clients only |
DNSSEC
Enable under Settings > DNS settings > DNSSEC. When enabled, AdGuard Home validates DNSSEC signatures on upstream responses and returns SERVFAIL for records that fail validation.
Reverse Proxy
The web admin interface can be placed behind Nginx Proxy Manager or Caddy. The DNS ports (53, 853, 443 for DoH/DoQ) should NOT go through a reverse proxy — they need direct port exposure.
Backup
All configuration lives in two directories:
| Data | Volume | Contents |
|---|---|---|
| Configuration | adguard-conf | AdGuardHome.yaml, DNS rewrites, filter lists |
| Runtime data | adguard-work | Query logs, DHCP leases, statistics |
docker run --rm -v adguard-conf:/data -v $(pwd):/backup alpine \
tar czf /backup/adguard-conf-$(date +%F).tar.gz -C /data .
See Backup Strategy for comprehensive guidance.
Troubleshooting
DoH/DoT Not Working
Symptom: Encrypted DNS connections time out
Fix: Verify your SSL certificate is valid and the paths are correct in encryption settings. Test with:
# Test DoT
kdig @dns.yourdomain.com +tls-ca +tls-host=dns.yourdomain.com example.com
# Test DoH
curl -H "accept: application/dns-json" \
"https://dns.yourdomain.com/dns-query?name=example.com&type=A"
Upstream Routing Not Working
Symptom: Domain-specific upstreams are ignored
Fix: Ensure the bracket syntax is correct: [/domain.com/]upstream_ip. The domain must end with /] and the upstream must follow immediately after. Check AdGuardHome.yaml for syntax errors.
Slow DNS Resolution
Symptom: Queries take 500ms+ to resolve
Fix: If using parallel upstreams, one slow upstream shouldn’t matter (fastest wins). If all are slow, check your network. Try fastest_addr mode under DNS settings to cache and prefer the fastest IP for each domain.
Resource Requirements
| Resource | Value |
|---|---|
| RAM | ~80 MB idle, ~200 MB with query logging |
| CPU | Low — Go binary handles thousands of queries/second |
| Disk | ~100 MB container + logs grow based on query volume |
| Network | Minimal for DNS; certificate renewal needs HTTPS outbound |
Verdict
For a self-hosted DNS server with native encrypted DNS support, AdGuard Home is the most capable single-binary option. The web UI makes configuration accessible, DNS rewrites handle local DNS elegantly, and upstream routing enables split DNS without touching config files. Built-in DoH, DoT, DoQ, and DNSCrypt support means you can serve encrypted DNS to all your devices without additional software.
If you don’t need encrypted DNS serving and prefer a lighter tool, Blocky or Pi-hole with custom upstreams works fine. For pure recursive resolution without a web UI, Unbound is more focused. AdGuard Home is the DNS Swiss Army knife.
FAQ
How is this different from the AdGuard Home ad blocking guide?
The setup guide covers initial Docker deployment and ad blocking. This guide covers DNS server features — encrypted DNS protocols, upstream routing, DNS rewrites, and DNSSEC.
Can I use AdGuard Home with Unbound?
Yes — set Unbound as AdGuard Home’s upstream for recursive DNS resolution. AdGuard Home handles encrypted DNS serving and filtering; Unbound handles recursive resolution. Use Unbound’s IP (e.g., 192.168.1.10:5353) as the upstream in AdGuard Home.
Does AdGuard Home replace the need for a separate DNS server?
For most homelabs, yes. It handles forwarding, caching, local DNS records, split DNS, and encrypted DNS. You’d only need a separate server like CoreDNS or PowerDNS for authoritative zone hosting or advanced use cases.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments