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.
# UDP-Puffergrößen für quic-go (DNS-over-QUIC) optimieren
net.core.rmem_max = 7500000
net.core.wmem_max = 7500000
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:
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:
# 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:
# 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