AdGuard Home: Self-Hosted DNS Filtering and Ad Blocking - 夜莺博客

AdGuard Home: Self-Hosted DNS Filtering and Ad Blocking

AdGuard Home is a network-wide DNS filter: point your clients at it, load blocklists, and it drops or rewrites queries for trackers, ads and known malware domains. It is lighter than running Pi-hole plus dnsmasq plus a separate recursive resolver, and it ships with DoH/DoT upstream support, per-client rules and query logging out of the box. This guide covers a production-ish deployment on Linux with sensible defaults.

Installation Options

# single binary, recommended for a small VM
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh \
  | sh -s -- -v

# docker alternative
docker run -d --name adguardhome --restart unless-stopped \
  -v /opt/adguardhome/work:/opt/adguardhome/work \
  -v /opt/adguardhome/conf:/opt/adguardhome/conf \
  -p 53:53/tcp -p 53:53/udp -p 3000:3000/tcp \
  adguard/adguardhome

Free port 53 first - systemd-resolved and dnsmasq both like to hold it. On Ubuntu, disable the stub listener in /etc/systemd/resolved.conf (DNSStubListener=no) and restart resolved.

Core Configuration

The whole configuration lives in /opt/adguardhome/conf/AdGuardHome.yaml. The parts worth tuning:

dns:
  bind_hosts:
    - 0.0.0.0
  port: 53
  upstream_dns:
    - 10.0.0.10          # internal AD DNS, first for split horizon
    - tls://1.1.1.1      # encrypted public resolver as fallback
  bootstrap_dns:
    - 9.9.9.10
  fallback_dns:
    - tls://9.9.9.9
  upstream_mode: load_balance
  cache_size: 4194304
  ratelimit: 20
  edns_client_subnet:
    enabled: false
  filtering_enabled: true
  blocked_response_ttl: 10

Order matters: put your internal resolver first so split-horizon internal names keep working, then an encrypted public resolver for everything else.

Filters and Client Policies

filters:
  - enabled: true
    url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
    name: AdGuard DNS filter
  - enabled: true
    url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_9.txt
    name: Malicious URL blocklist
  - enabled: false
    url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt
    name: AdAway (aggressive - test before enabling)

clients:
  persistent:
    - name: lab-nas
      ids: ["10.0.0.50"]
      use_global_settings: false
      filtering_enabled: false   # exempt this client from filtering

Per-client exceptions save a lot of support tickets: label each client as you discover it, and give infrastructure devices (backup servers, monitoring, anything that resolves vendor domains) an unfiltered policy.

Verification and Troubleshooting

dig @127.0.0.1 doubleclick.net +short        # expect 0.0.0.0
adguardhome --check-config
journalctl -u AdGuardHome -n 50 --no-pager
curl -s http://127.0.0.1:3000/control/status | head
  • Everything resolves to 0.0.0.0 including legitimate sites: the blocklist is too aggressive - disable the third-party list and re-enable individually.
  • Internal names fail to resolve: the upstream order is wrong, or conditional forwarding to your AD DNS is missing.
  • Queries time out under load: raise the UDP buffer, or move the service to a host with more than one vCPU and check the rate limit value.
  • Logs grow without bound: set query log retention in the UI (Settings > General) rather than editing the YAML.

Do not put a single AdGuard instance in front of a site without a second resolver in the DHCP options; a DNS outage looks exactly like a total network outage to users. Pair it with DNSSEC validation on Unbound if you need validated answers downstream, keep a local authoritative source of truth as described in PowerDNS and dnsdist, and for PXE/imaging environments see dnsmasq PXE boot setup.

Sizing, HA and Upgrades

  • Sizing - a small VM (1-2 vCPU, 1-2 GB RAM) handles a few thousand clients comfortably; the memory matters more than CPU because of the query log and cache.
  • HA - run two instances and list both in DHCP. They do not sync automatically, so keep the same filter and upstream sets on both, and accept that query logs are per-instance.
  • Caching - raise the cache size before adding more upstreams; a large local cache removes most upstream traffic.
  • Upgrades - upgrade the second instance first, watch the dashboard for errors for a day, then upgrade the first. The single-binary installer keeps a backup of the previous version.
  • Backups - a copy of AdGuardHome.yaml plus the blocklist set is a complete restore; keep it in git with secrets stripped.

原文链接:https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration