31 KiB
Konfiguration
Die zentrale Konfigurationsdatei liegt nach der Installation hier:
/opt/adguard-shield/adguard-shield.conf
Die Datei ist eine einfache Shell-ähnliche Key-Value-Datei. Kommentare beginnen mit #. Werte können ohne Anführungszeichen, mit doppelten Anführungszeichen oder mit einfachen Anführungszeichen geschrieben werden.
Beispiel:
ADGUARD_URL="https://dns1.example.com"
RATE_LIMIT_MAX_REQUESTS=30
WHITELIST="127.0.0.1,::1,192.168.1.1"
Nach Änderungen muss der Service neu gestartet werden:
sudo systemctl restart adguard-shield
sudo adguard-shield status
systemctl reload wird nicht unterstützt: Ein SIGHUP beendet den Daemon nicht mehr, lädt die Konfiguration aber auch nicht neu, sondern schreibt nur einen Hinweis ins Log.
Prüfung beim Laden
Ungültige Werte führen nicht zum Abbruch, damit der Schutz weiterläuft. Stattdessen wird der Standardwert verwendet und eine Warnung ausgegeben (im Daemon-Log bzw. bei CLI-Befehlen als WARNUNG: auf stderr). Geprüft wird unter anderem:
| Prüfung | Beispiel |
|---|---|
| Unbekannte Schlüssel (Tippfehler) | CHEK_INTERVAL=5 |
| Nicht lesbare Zahlen oder Wahrheitswerte | RATE_LIMIT_WINDOW=abc, GEOIP_ENABLED=vielleicht |
Werte, die größer als 0 sein müssen |
CHECK_INTERVAL=0, RATE_LIMIT_WINDOW=0 |
| Werte, die nicht negativ sein dürfen | PROGRESSIVE_BAN_MAX_LEVEL=-1, BAN_HISTORY_RETENTION_DAYS=-5, BAN_DURATION=-1, GEOIP_CACHE_TTL=-1 |
| Ungültige Ports | BLOCKED_PORTS="53 abc 70000" (ungültige Einträge werden ignoriert; ist kein Port gültig, gilt 53 443 853) |
| Ungültige Auswahlwerte | GEOIP_MODE, FIREWALL_MODE, LOG_LEVEL, NOTIFY_TYPE, REPORT_FORMAT, REPORT_INTERVAL |
| Ungültiger Web-Port/-Pfad | WEB_PORT=70000, WEB_BASE_PATH="/../x" |
Listen-URLs ohne https:// |
EXTERNAL_BLOCKLIST_URLS="http://..." oder file://... (die Quelle wird nicht geladen, siehe Externe Listen: Transport und Größe) |
Veraltete Schlüssel wie BAN_HISTORY_FILE (Shell-Version) oder WEB_LISTEN, WEB_TLS_CERT und WEB_TLS_KEY (bis v1.2.0) werden ignoriert und mit einem eigenen Hinweis gemeldet.
Automatische Migration
Beim Installieren oder Aktualisieren wird eine vorhandene Konfiguration nicht überschrieben. Der Installer vergleicht vorhandene Schlüssel mit der aktuellen Standardkonfiguration.
Wenn neue Parameter fehlen:
- Die alte Datei wird als
adguard-shield.conf.oldgesichert. - Fehlende Schlüssel werden am Ende ergänzt.
- Vorhandene Werte bleiben erhalten.
- Dateirechte werden auf
0600gesetzt.
Das ist besonders wichtig beim Umstieg von der Shell-Version auf die Go-Version. Prüfe nach einem Update trotzdem die neu ergänzten Parameter.
Empfohlene Startprüfung
Nach dem Bearbeiten der Konfiguration:
# API-Verbindung testen
sudo adguard-shield test
# Dry-Run: zeigt, was gesperrt würde, ohne die Firewall zu verändern
sudo adguard-shield dry-run
AdGuard Home API
| Parameter | Standard | Beschreibung |
|---|---|---|
ADGUARD_URL |
https://dns1.domain.com |
URL der AdGuard-Home-Weboberfläche/API |
ADGUARD_USER |
admin |
Benutzername für die API-Authentifizierung |
ADGUARD_PASS |
changeme |
Passwort für die API-Authentifizierung |
ADGUARD_TLS_INSECURE |
false |
true = TLS-Zertifikat der AdGuard-Home-API nicht prüfen (nur selbstsigniert/intern) |
Beispiel: Lokale Instanz
ADGUARD_URL="http://127.0.0.1:3000"
ADGUARD_USER="admin"
ADGUARD_PASS="sehr-geheim"
Beispiel: Entfernte Instanz mit HTTPS
ADGUARD_URL="https://dns.example.com"
ADGUARD_USER="admin"
ADGUARD_PASS="geheim"
AdGuard Shield ruft intern diesen Endpunkt ab:
/control/querylog?limit=<API_QUERY_LIMIT>&response_status=all
Hinweis: Standardmäßig (ADGUARD_TLS_INSECURE=false) prüft AdGuard Shield das TLS-Zertifikat der AdGuard-Home-API. Nutzt AdGuard Home ein selbstsigniertes Zertifikat, schlägt die Verbindung fehl. Abhilfe: gültiges Zertifikat, die API lokal per http://127.0.0.1:<port> ansprechen oder ADGUARD_TLS_INSECURE=true setzen. Letzteres erlaubt Man-in-the-Middle-Angriffe auf die API-Verbindung (Zugangsdaten und Querylog) und sollte nur in vertrauenswürdigen Netzen genutzt werden. Benachrichtigungen prüfen Zertifikate standardmäßig; nur mit NOTIFY_TLS_INSECURE=true werden für das Benachrichtigungsziel auch selbstsignierte Zertifikate akzeptiert. AbuseIPDB, externe Listen und der MaxMind-Download prüfen Zertifikate immer. Externe Listen werden außerdem nur per https:// geladen (siehe Externe Listen: Transport und Größe).
Querylog und Polling
| Parameter | Standard | Beschreibung |
|---|---|---|
CHECK_INTERVAL |
10 |
Abstand zwischen Querylog-Abfragen in Sekunden |
API_QUERY_LIMIT |
500 |
Seitengröße der Querylog-Abfrage (max. 5000); ist eine Seite voll, werden ältere Seiten nachgeladen (max. 20 pro Poll) |
Empfehlungen
| Situation | Empfehlung |
|---|---|
| Normaler Betrieb | CHECK_INTERVAL=10 ist ein guter Standard |
| Hohes DNS-Aufkommen | API_QUERY_LIMIT auf 1000–2000 erhöhen |
API_QUERY_LIMIT zu niedrig |
Mehr API-Abfragen pro Poll; ab 20 vollen Seiten werden ältere Einträge nicht mehr ausgewertet (Warnung im Log) |
| Sehr kurze Intervalle | Erzeugen mehr API-Last auf AdGuard Home |
Rate-Limit
| Parameter | Standard | Beschreibung |
|---|---|---|
RATE_LIMIT_MAX_REQUESTS |
30 |
Maximale Anfragen pro Client und Domain im Zeitfenster |
RATE_LIMIT_WINDOW |
60 |
Zeitfenster in Sekunden |
Das bedeutet: Wenn ein Client dieselbe Domain mehr als 30-mal innerhalb von 60 Sekunden abfragt, wird er als auffällig erkannt und gesperrt.
Empfohlene Startwerte
| Umgebung | MAX_REQUESTS |
WINDOW |
Hinweis |
|---|---|---|---|
| Kleines Heimnetz | 30 |
60 |
Standardwerte |
| Viele Clients | 60–120 |
60 |
Höherer Grenzwert für mehr Grundlast |
| Aktive Resolver/Forwarder | nach Bedarf | 60 |
Zuerst Forwarder whitelisten |
Wichtig: Wenn ein Router, Reverse Proxy oder lokaler DNS-Forwarder stellvertretend für viele Clients fragt, sollte dieser Client in die Whitelist. Sonst sieht AdGuard Shield nur eine sehr aktive IP und sperrt den Forwarder statt der eigentlichen Verursacher.
Subdomain-Flood-Erkennung
| Parameter | Standard | Beschreibung |
|---|---|---|
SUBDOMAIN_FLOOD_ENABLED |
true |
Erkennung zufälliger Subdomains aktivieren |
SUBDOMAIN_FLOOD_MAX_UNIQUE |
50 |
Maximale eindeutige Subdomains pro Client und Basisdomain |
SUBDOMAIN_FLOOD_WINDOW |
60 |
Zeitfenster in Sekunden |
Diese Erkennung zielt auf Muster wie:
a1b2.example.com
f8x9.example.com
zz12.example.com
Dabei zählt AdGuard Shield nicht die Gesamtzahl der Anfragen, sondern die Anzahl unterschiedlicher Subdomains unter derselben Basisdomain. Direkte Anfragen an example.com selbst zählen nicht.
Hinweise
- Die Basisdomain wird über die Public Suffix List bestimmt. Multi-Part-TLDs wie
.co.ukwerden korrekt als Basisdomain erkannt. - Auch private Suffixe wie
github.ioodercloudfront.netgelten als Suffix:nutzer.github.ioundd111111abcdef8.cloudfront.netsind jeweils eigene Basisdomains. Viele verschiedene Hosts solcher Plattformen werden daher nicht als Subdomain-Flood aufgithub.iobzw.cloudfront.netgewertet. - CDNs und manche Apps nutzen legitim viele Subdomains. Betroffene Clients whitelisten oder Grenzwert erhöhen.
DNS-Flood-Watchlist
| Parameter | Standard | Beschreibung |
|---|---|---|
DNS_FLOOD_WATCHLIST_ENABLED |
false |
Watchlist aktivieren |
DNS_FLOOD_WATCHLIST |
leer | Kommagetrennte Domainliste |
Die Watchlist ist für Domains gedacht, bei denen eine Überschreitung sofort hart behandelt werden soll, ohne progressive Stufen.
Beispiel
DNS_FLOOD_WATCHLIST_ENABLED=true
DNS_FLOOD_WATCHLIST="microsoft.com,google.com,apple.com"
Matching-Logik
Wenn ein Client login.microsoft.com über das Rate-Limit bringt, wird sofort permanent gesperrt, weil login.microsoft.com zur Watchlist-Domain microsoft.com gehört. evil-microsoft.com würde dagegen nicht matchen.
Folgen eines Watchlist-Treffers
| Aspekt | Verhalten |
|---|---|
| Grund | dns-flood-watchlist |
| Sperrdauer | Permanent |
| Progressive Sperren | Werden übersprungen |
| AbuseIPDB | Wird gemeldet, falls aktiviert |
Sperrdauer und Firewall
| Parameter | Standard | Beschreibung |
|---|---|---|
BAN_DURATION |
3600 |
Basisdauer temporärer Monitor-Sperren in Sekunden (1 Stunde, 0 = Monitor-Sperren sind permanent) |
IPTABLES_CHAIN |
ADGUARD_SHIELD |
Name der eigenen Firewall-Chain |
BLOCKED_PORTS |
53 443 853 |
Ports oder Portbereiche (a:b), die für gesperrte Clients blockiert werden (Leerzeichen- oder Komma-getrennt) |
FIREWALL_BACKEND |
ipset |
Firewall-Backend (ipset + iptables) |
FIREWALL_MODE |
host |
Verkehrsweg der AdGuard-Home-Installation |
DRY_RUN |
false |
Konfigurationsweiter Testmodus ohne echte Sperren |
Blockierte Ports
| Port | Zweck |
|---|---|
53 |
Klassisches DNS über UDP/TCP |
443 |
DNS-over-HTTPS (DoH), sofern AdGuard Home darüber erreichbar ist |
853 |
DNS-over-TLS (DoT) und DNS-over-QUIC (DoQ) |
Firewall-Modi
| Modus | Einsatz | Parent-Chain |
|---|---|---|
host |
Klassische AdGuard-Home-Installation direkt auf dem Host | INPUT |
docker-host |
Docker mit network_mode: host (Alias von host) |
INPUT |
docker-bridge |
Docker mit veröffentlichten Ports, z.B. -p 53:53 |
DOCKER-USER |
hybrid |
Schützt Host-Ports und Docker-Forwarding gleichzeitig | INPUT + DOCKER-USER |
Details zu den Docker-Modi stehen in Docker-Installationen.
Whitelist
| Parameter | Standard | Beschreibung |
|---|---|---|
WHITELIST |
127.0.0.1,::1 |
IPs oder CIDR-Netze (z.B. 192.168.1.0/24), die nie gesperrt werden (kommagetrennt) |
Beispiel
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.10,fd00::1"
Empfohlene Whitelist-Einträge
| Typ | Beispiel | Grund |
|---|---|---|
| Localhost | 127.0.0.1, ::1 |
Lokale Anfragen |
| Router/Gateway | 192.168.1.1 |
Bündelt oft DNS für alle Clients |
| Admin-IPs | 192.168.1.10 |
Eigene Management-Geräte |
| Monitoring | Monitoring-IP | Regelmäßige DNS-Checks |
| Interne Resolver | Resolver-IP | Fragt stellvertretend für viele Clients |
| VPN-Endpunkte | VPN-IP | Bündeln DNS-Anfragen vieler Nutzer |
Wichtig: Die Whitelist wird vor jeder Sperre geprüft. Das gilt für automatische, manuelle, GeoIP- und externe Blocklist-Sperren.
Zu breite Netze werden aus Sicherheitsgründen ignoriert und beim Start mit einer Warnung im Log gemeldet: /0, IPv4-Netze kürzer als /8 und IPv6-Netze kürzer als /16 (z.B. 0.0.0.0/0 oder 10.0.0.0/7).
Progressive Sperren
| Parameter | Standard | Beschreibung |
|---|---|---|
PROGRESSIVE_BAN_ENABLED |
true |
Wiederholungstäter stufenweise länger sperren |
PROGRESSIVE_BAN_MULTIPLIER |
2 |
Multiplikator pro Stufe (2 = Verdopplung) |
PROGRESSIVE_BAN_MAX_LEVEL |
5 |
Ab dieser Stufe permanent sperren (0 = nie permanent durch Stufe) |
PROGRESSIVE_BAN_RESET_AFTER |
86400 |
Offense-Zähler nach so vielen Sekunden ohne neues Vergehen zurücksetzen |
Stufenverlauf mit Standardwerten
| Vergehen | Stufe | Berechnung | Sperrdauer |
|---|---|---|---|
| 1 | 1 | 3600 × 2⁰ | 1 Stunde |
| 2 | 2 | 3600 × 2¹ | 2 Stunden |
| 3 | 3 | 3600 × 2² | 4 Stunden |
| 4 | 4 | 3600 × 2³ | 8 Stunden |
| 5 | 5 | Max-Level erreicht | Permanent |
Progressive Sperren gelten für Monitor-Sperren wie rate-limit und subdomain-flood. Watchlist-Treffer sind sofort permanent. GeoIP und externe Blocklisten haben eigene Regeln.
Verwaltungsbefehle
sudo adguard-shield offense-status # Zähler anzeigen
sudo adguard-shield offense-cleanup # Abgelaufene entfernen
sudo adguard-shield reset-offenses # Alle zurücksetzen
sudo adguard-shield reset-offenses <IP> # Eine IP zurücksetzen
Logging
| Parameter | Standard | Beschreibung |
|---|---|---|
LOG_FILE |
/var/log/adguard-shield.log |
Datei für Daemon-Ereignisse |
LOG_LEVEL |
INFO |
Minimales Log-Level |
LOG_MAX_SIZE_MB |
50 |
Ab dieser Größe wird LOG_FILE nach LOG_FILE.1 rotiert (ein Backup); 0 = keine Rotation |
Verfügbare Log-Level
| Level | Beschreibung | Empfehlung |
|---|---|---|
DEBUG |
Detaillierte Informationen, z.B. einzelne API-Ergebnisse | Nur kurzzeitig für Fehlersuche |
INFO |
Normale Betriebsmeldungen (Start, Sperren, Freigaben) | Empfohlen für den produktiven Betrieb |
WARN |
Warnungen (API-Fehler, fehlende Dateien, Konfigurationsprobleme) | |
ERROR |
Fehler, die den Betrieb beeinträchtigen |
CLI-Befehle
sudo adguard-shield logs --level warn --limit 100
sudo adguard-shield logs-follow debug
sudo adguard-shield live
Hinweis: Query-Inhalte werden nicht dauerhaft ins Log geschrieben. Für Query-nahe Diagnose ist die Live-Ansicht gedacht.
State und Runtime
| Parameter | Standard | Beschreibung |
|---|---|---|
STATE_DIR |
/var/lib/adguard-shield |
Verzeichnis für SQLite-Datenbank und Caches |
PID_FILE |
/var/run/adguard-shield.pid |
PID-Datei für direkten Vordergrundlauf |
BAN_HISTORY_RETENTION_DAYS |
0 |
Einträge der Ban-History und AbuseIPDB-Meldungen älter als X Tage werden täglich gelöscht; 0 = unbegrenzt aufbewahren |
Abgelaufene GeoIP-Cache-Einträge (älter als GEOIP_CACHE_TTL) werden unabhängig davon täglich entfernt, sofern GEOIP_CACHE_TTL größer als 0 ist.
SQLite-Datei
${STATE_DIR}/adguard-shield.db
Weitere Dateien in STATE_DIR
| Datei/Verzeichnis | Inhalt |
|---|---|
adguard-shield.db |
Hauptdatenbank (Sperren, History, Offenses, Caches) |
adguard-shield.db-wal |
WAL-Datei (im laufenden Betrieb) |
adguard-shield.db-shm |
Shared-Memory-Datei (im laufenden Betrieb) |
external-blocklist/ |
Cache für heruntergeladene Blocklisten |
external-whitelist/ |
Cache für heruntergeladene Whitelists |
iptables-rules.v4 |
Gesicherte IPv4-Firewall-Regeln |
iptables-rules.v6 |
Gesicherte IPv6-Firewall-Regeln |
Benachrichtigungen
| Parameter | Standard | Beschreibung |
|---|---|---|
NOTIFY_ENABLED |
false |
Benachrichtigungen aktivieren |
NOTIFY_TYPE |
ntfy |
Benachrichtigungskanal |
NOTIFY_WEBHOOK_URL |
leer | Webhook-URL (nicht für ntfy) |
NOTIFY_TLS_INSECURE |
false |
TLS-Zertifikat des Benachrichtigungsziels nicht prüfen (nur für selbstsignierte/interne Server) |
NTFY_SERVER_URL |
https://ntfy.sh |
Ntfy-Server |
NTFY_TOPIC |
leer | Ntfy-Topic |
NTFY_TOKEN |
leer | Optionaler Ntfy-Access-Token |
NTFY_PRIORITY |
4 |
Ntfy-Priorität (1–5) |
Verfügbare Typen
| Typ | Beschreibung |
|---|---|
ntfy |
Ntfy Push-Benachrichtigungen (öffentlich oder selbst gehostet) |
discord |
Discord-Webhook |
slack |
Slack-Webhook |
gotify |
Gotify-Server |
generic |
Eigener Webhook-Endpunkt (JSON POST) |
Beispiel: Ntfy
NOTIFY_ENABLED=true
NOTIFY_TYPE="ntfy"
NTFY_SERVER_URL="https://ntfy.sh"
NTFY_TOPIC="mein-adguard-shield"
NTFY_PRIORITY="4"
Beispiel: Discord
NOTIFY_ENABLED=true
NOTIFY_TYPE="discord"
NOTIFY_WEBHOOK_URL="https://discord.com/api/webhooks/..."
Details zu allen Kanälen stehen in Benachrichtigungen.
E-Mail-Reports
| Parameter | Standard | Beschreibung |
|---|---|---|
REPORT_ENABLED |
false |
Report-Funktion logisch aktivieren |
REPORT_INTERVAL |
weekly |
Versandintervall |
REPORT_TIME |
08:00 |
Versandzeit im Format HH:MM |
REPORT_EMAIL_TO |
admin@example.com |
Empfängeradresse |
REPORT_EMAIL_FROM |
adguard-shield@example.com |
Absenderadresse |
REPORT_FORMAT |
html |
Report-Format |
REPORT_MAIL_CMD |
msmtp |
Mailprogramm für den Versand |
REPORT_BUSIEST_DAY_RANGE |
30 |
Zeitraum für "Aktivster Tag"; 0 nutzt den Berichtszeitraum |
Verfügbare Intervalle
| Intervall | Versand |
|---|---|
daily |
Täglich zur konfigurierten Uhrzeit |
weekly |
Montags zur konfigurierten Uhrzeit |
biweekly |
Montags in ungeraden ISO-Kalenderwochen |
monthly |
Am 1. des Monats |
Verfügbare Formate
| Format | Beschreibung |
|---|---|
html |
HTML-formatierte E-Mail (empfohlen für Standard-Mail-Clients) |
txt |
Reiner Text (robuster für einfache Mail-Setups) |
Beispiel
REPORT_ENABLED=true
REPORT_INTERVAL="weekly"
REPORT_TIME="08:00"
REPORT_EMAIL_TO="admin@example.com"
REPORT_EMAIL_FROM="adguard-shield@example.com"
REPORT_FORMAT="html"
REPORT_MAIL_CMD="msmtp"
Cron-Job installieren
sudo adguard-shield report-install
Details stehen in E-Mail Report.
Die Templates werden bei install/update nach /opt/adguard-shield/templates geschrieben. Eigene Templates können alternativ über ADGUARD_SHIELD_TEMPLATE_DIR bereitgestellt werden.
Externe Whitelist
| Parameter | Standard | Beschreibung |
|---|---|---|
EXTERNAL_WHITELIST_ENABLED |
false |
Externe Whitelist aktivieren |
EXTERNAL_WHITELIST_URLS |
leer | Kommagetrennte URLs zu den Whitelist-Dateien |
EXTERNAL_WHITELIST_INTERVAL |
300 |
Synchronisationsintervall in Sekunden |
EXTERNAL_WHITELIST_CACHE_DIR |
/var/lib/adguard-shield/external-whitelist |
Cache-Verzeichnis |
Beispiel
EXTERNAL_WHITELIST_ENABLED=true
EXTERNAL_WHITELIST_URLS="https://example.com/trusted.txt"
EXTERNAL_WHITELIST_INTERVAL=300
Listenformat
# Hostnamen werden regelmäßig per DNS aufgelöst
mein-router.dyndns.org
vpn.example.com
# IPs und Netze direkt
192.168.1.10
10.0.0.0/24
2001:db8::1
Mehrere Listen
EXTERNAL_WHITELIST_URLS="https://example.com/a.txt,https://example.net/b.txt"
Verhalten
- Hostnamen werden per DNS aufgelöst und als IPs in SQLite gespeichert.
- Aufgelöste IPs werden bei jedem Sync aktualisiert.
- Bereits aktive Sperren werden aufgehoben, wenn die IP in der Whitelist auftaucht.
- Ist eine Quelle nicht erreichbar, wird die zuletzt heruntergeladene Fassung aus dem Cache-Verzeichnis verwendet. Gibt es auch keinen Cache, wird der Sync abgebrochen und die bisherige Whitelist bleibt vollständig erhalten.
- Zu breite Netze (
/0, IPv4 kürzer als/8, IPv6 kürzer als/16, auch als IPv4-mapped IPv6 wie::ffff:0:0/96) werden mit Warnung ignoriert. - Sicherheitsbremse: Würde ein Sync mehr als 50 % der aktiven Sperren (und mehr als 100) aufheben, wird nur die Whitelist übernommen, die Freigabe aber mit einem ERROR-Logeintrag abgebrochen.
- Ist der Whitelist-Worker deaktiviert, lädt der Daemon die Whitelist alle 5 Minuten aus der Datenbank neu (z.B. nach
adguard-shield whitelist-syncüber die CLI). - Kommentare (
#) und Inline-Kommentare (#oder;) werden unterstützt.
Externe Blocklist
| Parameter | Standard | Beschreibung |
|---|---|---|
EXTERNAL_BLOCKLIST_ENABLED |
false |
Externe Blocklist aktivieren |
EXTERNAL_BLOCKLIST_URLS |
leer | Kommagetrennte URLs |
EXTERNAL_BLOCKLIST_INTERVAL |
300 |
Synchronisationsintervall in Sekunden |
EXTERNAL_BLOCKLIST_BAN_DURATION |
0 |
Sperrdauer in Sekunden (0 = permanent bis IP aus Liste entfernt) |
EXTERNAL_BLOCKLIST_AUTO_UNBAN |
true |
IPs freigeben, wenn sie nicht mehr in der Liste stehen |
EXTERNAL_BLOCKLIST_NOTIFY |
false |
Benachrichtigungen für Blocklist-Sperren senden |
EXTERNAL_BLOCKLIST_CACHE_DIR |
/var/lib/adguard-shield/external-blocklist |
Cache-Verzeichnis |
Beispiel
EXTERNAL_BLOCKLIST_ENABLED=true
EXTERNAL_BLOCKLIST_URLS="https://example.com/blocklist.txt"
EXTERNAL_BLOCKLIST_INTERVAL=300
EXTERNAL_BLOCKLIST_BAN_DURATION=0
EXTERNAL_BLOCKLIST_AUTO_UNBAN=true
EXTERNAL_BLOCKLIST_NOTIFY=false
Unterstützte Listenformate
| Format | Beispiel |
|---|---|
| IPv4 | 203.0.113.50 |
| IPv4-CIDR | 198.51.100.0/24 |
| IPv6 | 2001:db8::1 |
| IPv6-CIDR | 2001:db8::/32 |
| Hostname | bad.example.com |
| Hosts-Format | 0.0.0.0 bad.example.com |
| Kommentar | # Text |
| Inline-Kommentar | 203.0.113.50 # Grund |
Ignorierte Einträge
- URLs wie
https://... - IP:Port wie
203.0.113.50:8443 - Hostnamen ohne Punkt oder mit ungültigen Zeichen
- Nicht auflösbare Hostnamen
- Blocking-Antworten wie
0.0.0.0oder:: - Loopback-Adressen (
127.0.0.0/8,::1) und Netze mit/0(Warnung im Log)
Hinweise
- Große Listen können viele Sperren erzeugen.
EXTERNAL_BLOCKLIST_NOTIFY=falseist deshalb der sichere Standard. - Hostnamen mit mehreren IPs: Alle aufgelösten IPs werden verarbeitet.
- IPs aus der Whitelist werden nicht gesperrt. Netze, die sich mit einer gewhitelisteten IP oder einem gewhitelisteten Netz überschneiden, werden ebenfalls nicht gesperrt (Warnung im Log).
- Bei
EXTERNAL_BLOCKLIST_AUTO_UNBAN=truewerden entfernte Einträge automatisch wieder freigegeben. - Ist eine Quelle nicht erreichbar, wird ihr Cache verwendet. Gibt es keinen Cache, werden die übrigen Listen trotzdem verarbeitet, der Auto-Unban wird in diesem Lauf aber übersprungen. So werden bei einem Download-Fehler keine Sperren versehentlich aufgehoben.
Dateiformat-Empfehlungen
- UTF-8 ohne BOM
- Unix-Zeilenenden (
LF) - IP-Listen und Hostname-Listen möglichst getrennt pflegen
Externe Listen: Transport und Größe
Die externe Whitelist und die externe Blocklist fließen direkt in Firewall-Entscheidungen ein. Deshalb gelten für beide dieselben Regeln beim Download:
| Parameter | Standard | Beschreibung |
|---|---|---|
ALLOW_INSECURE_LIST_URLS |
false |
true = Listen auch unverschlüsselt per http:// laden (unsicher) |
- Erlaubt sind nur
https://-URLs mit Host.http://wird nur mitALLOW_INSECURE_LIST_URLS=trueakzeptiert, andere Schemata wiefile://oderftp://nie. - Eine abgelehnte URL meldet schon beim Start eine Konfigurationswarnung und bei jedem Sync eine Download-Warnung. Sie zählt als fehlgeschlagene Quelle: Die externe Whitelist bleibt dann unverändert, der Auto-Unban der Blocklist wird übersprungen. Ein vorhandener Cache dieser Quelle wird bewusst nicht genutzt, da er aus einem unverschlüsselten Download stammen kann.
- Mit
ALLOW_INSECURE_LIST_URLS=truewird für jedehttp://-Quelle beim Start und beim ersten Download eine Warnung geschrieben. - Weiterleitungen müssen dieselben Regeln erfüllen. Eine Weiterleitung von
https://aufhttp://wird ohneALLOW_INSECURE_LIST_URLS=trueabgelehnt; dann wird wie bei anderen Download-Fehlern der Cache der Quelle verwendet. - Eine Liste darf höchstens 50 MB groß sein. Größere Downloads werden verworfen statt abgeschnitten: Der Cache bleibt unverändert und wird verwendet (Warnung im Log); ohne Cache gilt die Quelle als fehlgeschlagen.
Hinweis für Updates: Bis v1.1.x wurden http://-Listen ohne Rückfrage geladen. Nach dem Update werden sie abgelehnt, im Log steht z.B. blocklist Download Warnung Quelle #1 (http://example.com): unverschlüsseltes http:// ist nicht erlaubt .... Abhilfe: die URL in EXTERNAL_WHITELIST_URLS bzw. EXTERNAL_BLOCKLIST_URLS auf https:// umstellen (die meisten Anbieter unterstützen das) und den Dienst neu starten. Nur wenn die Quelle kein HTTPS anbietet und das Netz vertrauenswürdig ist, bewusst ALLOW_INSECURE_LIST_URLS=true setzen. Ein Angreifer im Netzwerkpfad kann sonst beliebige IPs auf die Blocklist setzen oder die Whitelist verändern.
Web-Statusseite
Optionale, schreibgeschützte Statusseite mit Live-Ansicht. Der eingebaute Webserver spricht nur HTTP und lauscht auf allen Schnittstellen; HTTPS übernimmt ein Reverse-Proxy. Einrichtung, Absicherung und Reverse-Proxy-Beispiele: Web-Statusseite.
| Parameter | Standard | Beschreibung |
|---|---|---|
WEB_ENABLED |
false |
Schreibgeschützte Web-Statusseite aktivieren |
WEB_PORT |
8080 |
HTTP-Port der Statusseite (1–65535) |
WEB_BASE_PATH |
/ |
Basispfad, z. B. /adguard-shield/, wenn der Reverse-Proxy die Seite in einem Unterordner ausliefert |
WEB_USER |
admin |
Benutzername für HTTP Basic Auth |
WEB_PASSWORD |
(leer) | Passwort für HTTP Basic Auth; leer = Statusseite ohne Anmeldung |
Der Port ist auf allen Schnittstellen offen. Ohne
WEB_PASSWORDist die Seite ohne Anmeldung erreichbar, der Daemon warnt dann beim Start. Den Port per Firewall auf den Reverse-Proxy beschränken und von außen nur über HTTPS zugreifen, sonst läuft ein gesetztes Passwort im Klartext über das Netz.
AbuseIPDB
| Parameter | Standard | Beschreibung |
|---|---|---|
ABUSEIPDB_ENABLED |
false |
AbuseIPDB-Reporting aktivieren |
ABUSEIPDB_API_KEY |
leer | API-Key von abuseipdb.com |
ABUSEIPDB_CATEGORIES |
4 |
Kategorien, kommagetrennt (siehe abuseipdb.com/categories) |
Beispiel
ABUSEIPDB_ENABLED=true
ABUSEIPDB_API_KEY="dein-api-key"
ABUSEIPDB_CATEGORIES="4"
Was gemeldet wird
| Wird gemeldet | Wird nicht gemeldet |
|---|---|
| Watchlist-Treffer (permanent) | Temporäre Sperren |
| Progressive-Ban auf Maximalstufe (permanent) | GeoIP-Sperren |
| Externe Blocklist-Sperren | |
| Manuelle Sperren |
GeoIP-Länderfilter
| Parameter | Standard | Beschreibung |
|---|---|---|
GEOIP_ENABLED |
false |
GeoIP-Filter aktivieren |
GEOIP_MODE |
blocklist |
Filtermodus |
GEOIP_COUNTRIES |
leer | Ländercodes nach ISO 3166-1 Alpha-2 |
GEOIP_CHECK_INTERVAL |
0 |
Eigenes GeoIP-Prüfintervall in Sekunden; 0 nutzt CHECK_INTERVAL. |
GEOIP_NOTIFY |
true |
Benachrichtigungen bei GeoIP-Sperren senden |
GEOIP_SKIP_PRIVATE |
true |
Private/lokale IPs überspringen |
GEOIP_LICENSE_KEY |
leer | MaxMind-License-Key für automatischen Download |
GEOIP_MMDB_PATH |
leer | Manueller Pfad zur MaxMind-MMDB-Datei (hat Vorrang) |
GEOIP_CACHE_TTL |
86400 |
GeoIP-Cache-Dauer in Sekunden (Standard: 24 Stunden, 0 = Einträge laufen nicht ab) |
Modi
| Modus | Beschreibung |
|---|---|
blocklist |
Nur die genannten Länder werden gesperrt. Alle anderen sind erlaubt. |
allowlist |
Nur die genannten Länder sind erlaubt. Alle anderen öffentlichen IPs werden gesperrt. |
Ländercodes
Die Ländercodes folgen dem Standard ISO 3166-1 Alpha-2. Eine vollständige Liste aller Ländercodes findest du in der ISO-3166-1-Kodierliste auf Wikipedia.
Häufig verwendete Codes:
| Code | Land | Code | Land | |
|---|---|---|---|---|
DE |
Deutschland | CN |
China | |
AT |
Österreich | RU |
Russland | |
CH |
Schweiz | KP |
Nordkorea | |
US |
Vereinigte Staaten | IR |
Iran | |
GB |
Vereinigtes Königreich | BR |
Brasilien | |
FR |
Frankreich | IN |
Indien | |
NL |
Niederlande | VN |
Vietnam |
Beispiel: Blocklist-Modus
GEOIP_ENABLED=true
GEOIP_MODE="blocklist"
GEOIP_COUNTRIES="CN,RU,KP,IR"
Damit werden öffentliche DNS-Clients aus China, Russland, Nordkorea und dem Iran gesperrt.
Beispiel: Allowlist-Modus
GEOIP_ENABLED=true
GEOIP_MODE="allowlist"
GEOIP_COUNTRIES="DE,AT,CH"
Damit werden nur Clients aus Deutschland, Österreich und der Schweiz erlaubt. Alle anderen öffentlichen Länder werden gesperrt.
Private IPs
GEOIP_SKIP_PRIVATE=true
Damit werden folgende Adressbereiche übersprungen:
- Private Netze (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
- Loopback (127.0.0.0/8, ::1)
- Link-Local (169.254.0.0/16, fe80::/10)
- CGNAT (100.64.0.0/10)
GeoIP-Datenquellen
| Priorität | Quelle | Konfiguration |
|---|---|---|
| 1 | Manueller MMDB-Pfad | GEOIP_MMDB_PATH="/usr/share/GeoIP/GeoLite2-Country.mmdb" |
| 2 | Automatischer MaxMind-Download | GEOIP_LICENSE_KEY="dein_maxmind_license_key" |
| 3 | Legacy-Fallback | geoiplookup / geoiplookup6 Systembefehle |
Automatischer MaxMind-Download
GEOIP_LICENSE_KEY="dein_maxmind_license_key"
Die Datenbank wird unter /opt/adguard-shield/geoip/ gespeichert und nach 24 Stunden automatisch erneuert. Der Worker geoip-refresh prüft das täglich im laufenden Betrieb, lädt bei Bedarf eine neue Datenbank herunter und tauscht sie ohne Neustart aus. Schlägt der Download fehl, wird die vorhandene ältere Datenbank weiterverwendet und der Fehler geloggt; der License-Key erscheint dabei nicht im Log.
Mit GEOIP_MMDB_PATH wird nichts heruntergeladen. Wird die Datei dort extern aktualisiert (z.B. per geoipupdate), übernimmt der Daemon sie beim nächsten täglichen Refresh ebenfalls ohne Neustart.
GeoIP-Befehle
sudo adguard-shield geoip-status # Status anzeigen
sudo adguard-shield geoip-lookup 8.8.8.8 # IP nachschlagen
sudo adguard-shield geoip-sync # Clients prüfen
sudo adguard-shield geoip-flush-cache # Cache leeren
sudo adguard-shield geoip-flush # Alle GeoIP-Sperren aufheben
Protokollerkennung
AdGuard Shield liest das Feld client_proto aus der AdGuard-Home-API und zeigt das verwendete DNS-Protokoll an.
| API-Wert | Anzeige | Bedeutung |
|---|---|---|
leer oder dns |
DNS |
Klassisches DNS |
doh |
DoH |
DNS-over-HTTPS |
dot |
DoT |
DNS-over-TLS |
doq |
DoQ |
DNS-over-QUIC |
dnscrypt |
DNSCrypt |
DNSCrypt-Protokoll |
Die Sperre blockiert immer alle konfigurierten Ports, unabhängig davon, welches Protokoll den Verstoß ausgelöst hat.
Beispielkonfiguration: Heimnetz
ADGUARD_URL="http://127.0.0.1:3000"
ADGUARD_USER="admin"
ADGUARD_PASS="geheim"
RATE_LIMIT_MAX_REQUESTS=30
RATE_LIMIT_WINDOW=60
CHECK_INTERVAL=10
API_QUERY_LIMIT=500
SUBDOMAIN_FLOOD_ENABLED=true
SUBDOMAIN_FLOOD_MAX_UNIQUE=50
SUBDOMAIN_FLOOD_WINDOW=60
BAN_DURATION=3600
PROGRESSIVE_BAN_ENABLED=true
PROGRESSIVE_BAN_MAX_LEVEL=5
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.10"
NOTIFY_ENABLED=true
NOTIFY_TYPE="ntfy"
NTFY_TOPIC="adguard-shield-home"
REPORT_ENABLED=false
GEOIP_ENABLED=false
EXTERNAL_BLOCKLIST_ENABLED=false
EXTERNAL_WHITELIST_ENABLED=false
Beispielkonfiguration: Öffentlicher Resolver
ADGUARD_URL="https://dns.example.com"
ADGUARD_USER="admin"
ADGUARD_PASS="geheim"
RATE_LIMIT_MAX_REQUESTS=60
RATE_LIMIT_WINDOW=60
CHECK_INTERVAL=5
API_QUERY_LIMIT=2000
SUBDOMAIN_FLOOD_ENABLED=true
SUBDOMAIN_FLOOD_MAX_UNIQUE=75
SUBDOMAIN_FLOOD_WINDOW=60
DNS_FLOOD_WATCHLIST_ENABLED=true
DNS_FLOOD_WATCHLIST="microsoft.com,google.com,apple.com"
BAN_DURATION=3600
PROGRESSIVE_BAN_ENABLED=true
PROGRESSIVE_BAN_MULTIPLIER=2
PROGRESSIVE_BAN_MAX_LEVEL=5
GEOIP_ENABLED=true
GEOIP_MODE="blocklist"
GEOIP_COUNTRIES="CN,RU,KP,IR"
GEOIP_LICENSE_KEY="..."
ABUSEIPDB_ENABLED=true
ABUSEIPDB_API_KEY="..."
NOTIFY_ENABLED=true
NOTIFY_TYPE="ntfy"
NTFY_TOPIC="adguard-shield-prod"
Vor produktiver Aktivierung
sudo adguard-shield test
sudo adguard-shield dry-run