Zum Inhalt

Verschlüsseltes Netzwerk-Filtering: AdGuard Home Go-Engine, Natives DoH/DoT/DoQ & Adblock-Syntax

Erstellt: 06.11.2026 Aktualisiert: 06.11.2026

Management Summary: Während traditionelle DNS-Sinkholes ausschließlich über unverschlüsseltes UDP/TCP Port 53 operieren, verlangen moderne Multi-VLAN- und mobile Setups eine native verschlüsselte DNS-Terminierung (DNS-over-HTTPS, DNS-over-TLS und DNS-over-QUIC) gepaart mit mächtigen Adblock-Regeln (||example.org^$important). Dieser Leitfaden beschreibt das Produktiv-Deployment von AdGuard Home, geschrieben in speichersicherem Go, inklusive nativer TLS/QUIC-Listener, optimistischem DNS-Caching, EDNS0-Client-Subnet-Weiterleitung (ECS) und deklarativer YAML-Konfiguration.

  • Nativer DoH-, DoT- & DoQ-Server


    Terminiert DNS-over-QUIC (quic://:853), DNS-over-TLS (tls://:853) und DNS-over-HTTPS (https://:443/dns-query) direkt im statischen Go-Binary.

  • Adblock-Syntax Rule-Engine


    Ermöglicht granulare Modifikatoren ($important, $dnstype=HTTPS, $client='192.168.30.0/24', $dnsrewrite) weit über statische /etc/hosts-Dateien hinaus.

  • Optimistischer Cache & Parallele Upstreams


    Liefert abgelaufene TTL-Einträge sofort aus und aktualisiert Upstream-Einträge parallel im Hintergrund für mediane Latenzen im Sub-Millisekundenbereich.

  • Client-Identität via ClientID


    Identifiziert mobile Endgeräte außerhalb des LANs über individuelle DoH/DoT-URLs (https://dns.example.com/dns-query/laptop-nejat).


1. Architektur: Single-Binary Go-Architektur & Verschlüsselte Transporte

AdGuard Home bündelt seinen DNS-Resolver (dnsproxy), die verschlüsselten Transport-Listener, einen DHCP-Server und das React-Webinterface in einem einzigen, abhängigkeitsfreien Go-Binary. Im Gegensatz zu Lösungen, die Nginx oder stunnel zur TLS-Terminierung vorschalten müssen, verwaltet AdGuard Home X.509-Zertifikate und QUIC-Streams (UDP/853) nativ.

%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
    subgraph Clients["Interne & Mobile Endgeräte"]
        LAN["LAN-Clients<br/>UDP/TCP :53"]
        Mobile["Roaming iOS / Android<br/>DoT/DoQ :853 & DoH :443"]
    end

    subgraph AGHCore["AdGuard Home (Go-Laufzeit)"]
        Listeners["Zentraler Listener-Pool<br/>53 / 853 (TLS+QUIC) / 443"]
        RuleEngine["Adblock-Regel-Engine<br/>$dnstype / $client / $rewrite"]
        OptCache["Optimistischer LRU-Cache<br/>Asynchroner TTL-Refresh"]
    end

    subgraph Upstreams["Upstream-Auflösungsebene"]
        Unbound["Lokaler Unbound<br/>127.0.0.1:5335"]
        Quad9DoQ["Verschlüsselter Upstream<br/>quic://dns.quad9.net:853"]
    end

    LAN -->|"Standard-DNS"| Listeners
    Mobile -->|"ClientID TLS/QUIC"| Listeners
    Listeners --> RuleEngine
    RuleEngine <-->|"Cache-Treffer (<1ms)"| OptCache
    OptCache -->|"Lokale Zonen"| Unbound
    OptCache -->|"Parallel / Load-Balanced"| Quad9DoQ

Architektonischer Vergleich: AdGuard Home vs. Pi-hole v6

Eigenschaft AdGuard Home Pi-hole v6 (pihole-FTL)
Kern-Laufzeit Speichersicheres statisches Go-Binary C (dnsmasq + Civetweb + SQLite3)
Inbound DoH / DoT / DoQ Nativ integriert (inkl. ClientID-Routing) Erfordert externen Reverse-Proxy für DoH/DoT; kein DoQ
Outbound Verschlüsseltes DNS Integriertes DoH, DoT, DoQ und DNSCrypt Erfordert unbound oder cloudflared-Helfer
Filter-Syntax Vollständige Adblock-Syntax (||domain^$dnstype=AAAA,client=...) Hosts-Format + Domainlisten + POSIX ERE Regex
Konfigurationsspeicher Zentrale deklarative Datei (AdGuardHome.yaml) Deklarative pihole.toml + gravity.db (SQLite)

2. Gehärtetes Systemd- / Container-Deployment

Bei der Bereitstellung von AdGuard Home unter Debian/Ubuntu benötigt das Binary CAP_NET_BIND_SERVICE, um privilegierte Ports (53, 443, 853) als unprivilegierter Benutzer zu binden. Für QUIC-Verbindungen sind zudem erweiterte UDP-Kernel-Puffer empfehlenswert.

/etc/sysctl.d/99-adguard-quic.conf
# UDP-Puffergrößen für quic-go (DNS-over-QUIC) optimieren
net.core.rmem_max = 7500000
net.core.wmem_max = 7500000
/opt/adguardhome/compose.yaml
services:
  adguardhome:
    image: adguard/adguardhome:latest
    container_name: adguardhome
    restart: unless-stopped
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "853:853/tcp"
      - "853:853/udp"
      - "127.0.0.1:3000:3000/tcp"
    volumes:
      - ./work:/opt/adguardhome/work:Z
      - ./conf:/opt/adguardhome/conf:Z
      - /etc/letsencrypt:/etc/letsencrypt:ro
    cap_add:
      - NET_BIND_SERVICE
      - NET_RAW

3. Deklarative Produktivkonfiguration (AdGuardHome.yaml)

Der folgende Auszug zeigt eine gehärtete AdGuardHome.yaml mit parallelen Upstreams, optimistischem Cache, Rate-Limiting gegen Amplification-Angriffe und nativer TLS/QUIC-Terminierung:

/opt/adguardhome/conf/AdGuardHome.yaml
http:
  address: 127.0.0.1:3000
  session_ttl: 720h

dns:
  bind_hosts:
    - 0.0.0.0
    - "::"
  port: 53
  anonymize_client_ip: false
  ratelimit: 300
  ratelimit_whitelist:
    - 192.168.10.0/24
  refuse_any: true

  # Upstream-DNS-Strategie: Lokaler Unbound + verschlüsselter Fallback DoQ
  upstream_dns:
    - 127.0.0.1:5335
    - "[/lan.nejat-hakan.de/]127.0.0.1:5335"
    - "[/10.168.192.in-addr.arpa/]127.0.0.1:5335"
  upstream_mode: load_balance
  fastest_timeout: 1s

  # Hochperformanter optimistischer LRU-Cache
  cache_size: 33554432
  cache_ttl_min: 300
  cache_ttl_max: 86400
  cache_optimistic: true

  enable_dnssec: true
  blocking_mode: null_ip
  blocked_response_ttl: 60

tls:
  enabled: true
  server_name: dns.nejat-hakan.de
  force_https: true
  port_https: 443
  port_dns_over_tls: 853
  port_dns_over_quic: 853
  certificate_path: /etc/letsencrypt/live/dns.nejat-hakan.de/fullchain.pem
  private_key_path: /etc/letsencrypt/live/dns.nejat-hakan.de/privkey.pem
  strict_sni_check: true

Öffentlich erreichbare DoT/DoQ-Server vor Open-Resolver-Missbrauch schützen

Wenn Port 853 (DoT/DoQ) oder 443 (/dns-query) auf einem öffentlichen VPS für mobile Clients freigegeben wird, darf Port 53 niemals auf 0.0.0.0/0 lauschen. Zudem sollte über allowed_clients in AdGuardHome.yaml sichergestellt werden, dass nur verifizierte ClientID-Kennungen (z. B. iphone-nejat) Abfragen auflösen dürfen.


4. AdGuard-Filtersyntax & Benutzerdefinierte Modifikatoren

Die Filter-Engine von AdGuard Home bietet mächtige Syntax-Operatoren:

Praxisnahe benutzerdefinierte Filterregeln in AdGuard Home
# 1. Domain und sämtliche Subdomains für alle Record-Typen sperren
||telemetry.microsoft.com^

# 2. Blocklisten übersteuern und kritische Domain zwingend erlauben ($important)
@@||login.microsoftonline.com^$important

# 3. Split-Horizon DNS-Rewrite: Lokale LAN-IP für interne Domains liefern
||vault.nejat-hakan.de^$dnsrewrite=NOERROR;A;192.168.10.25
||vault.nejat-hakan.de^$dnsrewrite=NOERROR;AAAA;fd88:cafe:10::25

# 4. HTTPS/SVCB-Records (Typ 65) blockieren, um ECH/DoH-Auto-Upgrades von Browsern im Gastnetz zu unterbinden
||*$dnstype=HTTPS,client=192.168.30.0/24

# 5. Social-Video-Plattformen gezielt nur für das Gast-VLAN sperren
||tiktok.com^$client='192.168.40.0/24'
||googlevideo.com^$client='192.168.40.0/24'

5. Verifikation & Transport-Tests

Mit kdig (aus dem Paket knot-dnsutils) oder doggo können Standard-DNS, DNS-over-TLS (DoT), DNS-over-HTTPS (DoH) und DNS-over-QUIC (DoQ) validiert werden:

DoT, DoH und Split-Horizon-Rewrites überprüfen
# 1. DNS-over-TLS (DoT) auf Port 853 mit kdig testen
kdig -d @dns.nejat-hakan.de +tls-ca +tls-host=dns.nejat-hakan.de nejat-hakan.de A

# 2. Split-Horizon $dnsrewrite-Regel prüfen
dig @127.0.0.1 vault.nejat-hakan.de A +short
# Erwartete Ausgabe: 192.168.10.25

# 3. AdGuard Home Syntax und Konfigurationszustand validieren
sudo AdGuardHome --check-config -c /opt/adguardhome/conf/AdGuardHome.yaml