Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bbdb104c4 | ||
| a7f7dbdb71 |
330
README.md
330
README.md
@@ -24,164 +24,310 @@
|
||||
|
||||
## ✨ Was ist AdGuard Shield?
|
||||
|
||||
AdGuard Shield überwacht das Query Log deiner AdGuard-Home-Instanz und erkennt Clients, die eine Domain oder viele zufällige Subdomains in kurzer Zeit übermäßig oft anfragen. Auffällige Clients werden über eine eigene `iptables`/`ip6tables`-Chain auf DNS-relevanten Ports blockiert.
|
||||
AdGuard Shield ist ein Go-basierter Sicherheitsdaemon, der das Query Log deiner AdGuard-Home-Instanz kontinuierlich überwacht. Er erkennt Clients, die eine Domain oder viele zufällige Subdomains in kurzer Zeit übermäßig oft anfragen, und sperrt sie automatisch über eine eigene `iptables`/`ip6tables`-Chain auf DNS-relevanten Ports.
|
||||
|
||||
Das schützt klassische DNS-Anfragen genauso wie DoH, DoT und DoQ, ohne deine bestehenden Firewall-Regeln unnötig anzufassen.
|
||||
Das Projekt schützt klassische DNS-Anfragen genauso wie DNS-over-HTTPS (DoH), DNS-over-TLS (DoT), DNS-over-QUIC (DoQ) und DNSCrypt, ohne deine bestehenden Firewall-Regeln anzufassen. AdGuard Shield arbeitet nicht direkt am Netzwerkverkehr, sondern wertet das Querylog von AdGuard Home über dessen API aus. Dadurch werden auch verschlüsselte DNS-Protokolle zuverlässig erfasst, solange sie in AdGuard Home sichtbar sind.
|
||||
|
||||
Das gesamte Projekt ist als einzelnes, statisch kompiliertes Go-Binary realisiert, das gleichzeitig als Daemon, CLI-Werkzeug, Installer und Report-Generator fungiert. Es ersetzt die frühere Shell-basierte Implementierung mit mehreren Skripten, Cron-Jobs und einem separaten Watchdog.
|
||||
|
||||
## 🚀 Highlights
|
||||
|
||||
- Automatische Sperren bei Rate-Limit-Verstößen
|
||||
- Erkennung von Random-Subdomain-Floods, z.B. `abc123.example.com`
|
||||
- DNS-Flood-Watchlist: sofortiger permanenter Ban + AbuseIPDB-Meldung für definierte Domains
|
||||
- Progressive Sperren für Wiederholungstäter, ähnlich wie bei fail2ban
|
||||
- Unterstützung für DNS, DoH, DoT, DoQ und DNSCrypt
|
||||
- IPv4 und IPv6
|
||||
- Go-Daemon mit einem zentralen Querylog-Poller statt mehrerer Shell-Worker
|
||||
- Eigene Firewall-Chain mit `ipset`-Sets für schnelle Sperren bei vielen IPs
|
||||
- Firewall-Modi für klassische Installation, Docker Host Network und Docker mit veröffentlichten Ports
|
||||
- Externe Blocklisten und dynamische externe Whitelists
|
||||
- GeoIP-Länderfilter mit Blocklist- oder Allowlist-Modus
|
||||
- AbuseIPDB-Reporting für permanent gesperrte IPs
|
||||
- Benachrichtigungen über Ntfy, Discord, Slack, Gotify oder Generic Webhook
|
||||
- E-Mail-Reports als HTML oder Text direkt aus dem Go-Binary
|
||||
- systemd-Service mit Restart-Policy, ohne Shell-Worker
|
||||
| Bereich | Funktionen |
|
||||
|---|---|
|
||||
| **Erkennung** | Rate-Limit-Überwachung pro Client und Domain, Random-Subdomain-Flood-Erkennung (z.B. `abc123.example.com`), DNS-Flood-Watchlist für sofortigen Permanent-Ban |
|
||||
| **Sperren** | Progressive Sperren für Wiederholungstäter (fail2ban-ähnlich), temporäre und permanente Sperren, automatische Freigabe abgelaufener Sperren |
|
||||
| **Protokolle** | DNS, DoH, DoT, DoQ und DNSCrypt, IPv4 und IPv6 |
|
||||
| **Firewall** | Eigene Chain mit `ipset`-Sets für performante Sperren, Firewall-Modi für Host, Docker Host Network, Docker Bridge und Hybrid |
|
||||
| **Listen** | Externe Blocklisten und dynamische externe Whitelists mit automatischer DNS-Auflösung |
|
||||
| **GeoIP** | Länderbasierte Filterung mit Blocklist- oder Allowlist-Modus über MaxMind GeoLite2 |
|
||||
| **Meldungen** | AbuseIPDB-Reporting für permanent gesperrte IPs |
|
||||
| **Benachrichtigungen** | Ntfy, Discord, Slack, Gotify oder Generic Webhook |
|
||||
| **Reports** | E-Mail-Reports als HTML oder Text mit konfigurierbarem Versandintervall |
|
||||
| **Betrieb** | systemd-Service mit Restart-Policy, Terminal-Live-Ansicht, Dry-Run-Modus, SQLite-State |
|
||||
|
||||
## ✅ Voraussetzungen
|
||||
|
||||
- Linux-Server mit AdGuard Home
|
||||
- Root-Zugriff per `sudo`
|
||||
- Erreichbare AdGuard Home Web-API, standardmäßig `http://127.0.0.1:3000`
|
||||
- `iptables`, `ip6tables`, `ipset` und `systemd`
|
||||
| Komponente | Beschreibung |
|
||||
|---|---|
|
||||
| **Betriebssystem** | Linux-Server (Debian, Ubuntu oder kompatible Distribution) |
|
||||
| **AdGuard Home** | Laufende Instanz mit erreichbarer Web-API (Standard: `http://127.0.0.1:3000`) |
|
||||
| **Root-Zugriff** | Erforderlich für Firewall-Steuerung und Service-Management |
|
||||
| **Systempakete** | `iptables`, `ip6tables`, `ipset` und `systemd` |
|
||||
| **Optional** | `msmtp` für E-Mail-Reports, MaxMind-Account für GeoIP-Daten |
|
||||
|
||||
Die benötigten Pakete werden vom Go-Installer auf Ubuntu/Debian automatisch installiert.
|
||||
Die benötigten Pakete werden vom Installer auf Ubuntu/Debian automatisch installiert, sofern `apt-get` verfügbar ist.
|
||||
|
||||
Wichtig: Go wird auf dem Server nicht benötigt, wenn du ein fertiges Linux-Binary installierst. Zum Erzeugen dieses Binarys brauchst du Go aber auf dem Rechner, auf dem du baust, oder alternativ Docker/CI/Release-Artefakte.
|
||||
> **Hinweis:** Go wird auf dem Server nicht benötigt, wenn du ein fertiges Linux-Binary verwendest. Zum Erzeugen des Binarys brauchst du Go auf dem Build-Rechner oder alternativ Docker/CI/Release-Artefakte.
|
||||
|
||||
## ⚡ Schnellstart
|
||||
|
||||
```bash
|
||||
git clone https://git.techniverse.net/scriptos/adguard-shield.git /tmp/adguard-shield
|
||||
cd /tmp/adguard-shield
|
||||
### Variante A: Fertiges Release-Binary
|
||||
|
||||
# Variante A: fertiges Release-Binary laden
|
||||
```bash
|
||||
# Release-Archiv herunterladen und entpacken
|
||||
curl -fL -o adguard-shield-linux-amd64.tar.gz \
|
||||
https://git.techniverse.net/scriptos/adguard-shield/releases/download/v1.0.0/adguard-shield-linux-amd64.tar.gz
|
||||
tar -xzf adguard-shield-linux-amd64.tar.gz
|
||||
chmod +x ./adguard-shield
|
||||
```
|
||||
|
||||
# Variante B: Linux-Binary lokal bauen, wenn Go installiert ist
|
||||
### Variante B: Lokal mit Go bauen
|
||||
|
||||
```bash
|
||||
git clone https://git.techniverse.net/scriptos/adguard-shield.git
|
||||
cd adguard-shield
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o adguard-shield ./cmd/adguard-shieldd
|
||||
```
|
||||
|
||||
# Variante C: ohne lokale Go-Installation per Docker bauen
|
||||
### Variante C: Ohne lokales Go per Docker bauen
|
||||
|
||||
```bash
|
||||
git clone https://git.techniverse.net/scriptos/adguard-shield.git
|
||||
cd adguard-shield
|
||||
docker run --rm -v "$PWD":/src -w /src -e GOOS=linux -e GOARCH=amd64 -e CGO_ENABLED=0 golang:1.22 \
|
||||
go build -o adguard-shield ./cmd/adguard-shieldd
|
||||
```
|
||||
|
||||
# Fertiges Binary auf dem Server installieren
|
||||
chmod +x ./adguard-shield
|
||||
### Installation und erster Start
|
||||
|
||||
```bash
|
||||
# Binary auf dem Server installieren
|
||||
sudo ./adguard-shield install
|
||||
# Der Installer fragt am Ende, ob AdGuard Shield direkt gestartet werden soll.
|
||||
|
||||
# Bestehende Shell-Installation?
|
||||
# Der Go-Installer bricht ab und meldet die gefundenen Script-Artefakte.
|
||||
# Die alte Version zuerst deinstallieren und die adguard-shield.conf behalten.
|
||||
# Konfiguration anpassen (mindestens API-Zugangsdaten und Whitelist)
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
|
||||
# Vor dem produktiven Start testen: loggt nur, sperrt nichts
|
||||
# API-Verbindung testen
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
|
||||
# Dry-Run: loggt Erkennungen, sperrt aber nicht
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
|
||||
# Service starten, falls du die Nachfrage verneint hast, und prüfen
|
||||
# Service starten und prüfen
|
||||
sudo systemctl start adguard-shield
|
||||
sudo systemctl status adguard-shield
|
||||
```
|
||||
|
||||
> Beim Installieren wird der systemd-Service für den Autostart registriert und am Ende nach dem direkten Start gefragt. Die Go-Version nutzt `Restart=on-failure`; einen separaten Watchdog-Timer wie in der alten Shell-Version gibt es nicht mehr.
|
||||
|
||||
> **Bestehende Shell-Installation?** Der Go-Installer bricht ab und meldet die gefundenen Script-Artefakte. Die alte Version muss zuerst deinstalliert werden (Konfiguration behalten). Details unter [docs/update.md](docs/update.md).
|
||||
|
||||
[](https://asciinema.techniverse.net/a/77)
|
||||
|
||||
## 🔧 Wichtigste Befehle
|
||||
## 🔧 Befehlsübersicht
|
||||
|
||||
AdGuard Shield wird über ein einzelnes Binary bedient. Die Grundform lautet:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield <befehl>
|
||||
```
|
||||
|
||||
### Installation & Updates
|
||||
|
||||
```bash
|
||||
sudo ./adguard-shield install # Go-Binary installieren
|
||||
sudo ./adguard-shield update # Binary, Service und Config-Migration aktualisieren
|
||||
sudo ./adguard-shield install-status # Installationsstatus prüfen
|
||||
sudo /opt/adguard-shield/adguard-shield uninstall --keep-config
|
||||
```
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `install` | Binary, Konfiguration und systemd-Service installieren |
|
||||
| `install --skip-deps` | Installation ohne automatische Paketprüfung |
|
||||
| `install --no-enable` | Installation ohne systemd-Autostart |
|
||||
| `install --config-source <pfad>` | Bestehende Konfiguration als Vorlage übernehmen |
|
||||
| `update` | Binary, Service und Konfiguration aktualisieren |
|
||||
| `install-status` | Installationsstatus anzeigen (Binary, Service, Version) |
|
||||
| `uninstall` | Vollständige Deinstallation |
|
||||
| `uninstall --keep-config` | Deinstallation mit Erhalt der Konfiguration |
|
||||
|
||||
### Betrieb & Diagnose
|
||||
### Daemon & Service
|
||||
|
||||
```bash
|
||||
sudo systemctl status adguard-shield
|
||||
sudo systemctl restart adguard-shield
|
||||
sudo journalctl -u adguard-shield -f
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `run` / `start` | Daemon im Vordergrund starten |
|
||||
| `dry-run` | Daemon starten, der nur loggt aber nicht sperrt |
|
||||
| `stop` | Laufenden Daemon über PID-Datei stoppen |
|
||||
| `test` | API-Verbindung zu AdGuard Home testen |
|
||||
| `version` | Installierte Version anzeigen |
|
||||
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield live
|
||||
sudo /opt/adguard-shield/adguard-shield history
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
sudo /opt/adguard-shield/adguard-shield unban 192.0.2.10
|
||||
sudo /opt/adguard-shield/adguard-shield flush
|
||||
```
|
||||
### Status & Monitoring
|
||||
|
||||
`live` zeigt eine Terminal-Ansicht mit aktuellen Queries, Top-Client/Domain-Zählungen, Subdomain-Flood-Kandidaten, aktiven Sperren und Systemereignissen. Query-Inhalte werden dabei nicht dauerhaft ins Systemlog geschrieben; `logs` und `logs-follow` sind für Daemon-, Worker- und Fehlerereignisse gedacht.
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `status` | Aktive Sperren und Konfigurationsübersicht anzeigen |
|
||||
| `live` / `watch` | Terminal-Live-Ansicht mit Queries, Top-Clients, Sperren und Logs |
|
||||
| `live --interval 2` | Live-Ansicht mit benutzerdefiniertem Aktualisierungsintervall |
|
||||
| `live --top 20` | Live-Ansicht mit mehr Top-Einträgen |
|
||||
| `live --recent 25` | Mehr letzte Queries und Logs anzeigen |
|
||||
| `live --logs debug` | DEBUG-Logs in der Live-Ansicht einblenden |
|
||||
| `live --logs off` | Log-Bereich in der Live-Ansicht ausblenden |
|
||||
| `live --once` | Einmaligen Snapshot ausgeben |
|
||||
| `history [N]` | Ban-History anzeigen (Standard: 50 Einträge) |
|
||||
| `logs` | Daemon-Logeinträge anzeigen |
|
||||
| `logs --level warn --limit 100` | Gefilterte Logs anzeigen |
|
||||
| `logs-follow` | Logs in Echtzeit verfolgen |
|
||||
|
||||
### Optionale Module
|
||||
### Sperren & Freigaben
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-status
|
||||
sudo /opt/adguard-shield/adguard-shield whitelist-status
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-status
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `ban <IP>` | IP-Adresse manuell permanent sperren |
|
||||
| `unban <IP>` | Sperre für eine IP-Adresse aufheben |
|
||||
| `flush` | Alle aktiven Sperren aufheben |
|
||||
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate html /tmp/adguard-shield-report.html
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
```
|
||||
### Progressive Sperren (Offense-Tracking)
|
||||
|
||||
Die vollständige Befehlsreferenz steht in [docs/befehle.md](docs/befehle.md).
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `offense-status` | Offense-Zähler und Statistik anzeigen |
|
||||
| `offense-cleanup` | Abgelaufene Offense-Zähler entfernen |
|
||||
| `reset-offenses` | Alle Offense-Zähler zurücksetzen |
|
||||
| `reset-offenses <IP>` | Offense-Zähler für eine bestimmte IP zurücksetzen |
|
||||
|
||||
### Firewall
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `firewall-create` | Firewall-Chain und ipsets anlegen |
|
||||
| `firewall-status` | Aktuelle Firewall-Regeln und ipsets anzeigen |
|
||||
| `firewall-flush` | ipsets leeren (Sperren entfernen, Struktur bleibt) |
|
||||
| `firewall-remove` | Chain, Regeln und ipsets vollständig entfernen |
|
||||
| `firewall-save` | Aktuelle iptables-Regeln in Datei sichern |
|
||||
| `firewall-restore` | Gesicherte Regeln wiederherstellen |
|
||||
|
||||
### GeoIP
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `geoip-status` | GeoIP-Konfiguration und Status anzeigen |
|
||||
| `geoip-lookup <IP>` | Land einer IP-Adresse nachschlagen |
|
||||
| `geoip-sync` | Aktuelle Querylog-Clients einmalig gegen GeoIP prüfen |
|
||||
| `geoip-flush` | Alle GeoIP-Sperren aufheben |
|
||||
| `geoip-flush-cache` | GeoIP-Cache leeren |
|
||||
|
||||
### Externe Listen
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `blocklist-status` | Status der externen Blocklist anzeigen |
|
||||
| `blocklist-sync` | Externe Blocklist sofort synchronisieren |
|
||||
| `blocklist-flush` | Alle Sperren aus externer Blocklist aufheben |
|
||||
| `whitelist-status` | Status der externen Whitelist anzeigen |
|
||||
| `whitelist-sync` | Externe Whitelist sofort synchronisieren |
|
||||
| `whitelist-flush` | Aufgelöste externe Whitelist-Einträge entfernen |
|
||||
|
||||
### E-Mail-Reports
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `report-status` | Report-Konfiguration und Cron-Status anzeigen |
|
||||
| `report-generate html <datei>` | HTML-Report in Datei schreiben |
|
||||
| `report-generate txt` | Text-Report auf stdout ausgeben |
|
||||
| `report-test` | Testmail senden |
|
||||
| `report-send` | Aktuellen Report erzeugen und per E-Mail versenden |
|
||||
| `report-install` | Cron-Job für automatischen Versand installieren |
|
||||
| `report-remove` | Cron-Job entfernen |
|
||||
|
||||
Die vollständige Befehlsreferenz mit Beispielen und typischen Betriebsabläufen steht in [docs/befehle.md](docs/befehle.md).
|
||||
|
||||
## ⚙️ Konfiguration
|
||||
|
||||
Die zentrale Konfiguration liegt nach der Installation hier:
|
||||
Die zentrale Konfigurationsdatei liegt nach der Installation hier:
|
||||
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield.conf
|
||||
```
|
||||
|
||||
Wichtige Startpunkte:
|
||||
Die Datei verwendet ein einfaches Shell-ähnliches Key-Value-Format. Nach Änderungen muss der Service neu gestartet werden:
|
||||
|
||||
- `ADGUARD_URL`, `ADGUARD_USER`, `ADGUARD_PASS` für die AdGuard-Home-API
|
||||
- `RATE_LIMIT_MAX_REQUESTS`, `RATE_LIMIT_WINDOW` und `CHECK_INTERVAL` für die Erkennung
|
||||
- `BAN_DURATION` und `PROGRESSIVE_BAN_*` für temporäre und progressive Sperren
|
||||
- `FIREWALL_MODE` für klassische Installationen, Docker Host Network oder Docker Bridge
|
||||
- `WHITELIST` für vertrauenswürdige Clients wie Router, Management-IPs oder lokale Resolver
|
||||
- `DNS_FLOOD_WATCHLIST_*` für sofortigen Permanent-Ban bei bekannten Flood-Domains
|
||||
- `NOTIFY_*`, `REPORT_*`, `GEOIP_*`, `EXTERNAL_BLOCKLIST_*` und `EXTERNAL_WHITELIST_*` für optionale Funktionen
|
||||
```bash
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
### Wichtigste Parameter
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `ADGUARD_URL` | `https://dns1.domain.com` | URL der AdGuard-Home-API |
|
||||
| `ADGUARD_USER` | `admin` | API-Benutzername |
|
||||
| `ADGUARD_PASS` | `changeme` | API-Passwort |
|
||||
| `RATE_LIMIT_MAX_REQUESTS` | `30` | Maximale Anfragen pro Client/Domain im Zeitfenster |
|
||||
| `RATE_LIMIT_WINDOW` | `60` | Zeitfenster in Sekunden |
|
||||
| `CHECK_INTERVAL` | `10` | Abstand zwischen Querylog-Abfragen in Sekunden |
|
||||
| `BAN_DURATION` | `3600` | Basis-Sperrdauer in Sekunden (1 Stunde) |
|
||||
| `FIREWALL_MODE` | `host` | `host`, `docker-host`, `docker-bridge` oder `hybrid` |
|
||||
| `WHITELIST` | `127.0.0.1,::1` | IPs, die nie gesperrt werden (kommagetrennt) |
|
||||
| `DRY_RUN` | `false` | Testmodus: nur loggen, nicht sperren |
|
||||
|
||||
### Optionale Module
|
||||
|
||||
| Modul | Aktivierung | Beschreibung |
|
||||
|---|---|---|
|
||||
| Subdomain-Flood | `SUBDOMAIN_FLOOD_ENABLED=true` | Erkennung von Random-Subdomain-Angriffen |
|
||||
| DNS-Flood-Watchlist | `DNS_FLOOD_WATCHLIST_ENABLED=true` | Sofortiger Permanent-Ban für definierte Domains |
|
||||
| Progressive Sperren | `PROGRESSIVE_BAN_ENABLED=true` | Stufenweise längere Sperren für Wiederholungstäter |
|
||||
| GeoIP-Länderfilter | `GEOIP_ENABLED=true` | Ländersperre per MaxMind-Datenbank |
|
||||
| Externe Blocklist | `EXTERNAL_BLOCKLIST_ENABLED=true` | IP-Sperren aus externen Listen |
|
||||
| Externe Whitelist | `EXTERNAL_WHITELIST_ENABLED=true` | Dynamische Whitelist mit DNS-Auflösung |
|
||||
| Benachrichtigungen | `NOTIFY_ENABLED=true` | Push-Benachrichtigungen bei Sperrereignissen |
|
||||
| E-Mail-Reports | `REPORT_ENABLED=true` | Periodische Statistik-Reports per E-Mail |
|
||||
| AbuseIPDB | `ABUSEIPDB_ENABLED=true` | Automatische Meldung permanenter Sperren |
|
||||
|
||||
Bei Updates migriert der Installer die bestehende Konfiguration automatisch: vorhandene Werte bleiben erhalten, neue Parameter werden ergänzt und die alte Datei wird als `adguard-shield.conf.old` gesichert.
|
||||
|
||||
Mehr Details findest du in [docs/konfiguration.md](docs/konfiguration.md).
|
||||
Die vollständige Parameterbeschreibung mit Beispielkonfigurationen findest du in [docs/konfiguration.md](docs/konfiguration.md).
|
||||
|
||||
## 🧭 Dokumentation
|
||||
## 🧩 Wie AdGuard Shield arbeitet
|
||||
|
||||
| Thema | Link |
|
||||
|---|---|
|
||||
| Architektur & Funktionsweise | [docs/architektur.md](docs/architektur.md) |
|
||||
| Befehle & Nutzung | [docs/befehle.md](docs/befehle.md) |
|
||||
| Konfiguration | [docs/konfiguration.md](docs/konfiguration.md) |
|
||||
| Docker-Installationen | [docs/docker.md](docs/docker.md) |
|
||||
| Benachrichtigungen | [docs/benachrichtigungen.md](docs/benachrichtigungen.md) |
|
||||
| E-Mail Report | [docs/report.md](docs/report.md) |
|
||||
| Updates | [docs/update.md](docs/update.md) |
|
||||
| Tipps & Troubleshooting | [docs/tipps-und-troubleshooting.md](docs/tipps-und-troubleshooting.md) |
|
||||
|
||||
## 🧩 Wie es arbeitet
|
||||
```text
|
||||
DNS-Clients
|
||||
│
|
||||
│ DNS, DoH, DoT, DoQ, DNSCrypt
|
||||
▼
|
||||
AdGuard Home
|
||||
│
|
||||
│ /control/querylog API
|
||||
▼
|
||||
AdGuard Shield Daemon (pollt alle CHECK_INTERVAL Sekunden)
|
||||
│
|
||||
├── Rate-Limit-Prüfung (Client + Domain)
|
||||
├── Subdomain-Flood-Erkennung (Client + Basisdomain)
|
||||
├── DNS-Flood-Watchlist-Abgleich
|
||||
├── Whitelist-Prüfung (statisch + extern)
|
||||
├── GeoIP-Prüfung (falls aktiviert)
|
||||
├── Progressive Ban-Berechnung
|
||||
└── History-Protokollierung
|
||||
│
|
||||
▼
|
||||
SQLite-Datenbank (active_bans, ban_history, offense_tracking)
|
||||
│
|
||||
▼
|
||||
ipset + iptables/ip6tables
|
||||
│
|
||||
▼
|
||||
DNS-relevante Ports (53, 443, 853) werden für gesperrte Clients blockiert
|
||||
```
|
||||
|
||||
1. AdGuard Shield liest regelmäßig das AdGuard-Home-Query-Log über die API.
|
||||
2. Anfragen werden pro Client, Domain und Protokoll ausgewertet.
|
||||
3. Überschreitet ein Client die konfigurierten Limits, wird er gegen Whitelist und Sonderregeln geprüft.
|
||||
4. Die Sperre landet in der eigenen Firewall-Chain `ADGUARD_SHIELD`.
|
||||
3. Überschreitet ein Client die konfigurierten Limits, wird er gegen Whitelist, GeoIP und Sonderregeln geprüft.
|
||||
4. Die Sperre landet in der eigenen Firewall-Chain `ADGUARD_SHIELD` und wird in SQLite gespeichert.
|
||||
5. Ban-History, Logs und optionale Benachrichtigungen dokumentieren das Ereignis.
|
||||
6. Temporäre Sperren werden automatisch entfernt, permanente Sperren bleiben bis zur manuellen Freigabe aktiv.
|
||||
7. Bei einem Neustart werden alle aktiven Sperren aus SQLite wieder in die Firewall übertragen.
|
||||
|
||||
## 🧭 Dokumentation
|
||||
|
||||
| Thema | Link | Beschreibung |
|
||||
|---|---|---|
|
||||
| Architektur & Funktionsweise | [docs/architektur.md](docs/architektur.md) | Aufbau, Datenfluss, Firewall-Modell, SQLite-Schema, Hintergrundjobs und Sperrlogik |
|
||||
| Befehle & Nutzung | [docs/befehle.md](docs/befehle.md) | Vollständige CLI-Referenz mit Beispielen und typischen Betriebsabläufen |
|
||||
| Konfiguration | [docs/konfiguration.md](docs/konfiguration.md) | Alle Parameter aus `adguard-shield.conf` mit Beispielen und Empfehlungen |
|
||||
| Docker-Installationen | [docs/docker.md](docs/docker.md) | Firewall-Modi für klassische Installation, Docker Host Network und Docker Bridge |
|
||||
| Benachrichtigungen | [docs/benachrichtigungen.md](docs/benachrichtigungen.md) | Einrichtung von Ntfy, Discord, Slack, Gotify und Generic Webhooks |
|
||||
| E-Mail Report | [docs/report.md](docs/report.md) | Report-Inhalte, Mailversand, Cron-Job und manuelle Tests |
|
||||
| Updates | [docs/update.md](docs/update.md) | Update-Ablauf, Konfigurationsmigration und Migration von der Shell-Version |
|
||||
| Tipps & Troubleshooting | [docs/tipps-und-troubleshooting.md](docs/tipps-und-troubleshooting.md) | Diagnosewege für API, Firewall, GeoIP, Reports, Listen und falsche Sperren |
|
||||
|
||||
## 📜 Lizenz
|
||||
|
||||
Dieses Projekt steht unter der [MIT-Lizenz](./LICENSE).
|
||||
|
||||
<br><br>
|
||||
<p align="center">
|
||||
|
||||
@@ -8,18 +8,18 @@ AdGuard Shield ist ein Go-Daemon, der das Query Log von AdGuard Home auswertet,
|
||||
|
||||
| Dokument | Wofür es gedacht ist |
|
||||
|---|---|
|
||||
| [Architektur & Funktionsweise](architektur.md) | Erklärt den Aufbau, den Datenfluss, Firewall, SQLite, Hintergrundjobs und Sperrlogik |
|
||||
| [Befehle & Nutzung](befehle.md) | Vollständige CLI-Referenz mit typischen Betriebsabläufen |
|
||||
| [Konfiguration](konfiguration.md) | Alle Parameter aus `adguard-shield.conf` mit Beispielen und Empfehlungen |
|
||||
| [Architektur & Funktionsweise](architektur.md) | Erklärt den Aufbau, den Datenfluss, Firewall-Modell, SQLite-Schema, Hintergrundjobs und Sperrlogik |
|
||||
| [Befehle & Nutzung](befehle.md) | Vollständige CLI-Referenz mit Beispielen und typischen Betriebsabläufen |
|
||||
| [Konfiguration](konfiguration.md) | Alle Parameter aus `adguard-shield.conf` mit Beispielen, Empfehlungen und Beispielkonfigurationen |
|
||||
| [Docker-Installationen](docker.md) | Firewall-Modi für klassische Installation, Docker Host Network und veröffentlichte Docker-Ports |
|
||||
| [Benachrichtigungen](benachrichtigungen.md) | Einrichtung von Ntfy, Discord, Slack, Gotify und Generic Webhooks |
|
||||
| [E-Mail Report](report.md) | Report-Inhalte, Mailversand, Cron-Job und manuelle Tests |
|
||||
| [Update-Anleitung](update.md) | Update der Go-Version und Migration von alten Shell-Installationen |
|
||||
| [Tipps & Troubleshooting](tipps-und-troubleshooting.md) | Diagnosewege für API, Firewall, GeoIP, Reports, Listen und falsch gesetzte Sperren |
|
||||
| [Benachrichtigungen](benachrichtigungen.md) | Einrichtung von Ntfy, Discord, Slack, Gotify und Generic Webhooks mit Beispielinhalten |
|
||||
| [E-Mail Report](report.md) | Report-Inhalte, Formate, Mailversand, Cron-Job und manuelle Tests |
|
||||
| [Update-Anleitung](update.md) | Update der Go-Version, Konfigurationsmigration und Migration von alten Shell-Installationen |
|
||||
| [Tipps & Troubleshooting](tipps-und-troubleshooting.md) | Diagnosewege für API, Firewall, GeoIP, Reports, externe Listen und falsch gesetzte Sperren |
|
||||
|
||||
## Wichtigster Unterschied zur alten Shell-Version
|
||||
## Das Binary
|
||||
|
||||
Die frühere Version bestand aus mehreren Shell-Skripten, Hilfs-Workern, Cron-Jobs und einem separaten Watchdog. Die Go-Version bündelt diese Aufgaben in einem einzelnen Binary:
|
||||
Die Go-Version bündelt alle Aufgaben in einem einzelnen Binary:
|
||||
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield
|
||||
@@ -27,11 +27,11 @@ Die frühere Version bestand aus mehreren Shell-Skripten, Hilfs-Workern, Cron-Jo
|
||||
|
||||
Dieses Binary ist gleichzeitig:
|
||||
|
||||
- Daemon für den produktiven Betrieb
|
||||
- CLI für Status, History, Logs, Firewall, Listen, GeoIP und Reports
|
||||
- Installer, Updater und Uninstaller
|
||||
- Report-Generator
|
||||
- Hintergrundprozess für externe Whitelist, externe Blocklist, GeoIP und Offense-Cleanup
|
||||
- **Daemon** für den produktiven Betrieb (Querylog-Polling, Erkennung, Sperren)
|
||||
- **CLI** für Status, History, Logs, Firewall, Listen, GeoIP und Reports
|
||||
- **Installer**, **Updater** und **Uninstaller**
|
||||
- **Report-Generator** für HTML- und Text-Reports
|
||||
- **Hintergrundprozess** für externe Whitelist, externe Blocklist, GeoIP und Offense-Cleanup
|
||||
|
||||
Die meisten Befehle beginnen daher mit:
|
||||
|
||||
@@ -48,12 +48,35 @@ sudo ./adguard-shield update
|
||||
|
||||
## Empfohlener Lesefluss
|
||||
|
||||
Wenn du AdGuard Shield neu einrichtest:
|
||||
### Neueinrichtung
|
||||
|
||||
1. Lies zuerst [Architektur & Funktionsweise](architektur.md), damit klar ist, was genau gesperrt wird.
|
||||
1. Lies zuerst [Architektur & Funktionsweise](architektur.md), damit klar ist, was genau gesperrt wird und wie der Datenfluss aussieht.
|
||||
2. Passe danach [Konfiguration](konfiguration.md) an, besonders API-Zugang, Whitelist und Rate-Limits.
|
||||
3. Nutze [Befehle & Nutzung](befehle.md) für Installation, Dry-Run und Service-Start.
|
||||
4. Richte optional [Benachrichtigungen](benachrichtigungen.md), [Reports](report.md), GeoIP oder externe Listen ein.
|
||||
5. Bei Problemen hilft [Tipps & Troubleshooting](tipps-und-troubleshooting.md).
|
||||
|
||||
Wenn du von der alten Shell-Version kommst, beginne mit [Update-Anleitung](update.md).
|
||||
### Migration von der Shell-Version
|
||||
|
||||
Wenn du von der alten Shell-Version kommst, beginne mit [Update-Anleitung](update.md). Dort findest du den empfohlenen Migrationsablauf und Hinweise zu den erkannten Legacy-Artefakten.
|
||||
|
||||
### Docker-Setups
|
||||
|
||||
Wenn AdGuard Home in Docker läuft, lies [Docker-Installationen](docker.md) zusätzlich zur Grundkonfiguration. Der Firewall-Modus bestimmt, in welcher Chain die Sperren greifen.
|
||||
|
||||
## Wichtigster Unterschied zur alten Shell-Version
|
||||
|
||||
Die frühere Version bestand aus mehreren Shell-Skripten, Hilfs-Workern, Cron-Jobs und einem separaten Watchdog:
|
||||
|
||||
| Alte Shell-Version | Go-Version |
|
||||
|---|---|
|
||||
| `adguard-shield.sh` (Hauptskript) | Ein Binary für alles |
|
||||
| `iptables-helper.sh` | Integriert im Binary |
|
||||
| `external-blocklist-worker.sh` | Goroutine im Daemon |
|
||||
| `external-whitelist-worker.sh` | Goroutine im Daemon |
|
||||
| `geoip-worker.sh` | Goroutine im Daemon |
|
||||
| `offense-cleanup-worker.sh` | Goroutine im Daemon |
|
||||
| `report-generator.sh` | Integriert im Binary |
|
||||
| `unban-expired.sh` | Integriert im Daemon |
|
||||
| Watchdog-Service + Timer | `Restart=on-failure` in systemd |
|
||||
| Mehrere Cron-Jobs | Ein optionaler Cron-Job für Reports |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Architektur & Funktionsweise
|
||||
|
||||
Dieses Dokument erklärt, wie AdGuard Shield intern arbeitet. Es geht dabei nicht nur um die Dateien auf dem System, sondern auch um den Weg einer DNS-Anfrage vom AdGuard-Home-Querylog bis zur Firewall-Sperre.
|
||||
Dieses Dokument erklärt, wie AdGuard Shield intern arbeitet. Es geht dabei nicht nur um die Dateien auf dem System, sondern auch um den Weg einer DNS-Anfrage vom AdGuard-Home-Querylog bis zur Firewall-Sperre und die Logik hinter jeder Erkennungsmethode.
|
||||
|
||||
## Kurzüberblick
|
||||
|
||||
@@ -29,32 +29,33 @@ Das Binary übernimmt alle Aufgaben, die früher auf mehrere Shell-Skripte verte
|
||||
|
||||
```text
|
||||
Clients
|
||||
|
|
||||
| DNS, DoH, DoT, DoQ, DNSCrypt
|
||||
v
|
||||
│
|
||||
│ DNS, DoH, DoT, DoQ, DNSCrypt
|
||||
▼
|
||||
AdGuard Home
|
||||
|
|
||||
| /control/querylog
|
||||
v
|
||||
│
|
||||
│ /control/querylog
|
||||
▼
|
||||
AdGuard Shield Go-Daemon
|
||||
|
|
||||
|-- Rate-Limit-Prüfung pro Client + Domain
|
||||
|-- Subdomain-Flood-Prüfung pro Client + Basisdomain
|
||||
|-- Watchlist-Prüfung
|
||||
|-- Whitelist-Prüfung
|
||||
|-- GeoIP-Prüfung
|
||||
|-- externe Listen
|
||||
v
|
||||
│
|
||||
├── Rate-Limit-Prüfung pro Client + Domain
|
||||
├── Subdomain-Flood-Prüfung pro Client + Basisdomain
|
||||
├── Watchlist-Prüfung
|
||||
├── Whitelist-Prüfung (statisch + extern)
|
||||
├── GeoIP-Prüfung
|
||||
├── Progressive Ban-Berechnung
|
||||
├── externe Listen-Abgleich
|
||||
▼
|
||||
SQLite State
|
||||
|
|
||||
v
|
||||
│
|
||||
▼
|
||||
ipset + iptables/ip6tables
|
||||
|
|
||||
v
|
||||
│
|
||||
▼
|
||||
DNS-relevante Ports werden für gesperrte Clients blockiert
|
||||
```
|
||||
|
||||
Wichtig: AdGuard Shield analysiert nicht den Netzwerkverkehr direkt. Es liest das Querylog von AdGuard Home. Dadurch erkennt es auch Anfragen über moderne DNS-Protokolle, solange diese in AdGuard Home sichtbar sind.
|
||||
**Wichtig:** AdGuard Shield analysiert nicht den Netzwerkverkehr direkt. Es liest das Querylog von AdGuard Home. Dadurch erkennt es auch Anfragen über verschlüsselte DNS-Protokolle (DoH, DoT, DoQ, DNSCrypt), solange diese in AdGuard Home sichtbar sind.
|
||||
|
||||
## Laufzeit im produktiven Betrieb
|
||||
|
||||
@@ -66,18 +67,20 @@ Der systemd-Service startet den Daemon so:
|
||||
|
||||
Beim Start passiert in dieser Reihenfolge:
|
||||
|
||||
1. Konfiguration wird geladen.
|
||||
2. SQLite-Datenbank unter `STATE_DIR` wird geöffnet oder angelegt.
|
||||
3. Logdatei wird geöffnet.
|
||||
4. Firewall-Chain und ipsets werden vorbereitet.
|
||||
5. GeoIP-Datenbank wird geöffnet, falls GeoIP aktiv ist.
|
||||
6. Whitelist-Cache wird aus SQLite geladen.
|
||||
7. GeoIP-Sperren werden gegen die aktuelle GeoIP-Konfiguration geprüft.
|
||||
8. Aktive Sperren aus SQLite werden wieder in die Firewall geschrieben.
|
||||
9. Hintergrundjobs für externe Whitelist, externe Blocklist und Offense-Cleanup starten, falls aktiviert.
|
||||
10. Der zentrale Querylog-Poller beginnt mit der regelmäßigen Auswertung.
|
||||
| Schritt | Aktion | Beschreibung |
|
||||
|---:|---|---|
|
||||
| 1 | Konfiguration laden | Liest `adguard-shield.conf` und validiert alle Parameter |
|
||||
| 2 | SQLite-Datenbank öffnen | Öffnet oder erstellt die Datenbank unter `STATE_DIR` im WAL-Modus |
|
||||
| 3 | Logdatei öffnen | Initialisiert die Datei unter `LOG_FILE` |
|
||||
| 4 | Firewall vorbereiten | Erstellt Chain und ipsets, falls nicht vorhanden |
|
||||
| 5 | GeoIP öffnen | Lädt die MaxMind-Datenbank, falls GeoIP aktiviert ist |
|
||||
| 6 | Whitelist-Cache laden | Liest aufgelöste externe Whitelist-IPs aus SQLite |
|
||||
| 7 | GeoIP-Reconcile | Prüft bestehende GeoIP-Sperren gegen aktuelle Konfiguration |
|
||||
| 8 | Firewall-Reconcile | Überträgt aktive Sperren aus SQLite wieder in die Firewall |
|
||||
| 9 | Hintergrundjobs starten | Startet Goroutines für externe Listen und Offense-Cleanup |
|
||||
| 10 | Querylog-Poller starten | Beginnt mit der regelmäßigen Auswertung des Querylogs |
|
||||
|
||||
Das Reconcile beim Start ist wichtig: Wenn der Server neu startet oder iptables-Regeln verloren gehen, bleiben die Sperren in SQLite erhalten und werden beim nächsten Start wieder in die Firewall übertragen.
|
||||
Das Reconcile beim Start ist besonders wichtig: Wenn der Server neu startet oder `iptables`-Regeln verloren gehen (z.B. durch einen Reboot), bleiben die Sperren in SQLite erhalten und werden beim nächsten Start wieder in die Firewall übertragen.
|
||||
|
||||
## Querylog-Poller
|
||||
|
||||
@@ -90,8 +93,8 @@ Der Daemon ruft regelmäßig den AdGuard-Home-Endpunkt ab:
|
||||
Gesteuert wird das über:
|
||||
|
||||
```bash
|
||||
CHECK_INTERVAL=10
|
||||
API_QUERY_LIMIT=500
|
||||
CHECK_INTERVAL=10 # Abstand zwischen Abfragen in Sekunden
|
||||
API_QUERY_LIMIT=500 # Maximale Einträge pro API-Abfrage
|
||||
```
|
||||
|
||||
Aus jedem Querylog-Eintrag werden diese Informationen extrahiert:
|
||||
@@ -103,20 +106,22 @@ Aus jedem Querylog-Eintrag werden diese Informationen extrahiert:
|
||||
| Domain | Schlüssel für Rate-Limit und Subdomain-Flood |
|
||||
| `client_proto` | Anzeige von DNS, DoH, DoT, DoQ oder DNSCrypt |
|
||||
|
||||
Bereits gesehene Querylog-Einträge werden im Speicher dedupliziert. Der Daemon hält nur Ereignisse aus dem relevanten Zeitfenster plus kleinem Puffer vor.
|
||||
Bereits gesehene Querylog-Einträge werden im Speicher dedupliziert. Der Daemon hält nur Ereignisse aus dem relevanten Zeitfenster plus kleinem Puffer vor, sodass der Speicherverbrauch auch bei hohem DNS-Aufkommen stabil bleibt.
|
||||
|
||||
## Rate-Limit-Sperre
|
||||
## Erkennungsmethoden im Detail
|
||||
|
||||
### Rate-Limit-Sperre
|
||||
|
||||
Eine Rate-Limit-Sperre entsteht, wenn ein Client dieselbe Domain innerhalb des konfigurierten Fensters zu oft abfragt.
|
||||
|
||||
Beispiel:
|
||||
**Konfiguration:**
|
||||
|
||||
```bash
|
||||
RATE_LIMIT_MAX_REQUESTS=30
|
||||
RATE_LIMIT_WINDOW=60
|
||||
RATE_LIMIT_MAX_REQUESTS=30 # Maximale Anfragen pro Client und Domain
|
||||
RATE_LIMIT_WINDOW=60 # Zeitfenster in Sekunden
|
||||
```
|
||||
|
||||
Ablauf:
|
||||
**Ablauf am Beispiel:**
|
||||
|
||||
1. Client `192.168.1.50` fragt `example.com` 45-mal innerhalb von 60 Sekunden ab.
|
||||
2. Der Poller sieht diese Einträge im Querylog.
|
||||
@@ -128,134 +133,153 @@ Ablauf:
|
||||
8. Die IP wird in SQLite gespeichert und per Firewall blockiert.
|
||||
9. History, Log und optionale Benachrichtigung werden geschrieben.
|
||||
|
||||
## Subdomain-Flood-Erkennung
|
||||
### Subdomain-Flood-Erkennung
|
||||
|
||||
Random-Subdomain-Floods sehen anders aus als normale Wiederholungen. Ein Client fragt nicht eine Domain ständig neu ab, sondern viele zufällige Subdomains:
|
||||
Random-Subdomain-Floods sehen anders aus als normale Wiederholungen. Ein Client fragt nicht eine Domain ständig ab, sondern erzeugt viele verschiedene, oft zufällige Subdomains:
|
||||
|
||||
```text
|
||||
a8f3.example.com
|
||||
k29x.example.com
|
||||
z9p1.example.com
|
||||
m7q2.example.com
|
||||
```
|
||||
|
||||
AdGuard Shield extrahiert daraus die Basisdomain `example.com` und zählt pro Client, wie viele unterschiedliche Subdomains im Fenster vorkommen.
|
||||
AdGuard Shield extrahiert daraus die Basisdomain `example.com` und zählt pro Client, wie viele **unterschiedliche** Subdomains im Fenster vorkommen. Direkte Anfragen an `example.com` selbst werden bei dieser Erkennung nicht mitgezählt.
|
||||
|
||||
Gesteuert wird das über:
|
||||
**Konfiguration:**
|
||||
|
||||
```bash
|
||||
SUBDOMAIN_FLOOD_ENABLED=true
|
||||
SUBDOMAIN_FLOOD_MAX_UNIQUE=50
|
||||
SUBDOMAIN_FLOOD_WINDOW=60
|
||||
SUBDOMAIN_FLOOD_MAX_UNIQUE=50 # Maximale eindeutige Subdomains
|
||||
SUBDOMAIN_FLOOD_WINDOW=60 # Zeitfenster in Sekunden
|
||||
```
|
||||
|
||||
Ablauf:
|
||||
**Ablauf am Beispiel:**
|
||||
|
||||
1. Client `10.0.0.99` fragt 63 verschiedene Subdomains von `example.com` ab.
|
||||
2. Direkte Anfragen an `example.com` zählen für diese Erkennung nicht.
|
||||
3. Sobald mehr als `SUBDOMAIN_FLOOD_MAX_UNIQUE` eindeutige Subdomains erkannt werden, wird gesperrt.
|
||||
4. In der History erscheint die Domain als `*.example.com`.
|
||||
5. Der Grund lautet `subdomain-flood`, außer die Basisdomain steht auf der DNS-Flood-Watchlist.
|
||||
2. Sobald mehr als `SUBDOMAIN_FLOOD_MAX_UNIQUE` eindeutige Subdomains erkannt werden, wird gesperrt.
|
||||
3. In der History erscheint die Domain als `*.example.com`.
|
||||
4. Der Grund lautet `subdomain-flood`, außer die Basisdomain steht auf der DNS-Flood-Watchlist.
|
||||
|
||||
## DNS-Flood-Watchlist
|
||||
**Hinweise:**
|
||||
|
||||
- Multi-Part-TLDs wie `.co.uk` werden korrekt als Basisdomain erkannt.
|
||||
- CDNs und manche Apps erzeugen legitim viele Subdomains. In solchen Fällen den Grenzwert erhöhen oder den Client whitelisten.
|
||||
|
||||
### DNS-Flood-Watchlist
|
||||
|
||||
Die Watchlist ist für Domains gedacht, bei denen du nicht stufenweise reagieren möchtest. Wenn eine Domain auf der Watchlist steht und gleichzeitig ein Rate-Limit- oder Subdomain-Flood-Verstoß erkannt wird, wird sofort permanent gesperrt.
|
||||
|
||||
**Konfiguration:**
|
||||
|
||||
```bash
|
||||
DNS_FLOOD_WATCHLIST_ENABLED=true
|
||||
DNS_FLOOD_WATCHLIST="microsoft.com,google.com"
|
||||
```
|
||||
|
||||
Matching:
|
||||
**Matching-Logik:**
|
||||
|
||||
- `microsoft.com` matcht `microsoft.com`
|
||||
- `login.microsoft.com` matcht ebenfalls `microsoft.com`
|
||||
- `evil-microsoft.com` matcht nicht
|
||||
| Anfrage | Watchlist-Eintrag | Treffer? |
|
||||
|---|---|---|
|
||||
| `microsoft.com` | `microsoft.com` | Ja |
|
||||
| `login.microsoft.com` | `microsoft.com` | Ja |
|
||||
| `evil-microsoft.com` | `microsoft.com` | Nein |
|
||||
|
||||
Bei einem Treffer:
|
||||
**Bei einem Treffer:**
|
||||
|
||||
- Reason wird `dns-flood-watchlist`
|
||||
- Sperre ist permanent
|
||||
- Sperre ist immer permanent
|
||||
- Progressive-Ban-Stufen werden für die Dauer ignoriert
|
||||
- AbuseIPDB-Reporting kann ausgelöst werden, wenn es aktiviert und ein API-Key vorhanden ist
|
||||
- AbuseIPDB-Reporting wird ausgelöst, wenn aktiviert und ein API-Key vorhanden ist
|
||||
|
||||
## Progressive Sperren
|
||||
### Progressive Sperren
|
||||
|
||||
Progressive Sperren erhöhen die Sperrdauer bei wiederholten Monitor-Sperren. Das Verhalten ähnelt fail2ban.
|
||||
Progressive Sperren erhöhen die Sperrdauer bei wiederholten Verstößen. Das Verhalten ähnelt fail2ban.
|
||||
|
||||
Standard:
|
||||
**Konfiguration:**
|
||||
|
||||
```bash
|
||||
BAN_DURATION=3600
|
||||
BAN_DURATION=3600 # Basis-Sperrdauer: 1 Stunde
|
||||
PROGRESSIVE_BAN_ENABLED=true
|
||||
PROGRESSIVE_BAN_MULTIPLIER=2
|
||||
PROGRESSIVE_BAN_MAX_LEVEL=5
|
||||
PROGRESSIVE_BAN_RESET_AFTER=86400
|
||||
PROGRESSIVE_BAN_MULTIPLIER=2 # Verdopplung pro Stufe
|
||||
PROGRESSIVE_BAN_MAX_LEVEL=5 # Ab Stufe 5 permanent
|
||||
PROGRESSIVE_BAN_RESET_AFTER=86400 # Zähler-Reset nach 24h ohne Vergehen
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
**Stufenverlauf mit Standardwerten:**
|
||||
|
||||
| Vergehen | Stufe | Dauer |
|
||||
|---|---:|---|
|
||||
| 1 | 1 | 1 Stunde |
|
||||
| 2 | 2 | 2 Stunden |
|
||||
| 3 | 3 | 4 Stunden |
|
||||
| 4 | 4 | 8 Stunden |
|
||||
| 5 | 5 | permanent |
|
||||
| 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 |
|
||||
|
||||
Der Offense-Zähler wird in SQLite gespeichert. Wenn eine IP länger als `PROGRESSIVE_BAN_RESET_AFTER` nicht auffällig war, kann der Cleanup sie entfernen.
|
||||
Der Offense-Zähler wird in SQLite gespeichert. Wenn eine IP länger als `PROGRESSIVE_BAN_RESET_AFTER` (Standard: 24 Stunden) nicht auffällig war, wird der Zähler vom Cleanup-Job entfernt.
|
||||
|
||||
Progressive Sperren gelten für Monitor-Sperren. GeoIP- und externe Blocklist-Sperren haben eigene Regeln.
|
||||
**Geltungsbereich:** Progressive Sperren gelten nur für Monitor-Sperren (`rate-limit`, `subdomain-flood`). Watchlist-Treffer sind sofort permanent. GeoIP- und externe Blocklist-Sperren haben eigene Regeln.
|
||||
|
||||
## Firewall-Modell
|
||||
|
||||
AdGuard Shield nutzt eine eigene Chain und zwei ipsets:
|
||||
AdGuard Shield nutzt eine eigene Chain und zwei ipsets, um gesperrte IPs effizient zu verwalten:
|
||||
|
||||
```text
|
||||
ADGUARD_SHIELD
|
||||
adguard_shield_v4
|
||||
adguard_shield_v6
|
||||
Chain: ADGUARD_SHIELD
|
||||
IPv4: adguard_shield_v4
|
||||
IPv6: adguard_shield_v6
|
||||
```
|
||||
|
||||
### Chain-Einbindung
|
||||
|
||||
Die Chain wird je nach `FIREWALL_MODE` in die passende Host-Chain eingehängt:
|
||||
|
||||
| Modus | Parent-Chain |
|
||||
|---|---|
|
||||
| `host` / `docker-host` | `INPUT` |
|
||||
| `docker-bridge` | `DOCKER-USER` |
|
||||
| `hybrid` | `INPUT` und `DOCKER-USER` |
|
||||
| Modus | Parent-Chain | Einsatzgebiet |
|
||||
|---|---|---|
|
||||
| `host` / `docker-host` | `INPUT` | Klassische Installation oder Docker mit Host-Netzwerk |
|
||||
| `docker-bridge` | `DOCKER-USER` | Docker mit veröffentlichten Ports (`-p 53:53`) |
|
||||
| `hybrid` | `INPUT` und `DOCKER-USER` | Gemischte Setups oder Migrationsphasen |
|
||||
|
||||
Für klassische Installationen und Docker mit Host-Netzwerk sieht das so aus:
|
||||
### Regelstruktur im Host-Modus
|
||||
|
||||
```text
|
||||
INPUT
|
||||
|- tcp/53 -> ADGUARD_SHIELD
|
||||
|- udp/53 -> ADGUARD_SHIELD
|
||||
|- tcp/443 -> ADGUARD_SHIELD
|
||||
|- udp/443 -> ADGUARD_SHIELD
|
||||
|- tcp/853 -> ADGUARD_SHIELD
|
||||
|- udp/853 -> ADGUARD_SHIELD
|
||||
├── tcp/53 → ADGUARD_SHIELD
|
||||
├── udp/53 → ADGUARD_SHIELD
|
||||
├── tcp/443 → ADGUARD_SHIELD
|
||||
├── udp/443 → ADGUARD_SHIELD
|
||||
├── tcp/853 → ADGUARD_SHIELD
|
||||
└── udp/853 → ADGUARD_SHIELD
|
||||
|
||||
ADGUARD_SHIELD
|
||||
|- src in adguard_shield_v4 -> DROP
|
||||
|- src in adguard_shield_v6 -> DROP
|
||||
├── src in adguard_shield_v4 → DROP
|
||||
└── src in adguard_shield_v6 → DROP
|
||||
```
|
||||
|
||||
Bei Docker Bridge mit veröffentlichten Ports ersetzt `DOCKER-USER` die `INPUT`-Chain im oberen Teil des Diagramms. Docker leitet solche Pakete nach DNAT über `FORWARD`; `INPUT` sieht sie dort nicht zuverlässig.
|
||||
Bei Docker Bridge mit veröffentlichten Ports ersetzt `DOCKER-USER` die `INPUT`-Chain. Docker leitet solche Pakete nach DNAT über `FORWARD`; die `INPUT`-Chain sieht sie dort nicht zuverlässig.
|
||||
|
||||
Die Ports kommen aus:
|
||||
### Blockierte Ports
|
||||
|
||||
Die Ports werden über `BLOCKED_PORTS` konfiguriert:
|
||||
|
||||
```bash
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
Das blockiert klassische DNS-Anfragen und die üblichen Ports für DoH, DoT und DoQ. Die Erkennung selbst basiert weiterhin auf dem AdGuard-Home-Querylog.
|
||||
| Port | Protokoll | Zweck |
|
||||
|---:|---|---|
|
||||
| 53 | UDP/TCP | Klassisches DNS |
|
||||
| 443 | TCP | DNS-over-HTTPS (DoH) |
|
||||
| 853 | TCP/UDP | DNS-over-TLS (DoT) und DNS-over-QUIC (DoQ) |
|
||||
|
||||
Warum `ipset`?
|
||||
Die Erkennung basiert auf dem AdGuard-Home-Querylog, die Sperre blockiert aber alle konfigurierten Ports, unabhängig davon, welches Protokoll den Verstoß ausgelöst hat.
|
||||
|
||||
- viele gesperrte IPs erzeugen nicht tausende einzelne iptables-Regeln
|
||||
### Warum ipset?
|
||||
|
||||
- Viele gesperrte IPs erzeugen nicht tausende einzelne `iptables`-Regeln
|
||||
- IPv4 und IPv6 werden getrennt sauber verwaltet
|
||||
- Sperren und Freigaben sind schneller
|
||||
- die eigene Chain bleibt übersichtlich
|
||||
- Sperren und Freigaben sind performant, auch bei hunderten IPs
|
||||
- Die eigene Chain bleibt übersichtlich und beeinträchtigt bestehende Regeln nicht
|
||||
|
||||
## SQLite-State
|
||||
|
||||
@@ -265,17 +289,25 @@ Der zentrale Zustand liegt standardmäßig hier:
|
||||
/var/lib/adguard-shield/adguard-shield.db
|
||||
```
|
||||
|
||||
Wichtige Tabellen:
|
||||
### Tabellen
|
||||
|
||||
| Tabelle | Inhalt |
|
||||
| Tabelle | Inhalt | Beschreibung |
|
||||
|---|---|---|
|
||||
| `active_bans` | Aktive Sperren | IP, Grund, Dauer, Quelle, Ablaufzeit, Offense-Level, GeoIP-Metadaten |
|
||||
| `ban_history` | Dauerhafte Historie | Zeitstempel, Aktion (BAN/UNBAN/DRY), Client-IP, Domain, Protokoll, Grund |
|
||||
| `offense_tracking` | Progressive-Ban-Stufen | Client-IP, aktuelle Offense-Stufe, letzter Verstoß |
|
||||
| `whitelist_cache` | Externe Whitelist | Aufgelöste IPs aus externen Whitelist-URLs mit Quellzuordnung |
|
||||
| `geoip_cache` | GeoIP-Ergebnisse | IP, Ländercode, Zeitstempel der Abfrage, DB-Änderungszeitpunkt |
|
||||
|
||||
Die Datenbank nutzt WAL-Modus (Write-Ahead Logging) und einen Busy-Timeout, damit Daemon und CLI-Befehle gleichzeitig lesen und schreiben können, ohne sich gegenseitig zu blockieren.
|
||||
|
||||
### History-Aktionen
|
||||
|
||||
| Aktion | Bedeutung |
|
||||
|---|---|
|
||||
| `active_bans` | aktuell aktive Sperren mit IP, Grund, Dauer, Quelle und Ablaufzeit |
|
||||
| `ban_history` | dauerhafte Historie von `BAN`, `UNBAN` und `DRY` |
|
||||
| `offense_tracking` | Progressive-Ban-Stufen pro Client-IP |
|
||||
| `whitelist_cache` | aufgelöste IPs aus externen Whitelists |
|
||||
| `geoip_cache` | gecachte GeoIP-Ergebnisse |
|
||||
|
||||
Die Datenbank nutzt WAL-Modus und einen Busy-Timeout, damit Daemon und CLI-Befehle gleichzeitig lesen können.
|
||||
| `BAN` | Aktive Sperre gesetzt (Firewall-Regel erstellt) |
|
||||
| `UNBAN` | Sperre aufgehoben (manuell, abgelaufen oder durch Whitelist) |
|
||||
| `DRY` | Sperre wäre gesetzt worden, wurde aber im Dry-Run nur protokolliert |
|
||||
|
||||
## Verzeichnisstruktur
|
||||
|
||||
@@ -292,116 +324,155 @@ Nach einer Standardinstallation sieht die Struktur so aus:
|
||||
└── adguard-shield.service
|
||||
|
||||
/var/lib/adguard-shield/
|
||||
├── adguard-shield.db
|
||||
├── external-blocklist/
|
||||
├── external-whitelist/
|
||||
├── iptables-rules.v4
|
||||
└── iptables-rules.v6
|
||||
├── adguard-shield.db # SQLite State-Datenbank
|
||||
├── 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-Regeln (nach firewall-save)
|
||||
└── iptables-rules.v6 # Gesicherte IPv6-Regeln (nach firewall-save)
|
||||
|
||||
/var/log/
|
||||
└── adguard-shield.log
|
||||
└── adguard-shield.log # Daemon-Logdatei
|
||||
|
||||
/etc/cron.d/
|
||||
└── adguard-shield-report # Cron-Job für Reports (optional)
|
||||
```
|
||||
|
||||
## Hintergrundjobs im Daemon
|
||||
|
||||
Es gibt in der Go-Version keine separaten Worker-Skripte mehr. Diese Aufgaben laufen als Goroutines im Daemon:
|
||||
|
||||
| Aufgabe | Wann aktiv | Zweck |
|
||||
|---|---|---|
|
||||
| Querylog-Poller | immer | liest und analysiert AdGuard-Home-Querylogs |
|
||||
| externe Whitelist | `EXTERNAL_WHITELIST_ENABLED=true` | lädt Listen, löst Hostnamen auf, aktualisiert Whitelist-Cache |
|
||||
| externe Blocklist | `EXTERNAL_BLOCKLIST_ENABLED=true` | lädt Listen, sperrt gewünschte IPs und hebt entfernte IPs optional auf |
|
||||
| Offense-Cleanup | `PROGRESSIVE_BAN_ENABLED=true` | entfernt abgelaufene Offense-Zähler |
|
||||
| GeoIP-Lookups | `GEOIP_ENABLED=true` | prüft neue öffentliche Client-IPs gegen Länderregeln |
|
||||
| Aufgabe | Wann aktiv | Intervall | Zweck |
|
||||
|---|---|---|---|
|
||||
| Querylog-Poller | Immer | `CHECK_INTERVAL` | Liest und analysiert AdGuard-Home-Querylogs |
|
||||
| Externe Whitelist | `EXTERNAL_WHITELIST_ENABLED=true` | `EXTERNAL_WHITELIST_INTERVAL` | Lädt Listen, löst Hostnamen auf, aktualisiert Whitelist-Cache |
|
||||
| Externe Blocklist | `EXTERNAL_BLOCKLIST_ENABLED=true` | `EXTERNAL_BLOCKLIST_INTERVAL` | Lädt Listen, sperrt neue IPs, hebt entfernte IPs optional auf |
|
||||
| Offense-Cleanup | `PROGRESSIVE_BAN_ENABLED=true` | Stündlich | Entfernt abgelaufene Offense-Zähler |
|
||||
| GeoIP-Lookups | `GEOIP_ENABLED=true` | Mit jedem Poll | Prüft neue öffentliche Client-IPs gegen Länderregeln |
|
||||
|
||||
Externe Whitelist und Blocklist laufen sofort beim Start einmalig und danach im jeweiligen Intervall.
|
||||
Externe Whitelist und Blocklist laufen sofort beim Start einmalig und danach im jeweiligen Intervall. Die Sperren-Freigabe abgelaufener Bans wird bei jedem Querylog-Poll mit geprüft.
|
||||
|
||||
## Whitelist-Logik
|
||||
|
||||
Vor jeder Sperre wird geprüft, ob die IP vertrauenswürdig ist.
|
||||
|
||||
Quellen:
|
||||
**Quellen (in Prüfreihenfolge):**
|
||||
|
||||
- statische `WHITELIST` aus der Konfiguration
|
||||
- aufgelöste IPs aus externen Whitelists
|
||||
1. Statische `WHITELIST` aus der Konfiguration (kommagetrennt)
|
||||
2. Aufgelöste IPs aus externen Whitelists (gespeichert in SQLite)
|
||||
|
||||
Eine gewhitelistete IP wird nicht gesperrt. Wenn eine externe Whitelist später eine bereits gesperrte IP enthält, hebt der Daemon diese Sperre automatisch auf.
|
||||
**Verhalten:**
|
||||
|
||||
- Eine gewhitelistete IP wird nie gesperrt, unabhängig von der Sperrquelle.
|
||||
- Dies gilt für automatische Sperren, manuelle Sperren, GeoIP-Sperren und externe Blocklist-Sperren.
|
||||
- Wenn eine externe Whitelist später eine bereits gesperrte IP enthält, hebt der Daemon diese Sperre automatisch auf.
|
||||
|
||||
## GeoIP-Logik
|
||||
|
||||
GeoIP arbeitet nur mit öffentlichen IPs, wenn `GEOIP_SKIP_PRIVATE=true` gesetzt ist. Private Netze, Loopback, Link-Local und CGNAT werden übersprungen.
|
||||
GeoIP arbeitet mit der MaxMind GeoLite2-Datenbank und filtert DNS-Clients nach ihrem geografischen Herkunftsland.
|
||||
|
||||
Modi:
|
||||
### Private IPs
|
||||
|
||||
Wenn `GEOIP_SKIP_PRIVATE=true` gesetzt ist (Standard), 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)
|
||||
|
||||
### Modi
|
||||
|
||||
| Modus | Verhalten |
|
||||
|---|---|
|
||||
| `blocklist` | Länder aus `GEOIP_COUNTRIES` werden gesperrt |
|
||||
| `allowlist` | nur Länder aus `GEOIP_COUNTRIES` sind erlaubt, alle anderen öffentlichen Länder werden gesperrt |
|
||||
| `blocklist` | Nur die in `GEOIP_COUNTRIES` genannten Länder werden gesperrt. Alle anderen sind erlaubt. |
|
||||
| `allowlist` | Nur die in `GEOIP_COUNTRIES` genannten Länder sind erlaubt. Alle anderen öffentlichen IPs werden gesperrt. |
|
||||
|
||||
GeoIP-Sperren sind permanent, werden aber beim Start gegen die aktuelle Konfiguration geprüft. Wenn GeoIP deaktiviert wird, der Modus wechselt oder ein Land nicht mehr blockiert werden müsste, kann die Sperre automatisch aufgehoben werden.
|
||||
Die Ländercodes folgen dem Standard ISO 3166-1 Alpha-2 (siehe [ISO-3166-1-Kodierliste auf Wikipedia](https://de.wikipedia.org/wiki/ISO-3166-1-Kodierliste)).
|
||||
|
||||
### GeoIP-Datenquellen (Priorität)
|
||||
|
||||
| Priorität | Quelle | Konfiguration |
|
||||
|---:|---|---|
|
||||
| 1 | Manueller MMDB-Pfad | `GEOIP_MMDB_PATH="/pfad/zur/GeoLite2-Country.mmdb"` |
|
||||
| 2 | Automatischer MaxMind-Download | `GEOIP_LICENSE_KEY="dein_key"` |
|
||||
| 3 | Legacy-Fallback | `geoiplookup` / `geoiplookup6` (Systembefehle) |
|
||||
|
||||
**GeoIP-Sperren sind permanent**, werden aber beim Start gegen die aktuelle Konfiguration geprüft. Wenn GeoIP deaktiviert wird, der Modus wechselt oder ein Land nicht mehr blockiert werden müsste, wird die Sperre automatisch aufgehoben.
|
||||
|
||||
## AbuseIPDB-Reporting
|
||||
|
||||
AbuseIPDB wird nur für permanente Monitor-Sperren genutzt:
|
||||
AbuseIPDB wird nur für **permanente** Monitor-Sperren genutzt:
|
||||
|
||||
- DNS-Flood-Watchlist-Treffer
|
||||
- Progressive-Ban-Sperren, die die maximale Stufe erreicht haben
|
||||
| Wird gemeldet | Wird nicht gemeldet |
|
||||
|---|---|
|
||||
| DNS-Flood-Watchlist-Treffer | Temporäre Rate-Limit-Sperren |
|
||||
| Progressive-Ban auf Maximalstufe | Manuelle Sperren |
|
||||
| | GeoIP-Sperren |
|
||||
| | Externe Blocklist-Sperren |
|
||||
|
||||
Nicht gemeldet werden:
|
||||
|
||||
- temporäre Rate-Limit-Sperren
|
||||
- manuelle Sperren
|
||||
- GeoIP-Sperren
|
||||
- externe Blocklist-Sperren
|
||||
|
||||
Voraussetzung:
|
||||
**Konfiguration:**
|
||||
|
||||
```bash
|
||||
ABUSEIPDB_ENABLED=true
|
||||
ABUSEIPDB_API_KEY="..."
|
||||
ABUSEIPDB_CATEGORIES="4" # 4 = DDoS Attack
|
||||
```
|
||||
|
||||
Die Kategorie-Nummern sind auf [abuseipdb.com/categories](https://www.abuseipdb.com/categories) dokumentiert.
|
||||
|
||||
## Protokollerkennung
|
||||
|
||||
AdGuard Shield liest das Feld `client_proto` aus der AdGuard-Home-API und zeigt das Protokoll in History, Logs und Benachrichtigungen an:
|
||||
|
||||
| API-Wert | Anzeige | Beschreibung |
|
||||
|---|---|---|
|
||||
| leer oder `dns` | `DNS` | Klassisches DNS über UDP/TCP |
|
||||
| `doh` | `DoH` | DNS-over-HTTPS |
|
||||
| `dot` | `DoT` | DNS-over-TLS |
|
||||
| `doq` | `DoQ` | DNS-over-QUIC |
|
||||
| `dnscrypt` | `DNSCrypt` | DNSCrypt-Protokoll |
|
||||
|
||||
Die Sperre blockiert die konfigurierten Ports unabhängig davon, welches Protokoll den Verstoß ausgelöst hat. So wird verhindert, dass ein gesperrter Client einfach auf ein anderes DNS-Protokoll ausweicht.
|
||||
|
||||
## History und Logs
|
||||
|
||||
Es gibt zwei unterschiedliche Blickwinkel:
|
||||
Es gibt zwei unterschiedliche Blickwinkel auf das Geschehen:
|
||||
|
||||
| Quelle | Inhalt |
|
||||
| Quelle | Inhalt | Befehl |
|
||||
|---|---|---|
|
||||
| `ban_history` in SQLite | Sperren, Freigaben und Dry-Run-Ereignisse | `history [N]` |
|
||||
| `LOG_FILE` | Daemon-Ereignisse, Worker-Läufe, Warnungen, Fehler | `logs`, `logs-follow` |
|
||||
| Live-Ansicht | Aktuelle Queries, Top-Clients, Sperren, Systemereignisse | `live` |
|
||||
|
||||
**Wichtig:** Query-Inhalte werden nicht dauerhaft in die Logdatei geschrieben. Für aktuelle Queries ist die Live-Ansicht (`live`) gedacht.
|
||||
|
||||
### History-Gründe
|
||||
|
||||
| Grund | Bedeutung |
|
||||
|---|---|
|
||||
| `ban_history` in SQLite | Sperren, Freigaben und Dry-Run-Ereignisse |
|
||||
| `LOG_FILE` | Daemon-Ereignisse, Worker-Läufe, Warnungen, Fehler |
|
||||
|
||||
Query-Inhalte werden nicht dauerhaft in die Logdatei geschrieben. Für aktuelle Queries gibt es die Live-Ansicht:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield live
|
||||
```
|
||||
|
||||
History:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield history
|
||||
sudo /opt/adguard-shield/adguard-shield history 200
|
||||
```
|
||||
|
||||
Logs:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
sudo journalctl -u adguard-shield -f
|
||||
```
|
||||
| `rate-limit` | Gleiche Domain zu oft angefragt |
|
||||
| `subdomain-flood` | Zu viele eindeutige Subdomains einer Basisdomain |
|
||||
| `dns-flood-watchlist` | Watchlist-Treffer mit sofortigem Permanent-Ban |
|
||||
| `external-blocklist` | Sperre aus externer Blocklist |
|
||||
| `geoip` | GeoIP-Länderfilter |
|
||||
| `manual` | Manueller Ban oder Unban |
|
||||
| `manual-flush` | Freigabe aller Sperren durch `flush` |
|
||||
| `expired` | Temporäre Sperre ist abgelaufen |
|
||||
| `external-whitelist` | Freigabe durch externe Whitelist |
|
||||
|
||||
## Unterschied zur alten Shell-Architektur
|
||||
|
||||
Früher gab es unter anderem:
|
||||
|
||||
- `adguard-shield.sh`
|
||||
- `iptables-helper.sh`
|
||||
- `external-blocklist-worker.sh`
|
||||
- `external-whitelist-worker.sh`
|
||||
- `geoip-worker.sh`
|
||||
- `offense-cleanup-worker.sh`
|
||||
- `report-generator.sh`
|
||||
- `unban-expired.sh`
|
||||
- Watchdog-Service und Watchdog-Timer
|
||||
- `adguard-shield.sh` (Hauptskript)
|
||||
- `iptables-helper.sh` (Firewall-Management)
|
||||
- `external-blocklist-worker.sh` (Blocklist-Synchronisation)
|
||||
- `external-whitelist-worker.sh` (Whitelist-Synchronisation)
|
||||
- `geoip-worker.sh` (GeoIP-Prüfung)
|
||||
- `offense-cleanup-worker.sh` (Offense-Bereinigung)
|
||||
- `report-generator.sh` (Report-Erstellung)
|
||||
- `unban-expired.sh` (Ablauf temporärer Sperren)
|
||||
- Watchdog-Service und Watchdog-Timer (Überwachung)
|
||||
|
||||
In der Go-Version gibt es diese Skripte nicht mehr. Der systemd-Service nutzt `Restart=on-failure`; die eigentlichen Worker laufen im Daemon. Alte Artefakte werden vom Installer erkannt und müssen vor der Go-Installation entfernt werden, damit keine zwei Implementierungen parallel dieselbe Firewall und dieselben Dateien verwalten.
|
||||
In der Go-Version gibt es diese Skripte nicht mehr. Der systemd-Service nutzt `Restart=on-failure`; die eigentlichen Worker laufen als Goroutines im Daemon. Alte Artefakte werden vom Installer erkannt und müssen vor der Go-Installation entfernt werden, damit nicht zwei Implementierungen parallel dieselbe Firewall und dieselben Dateien verwalten.
|
||||
|
||||
702
docs/befehle.md
702
docs/befehle.md
File diff suppressed because it is too large
Load Diff
@@ -2,33 +2,36 @@
|
||||
|
||||
AdGuard Shield kann Ereignisse an Ntfy, Discord, Slack, Gotify oder einen eigenen Webhook senden. Benachrichtigungen sind optional und werden über `adguard-shield.conf` gesteuert.
|
||||
|
||||
Typische Ereignisse:
|
||||
## Unterstützte Ereignisse
|
||||
|
||||
- Service gestartet
|
||||
- Service gestoppt
|
||||
- automatische Sperre
|
||||
- manuelle Sperre
|
||||
- GeoIP-Sperre
|
||||
- externe Blocklist-Sperre, falls separat aktiviert
|
||||
- Freigabe
|
||||
- Bulk-Freigabe, zum Beispiel durch `flush`
|
||||
| Ereignis | Beschreibung |
|
||||
|---|---|
|
||||
| Service gestartet | Daemon wurde gestartet |
|
||||
| Service gestoppt | Daemon wurde gestoppt |
|
||||
| Automatische Sperre | Rate-Limit- oder Subdomain-Flood-Erkennung |
|
||||
| Watchlist-Sperre | DNS-Flood-Watchlist-Treffer (permanent) |
|
||||
| Manuelle Sperre | IP wurde manuell per `ban` gesperrt |
|
||||
| GeoIP-Sperre | Ländersperre ausgelöst (wenn `GEOIP_NOTIFY=true`) |
|
||||
| Blocklist-Sperre | Externe Blocklist (wenn `EXTERNAL_BLOCKLIST_NOTIFY=true`) |
|
||||
| Freigabe | IP wurde entsperrt (manuell, abgelaufen oder durch Whitelist) |
|
||||
| Bulk-Freigabe | `flush`, `geoip-flush` oder `blocklist-flush` |
|
||||
|
||||
## Grundkonfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="ntfy"
|
||||
NOTIFY_TYPE="ntfy" # ntfy, discord, slack, gotify oder generic
|
||||
```
|
||||
|
||||
Mögliche Typen:
|
||||
### Mögliche Typen
|
||||
|
||||
```text
|
||||
ntfy
|
||||
discord
|
||||
slack
|
||||
gotify
|
||||
generic
|
||||
```
|
||||
| Typ | Protokoll | Beschreibung |
|
||||
|---|---|---|
|
||||
| `ntfy` | HTTP POST | Push-Benachrichtigungen über ntfy.sh oder selbst gehostete Instanz |
|
||||
| `discord` | Webhook | Discord-Kanal-Webhook |
|
||||
| `slack` | Webhook | Slack Incoming Webhook |
|
||||
| `gotify` | HTTP POST | Gotify-Server mit App-Token |
|
||||
| `generic` | HTTP POST (JSON) | Eigener Webhook-Endpunkt |
|
||||
|
||||
Nach Änderungen:
|
||||
|
||||
@@ -36,12 +39,14 @@ Nach Änderungen:
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
Zum Prüfen kannst du den Service neu starten oder im Dry-Run eine Erkennung auslösen.
|
||||
---
|
||||
|
||||
## Ntfy
|
||||
|
||||
Ntfy ist der einfachste Einstieg, weil kein komplexer Webhook-Body benötigt wird.
|
||||
|
||||
### Konfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="ntfy"
|
||||
@@ -51,7 +56,7 @@ NTFY_TOKEN=""
|
||||
NTFY_PRIORITY="4"
|
||||
```
|
||||
|
||||
Eigene Ntfy-Instanz:
|
||||
### Eigene Ntfy-Instanz
|
||||
|
||||
```bash
|
||||
NTFY_SERVER_URL="https://ntfy.example.com"
|
||||
@@ -59,77 +64,91 @@ NTFY_TOPIC="dns-security"
|
||||
NTFY_TOKEN="tk_geheimer_token"
|
||||
```
|
||||
|
||||
Prioritäten:
|
||||
### Prioritäten
|
||||
|
||||
| Wert | Bedeutung |
|
||||
|---:|---|
|
||||
| `1` | Minimum |
|
||||
| `2` | Niedrig |
|
||||
| `3` | Standard |
|
||||
| `4` | Hoch |
|
||||
| `5` | Maximum |
|
||||
| Wert | Bedeutung | Beschreibung |
|
||||
|---:|---|---|
|
||||
| `1` | Minimum | Keine Benachrichtigung auf dem Gerät |
|
||||
| `2` | Niedrig | Leise Benachrichtigung |
|
||||
| `3` | Standard | Normale Benachrichtigung |
|
||||
| `4` | Hoch | Benachrichtigung mit Ton |
|
||||
| `5` | Maximum | Dringende Benachrichtigung |
|
||||
|
||||
Hinweise:
|
||||
### Hinweise
|
||||
|
||||
- Bei `NOTIFY_TYPE="ntfy"` wird `NOTIFY_WEBHOOK_URL` nicht verwendet.
|
||||
- Bei privaten Topics oder eigener Instanz ist ein Token empfehlenswert.
|
||||
- Der Topic-Name sollte nicht öffentlich erratbar sein.
|
||||
- Der Topic-Name sollte nicht öffentlich erratbar sein, um Fremdzugriff zu verhindern.
|
||||
|
||||
---
|
||||
|
||||
## Discord
|
||||
|
||||
### Konfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="discord"
|
||||
NOTIFY_WEBHOOK_URL="https://discord.com/api/webhooks/xxx/yyy"
|
||||
```
|
||||
|
||||
Webhook erstellen:
|
||||
### Webhook erstellen
|
||||
|
||||
1. Discord-Server öffnen.
|
||||
2. Servereinstellungen öffnen.
|
||||
3. Integrationen auswählen.
|
||||
4. Webhooks öffnen.
|
||||
5. Neuen Webhook erstellen.
|
||||
6. URL kopieren und in `NOTIFY_WEBHOOK_URL` eintragen.
|
||||
2. Servereinstellungen > Integrationen > Webhooks.
|
||||
3. Neuen Webhook erstellen.
|
||||
4. Gewünschten Kanal auswählen.
|
||||
5. URL kopieren und in `NOTIFY_WEBHOOK_URL` eintragen.
|
||||
|
||||
Discord erhält den Inhalt als `content`.
|
||||
Discord erhält den Inhalt als `content`-Feld im JSON-Body.
|
||||
|
||||
---
|
||||
|
||||
## Slack
|
||||
|
||||
### Konfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="slack"
|
||||
NOTIFY_WEBHOOK_URL="https://hooks.slack.com/services/xxx/yyy/zzz"
|
||||
```
|
||||
|
||||
Slack erhält den Inhalt als `text`.
|
||||
### Webhook einrichten
|
||||
|
||||
Einrichtung grob:
|
||||
|
||||
1. Slack-App mit Incoming Webhooks einrichten.
|
||||
1. Slack-App mit Incoming Webhooks erstellen oder vorhandene App verwenden.
|
||||
2. Webhook für den gewünschten Channel aktivieren.
|
||||
3. Webhook-URL in die Konfiguration kopieren.
|
||||
|
||||
Slack erhält den Inhalt als `text`-Feld im JSON-Body.
|
||||
|
||||
---
|
||||
|
||||
## Gotify
|
||||
|
||||
### Konfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="gotify"
|
||||
NOTIFY_WEBHOOK_URL="https://gotify.example.com/message?token=xxx"
|
||||
```
|
||||
|
||||
Gotify erhält `title`, `message` und `priority` als Formularwerte.
|
||||
|
||||
Token erstellen:
|
||||
### Token erstellen
|
||||
|
||||
1. Gotify-Weboberfläche öffnen.
|
||||
2. Apps auswählen.
|
||||
3. App erstellen.
|
||||
4. Token in die URL einsetzen.
|
||||
2. Apps > App erstellen.
|
||||
3. Token aus der App kopieren und in die URL einsetzen.
|
||||
|
||||
Gotify erhält `title`, `message` und `priority` als Formularwerte.
|
||||
|
||||
---
|
||||
|
||||
## Generic Webhook
|
||||
|
||||
Für eigene Automatisierung:
|
||||
Für eigene Automatisierung oder Anbindung an andere Systeme.
|
||||
|
||||
### Konfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
@@ -137,7 +156,9 @@ NOTIFY_TYPE="generic"
|
||||
NOTIFY_WEBHOOK_URL="https://example.com/adguard-shield-webhook"
|
||||
```
|
||||
|
||||
AdGuard Shield sendet einen `POST` mit JSON:
|
||||
### JSON-Payload
|
||||
|
||||
AdGuard Shield sendet einen `POST` mit folgendem JSON-Body:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -148,45 +169,36 @@ AdGuard Shield sendet einen `POST` mit JSON:
|
||||
}
|
||||
```
|
||||
|
||||
Mögliche `action`-Werte:
|
||||
### Mögliche `action`-Werte
|
||||
|
||||
| Aktion | Bedeutung |
|
||||
|---|---|
|
||||
| `ban` | Sperre |
|
||||
| `unban` | Freigabe |
|
||||
| `manual-flush` | Bulk-Freigabe |
|
||||
| `geoip-flush` | Bulk-Freigabe von GeoIP-Sperren |
|
||||
| `external-blocklist-flush` | Bulk-Freigabe externer Blocklist-Sperren |
|
||||
| `service_start` | Service gestartet |
|
||||
| `service_stop` | Service gestoppt |
|
||||
| `ban` | Sperre wurde gesetzt |
|
||||
| `unban` | Sperre wurde aufgehoben |
|
||||
| `manual-flush` | Bulk-Freigabe aller Sperren |
|
||||
| `geoip-flush` | Bulk-Freigabe aller GeoIP-Sperren |
|
||||
| `external-blocklist-flush` | Bulk-Freigabe aller externen Blocklist-Sperren |
|
||||
| `service_start` | Service wurde gestartet |
|
||||
| `service_stop` | Service wurde gestoppt |
|
||||
|
||||
## Externe Blocklist und Benachrichtigungen
|
||||
---
|
||||
|
||||
Für Sperren aus externen Blocklisten gibt es einen zusätzlichen Schalter:
|
||||
## Separate Steuerung für Module
|
||||
|
||||
### Externe Blocklist
|
||||
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=false
|
||||
```
|
||||
|
||||
Warum separat?
|
||||
**Warum separat?** Eine große Blocklist kann beim ersten Sync hunderte oder tausende IPs sperren. Wenn jede Sperre eine Nachricht erzeugt, wird der Benachrichtigungskanal unbrauchbar.
|
||||
|
||||
Eine große Blocklist kann beim ersten Sync hunderte oder tausende IPs sperren. Wenn dafür jede Sperre eine Nachricht erzeugt, wird dein Benachrichtigungskanal unbrauchbar.
|
||||
| Listengröße | Empfehlung |
|
||||
|---|---|
|
||||
| Große Listen (>100 IPs) | `EXTERNAL_BLOCKLIST_NOTIFY=false` (Standard) |
|
||||
| Kleine, kuratierte Listen (<50 IPs) | `EXTERNAL_BLOCKLIST_NOTIFY=true` möglich |
|
||||
|
||||
Empfehlung:
|
||||
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=false
|
||||
```
|
||||
|
||||
Nur bei kleinen, kuratierten Listen:
|
||||
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=true
|
||||
```
|
||||
|
||||
## GeoIP-Benachrichtigungen
|
||||
|
||||
GeoIP hat ebenfalls einen eigenen Schalter:
|
||||
### GeoIP
|
||||
|
||||
```bash
|
||||
GEOIP_NOTIFY=true
|
||||
@@ -198,6 +210,8 @@ Wenn GeoIP aktiv ist, aber keine Nachrichten für GeoIP-Sperren gesendet werden
|
||||
GEOIP_NOTIFY=false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bulk-Freigaben
|
||||
|
||||
Diese Befehle können viele IPs auf einmal freigeben:
|
||||
@@ -208,22 +222,28 @@ sudo /opt/adguard-shield/adguard-shield geoip-flush
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-flush
|
||||
```
|
||||
|
||||
AdGuard Shield sendet dafür nicht eine Nachricht pro IP, sondern eine zusammenfassende Meldung mit der Anzahl der freigegebenen Sperren.
|
||||
AdGuard Shield sendet dafür **nicht** eine Nachricht pro IP, sondern eine zusammenfassende Meldung mit der Anzahl der freigegebenen Sperren.
|
||||
|
||||
---
|
||||
|
||||
## AbuseIPDB-Hinweis in Nachrichten
|
||||
|
||||
Bei permanenten Monitor-Sperren kann AdGuard Shield zusätzlich an AbuseIPDB melden.
|
||||
|
||||
Voraussetzungen:
|
||||
**Voraussetzungen:**
|
||||
|
||||
```bash
|
||||
ABUSEIPDB_ENABLED=true
|
||||
ABUSEIPDB_API_KEY="..."
|
||||
```
|
||||
|
||||
Wenn eine Meldung ausgelöst wurde, enthält die Ban-Nachricht einen entsprechenden Hinweis. Außerdem enthält jede Ban- und Unban-Nachricht einen Link zur AbuseIPDB-Check-Seite der IP.
|
||||
**Verhalten:**
|
||||
|
||||
AbuseIPDB wird nicht für GeoIP- oder externe Blocklist-Sperren verwendet.
|
||||
- Wenn eine AbuseIPDB-Meldung ausgelöst wurde, enthält die Ban-Nachricht einen entsprechenden Hinweis.
|
||||
- Jede Ban- und Unban-Nachricht enthält einen Link zur AbuseIPDB-Check-Seite der IP.
|
||||
- AbuseIPDB wird nicht für GeoIP- oder externe Blocklist-Sperren verwendet.
|
||||
|
||||
---
|
||||
|
||||
## Beispielinhalte
|
||||
|
||||
@@ -299,6 +319,8 @@ Freigegebene IPs: 28
|
||||
Aktion: Manual-Flush
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fehlersuche
|
||||
|
||||
Wenn keine Benachrichtigung ankommt:
|
||||
@@ -308,17 +330,24 @@ sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
```
|
||||
|
||||
Prüfe:
|
||||
### Checkliste
|
||||
|
||||
- `NOTIFY_ENABLED=true`
|
||||
- `NOTIFY_TYPE` korrekt geschrieben
|
||||
- Ziel-URL oder Ntfy-Topic gesetzt
|
||||
- Token gültig
|
||||
- Server kann den Webhook erreichen
|
||||
- Firewall des Servers blockiert ausgehende HTTPS-Verbindungen nicht
|
||||
| Prüfpunkt | Was zu prüfen ist |
|
||||
|---|---|
|
||||
| Aktiviert | `NOTIFY_ENABLED=true` gesetzt? |
|
||||
| Typ | `NOTIFY_TYPE` korrekt geschrieben? |
|
||||
| Ziel | Webhook-URL oder Ntfy-Topic gesetzt? |
|
||||
| Token | Token gültig und nicht abgelaufen? |
|
||||
| Netzwerk | Server kann ausgehende HTTPS-Verbindungen aufbauen? |
|
||||
| Firewall | Keine Firewall blockiert ausgehende Verbindungen? |
|
||||
| Modul-Schalter | `EXTERNAL_BLOCKLIST_NOTIFY` oder `GEOIP_NOTIFY` separat deaktiviert? |
|
||||
|
||||
Bei `generic` kannst du testweise einen lokalen HTTP-Empfänger oder einen Request-Inspector verwenden.
|
||||
Bei `generic` kannst du testweise einen lokalen HTTP-Empfänger oder einen Request-Inspector verwenden, um den gesendeten Payload zu sehen.
|
||||
|
||||
---
|
||||
|
||||
## Datenschutz
|
||||
|
||||
Benachrichtigungen können IP-Adressen, Domainnamen und Hostnamen enthalten. Sende sie nur an Dienste, denen du vertraust. Für öffentliche oder geteilte Kanäle ist Ntfy mit privatem Topic oder eine eigene Ntfy/Gotify-Instanz oft die bessere Wahl.
|
||||
Benachrichtigungen können IP-Adressen, Domainnamen und Hostnamen enthalten. Sende sie nur an Dienste, denen du vertraust.
|
||||
|
||||
Für öffentliche oder geteilte Kanäle ist eine eigene Ntfy- oder Gotify-Instanz mit privatem Topic oft die bessere Wahl als ein öffentlicher Kanal.
|
||||
|
||||
144
docs/docker.md
144
docs/docker.md
@@ -1,52 +1,160 @@
|
||||
# Docker-Installationen
|
||||
|
||||
AdGuard Shield liest weiterhin das Querylog von AdGuard Home. Der Unterschied zwischen klassisch und Docker betrifft nur die Stelle, an der die Firewall eine gesperrte Client-IP abfangen muss.
|
||||
AdGuard Shield läuft auf dem Host und liest weiterhin das Querylog von AdGuard Home über die API. Der Unterschied zwischen klassischer Installation und Docker-Setup betrifft nur die Stelle, an der die Firewall eine gesperrte Client-IP abfangen muss.
|
||||
|
||||
## Modus wählen
|
||||
|
||||
| Installation | Einstellung |
|
||||
|---|---|
|
||||
| AdGuard Home direkt auf dem Host | `FIREWALL_MODE="host"` |
|
||||
| Docker mit `network_mode: host` | `FIREWALL_MODE="docker-host"` |
|
||||
| Docker Bridge mit veröffentlichten Ports | `FIREWALL_MODE="docker-bridge"` |
|
||||
| gemischtes Setup oder Migration | `FIREWALL_MODE="hybrid"` |
|
||||
Die Wahl des Firewall-Modus hängt davon ab, wie AdGuard Home betrieben wird:
|
||||
|
||||
`docker-host` verhält sich technisch wie `host`: Die DNS-Pakete landen in der Host-`INPUT`-Chain.
|
||||
| Installation | Einstellung | Parent-Chain |
|
||||
|---|---|---|
|
||||
| AdGuard Home direkt auf dem Host | `FIREWALL_MODE="host"` | `INPUT` |
|
||||
| Docker mit `network_mode: host` | `FIREWALL_MODE="docker-host"` | `INPUT` |
|
||||
| Docker Bridge mit veröffentlichten Ports | `FIREWALL_MODE="docker-bridge"` | `DOCKER-USER` |
|
||||
| Gemischtes Setup oder Migration | `FIREWALL_MODE="hybrid"` | `INPUT` + `DOCKER-USER` |
|
||||
|
||||
Bei Docker Bridge mit `ports:` oder `-p` landen veröffentlichte Ports nach Dockers NAT-Regeln im Forwarding-Pfad. Deshalb nutzt AdGuard Shield dort `DOCKER-USER`. Diese Chain ist genau für eigene Admin-Regeln vor Dockers Container-Regeln vorgesehen.
|
||||
### Warum verschiedene Modi?
|
||||
|
||||
## Beispiele
|
||||
**Host und Docker Host Network:** DNS-Pakete landen direkt in der `INPUT`-Chain des Hosts. Die Firewall-Regeln werden dort eingehängt.
|
||||
|
||||
Klassisch oder Docker Host Network:
|
||||
**Docker Bridge mit Port-Publishing:** Docker veröffentlicht Ports über NAT (DNAT). Die Pakete durchlaufen nach dem DNAT die `FORWARD`-Chain, nicht die `INPUT`-Chain. Docker stellt dafür die Chain `DOCKER-USER` bereit, die genau für eigene Admin-Regeln vor Dockers Container-Regeln vorgesehen ist.
|
||||
|
||||
**Hybrid:** Hängt Regeln in beide Chains ein. Nützlich bei Migrationen oder wenn unklar ist, welcher Weg die Pakete nehmen.
|
||||
|
||||
---
|
||||
|
||||
## Konfigurationsbeispiele
|
||||
|
||||
### Klassisch oder Docker Host Network
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="host"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
Docker Bridge mit Port-Publishing:
|
||||
`docker-host` verhält sich technisch identisch zu `host`:
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="docker-host"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
### Docker Bridge mit Port-Publishing
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="docker-bridge"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
Unklarer Übergangszustand:
|
||||
### Unklarer Übergangszustand
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="hybrid"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Regelstruktur nach Modus
|
||||
|
||||
### Host / Docker Host Network
|
||||
|
||||
```text
|
||||
INPUT
|
||||
├── tcp/53 → ADGUARD_SHIELD
|
||||
├── udp/53 → ADGUARD_SHIELD
|
||||
├── tcp/443 → ADGUARD_SHIELD
|
||||
├── udp/443 → ADGUARD_SHIELD
|
||||
├── tcp/853 → ADGUARD_SHIELD
|
||||
└── udp/853 → ADGUARD_SHIELD
|
||||
|
||||
ADGUARD_SHIELD
|
||||
├── src in adguard_shield_v4 → DROP
|
||||
└── src in adguard_shield_v6 → DROP
|
||||
```
|
||||
|
||||
### Docker Bridge
|
||||
|
||||
```text
|
||||
DOCKER-USER
|
||||
├── tcp/53 → ADGUARD_SHIELD
|
||||
├── udp/53 → ADGUARD_SHIELD
|
||||
├── tcp/443 → ADGUARD_SHIELD
|
||||
├── udp/443 → ADGUARD_SHIELD
|
||||
├── tcp/853 → ADGUARD_SHIELD
|
||||
└── udp/853 → ADGUARD_SHIELD
|
||||
|
||||
ADGUARD_SHIELD
|
||||
├── src in adguard_shield_v4 → DROP
|
||||
└── src in adguard_shield_v6 → DROP
|
||||
```
|
||||
|
||||
### Hybrid
|
||||
|
||||
Beide Strukturen gleichzeitig: `INPUT` und `DOCKER-USER` springen in `ADGUARD_SHIELD`.
|
||||
|
||||
---
|
||||
|
||||
## Wichtige Details
|
||||
|
||||
- `docker-bridge` benötigt eine vorhandene IPv4-Chain `DOCKER-USER`. Wenn Docker nicht läuft oder iptables für Docker deaktiviert ist, meldet `firewall-create` einen Fehler.
|
||||
- IPv6 über Docker wird nur eingehängt, wenn Docker auch eine `ip6tables`-Chain `DOCKER-USER` angelegt hat. Fehlt sie, wird IPv4 trotzdem geschützt.
|
||||
- In `DOCKER-USER` wird nach Dockers DNAT gematcht. Wenn du ungewöhnliche Port-Mappings nutzt, sollten `BLOCKED_PORTS` die Container-Zielports enthalten.
|
||||
- `hybrid` ist praktisch für Migrationen, kann aber mehr Verkehr treffen, weil sowohl Host-Ports als auch Docker-Forwarding geprüft werden.
|
||||
| Thema | Beschreibung |
|
||||
|---|---|
|
||||
| **DOCKER-USER Chain** | `docker-bridge` benötigt eine vorhandene IPv4-Chain `DOCKER-USER`. Wenn Docker nicht läuft oder iptables für Docker deaktiviert ist, meldet `firewall-create` einen Fehler. |
|
||||
| **IPv6 in Docker** | IPv6 über Docker wird nur eingehängt, wenn Docker auch eine `ip6tables`-Chain `DOCKER-USER` angelegt hat. Fehlt sie, wird IPv4 trotzdem geschützt. |
|
||||
| **Port-Mapping** | In `DOCKER-USER` wird nach Dockers DNAT gematcht. Bei ungewöhnlichen Port-Mappings sollten `BLOCKED_PORTS` die Container-Zielports enthalten (nicht die Host-Ports). |
|
||||
| **Hybrid-Warnung** | `hybrid` kann mehr Verkehr treffen, weil sowohl Host-Ports als auch Docker-Forwarding geprüft werden. Nur bei Migrationen oder unklaren Setups verwenden. |
|
||||
| **API-URL** | Die `ADGUARD_URL` muss vom Host aus erreichbar sein. Bei Docker Bridge ist das oft `http://127.0.0.1:<host-port>`. |
|
||||
|
||||
Nach einer Änderung:
|
||||
---
|
||||
|
||||
## Typisches Docker-Bridge-Setup
|
||||
|
||||
### docker-compose.yml (AdGuard Home)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
adguardhome:
|
||||
image: adguard/adguardhome
|
||||
ports:
|
||||
- "53:53/tcp"
|
||||
- "53:53/udp"
|
||||
- "443:443/tcp"
|
||||
- "853:853/tcp"
|
||||
- "3000:3000/tcp"
|
||||
volumes:
|
||||
- ./data:/opt/adguardhome/work
|
||||
- ./conf:/opt/adguardhome/conf
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### adguard-shield.conf
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="http://127.0.0.1:3000"
|
||||
ADGUARD_USER="admin"
|
||||
ADGUARD_PASS="geheim"
|
||||
FIREWALL_MODE="docker-bridge"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Nach einer Änderung prüfen
|
||||
|
||||
```bash
|
||||
sudo systemctl restart adguard-shield
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-status
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
```
|
||||
|
||||
## Firewall neu aufbauen
|
||||
|
||||
Falls der Modus gewechselt wurde:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-remove
|
||||
sudo systemctl restart adguard-shield
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-status
|
||||
```
|
||||
|
||||
Der Daemon erstellt die Firewall-Struktur beim Start automatisch neu und überträgt aktive Sperren aus SQLite.
|
||||
|
||||
@@ -16,7 +16,7 @@ RATE_LIMIT_MAX_REQUESTS=30
|
||||
WHITELIST="127.0.0.1,::1,192.168.1.1"
|
||||
```
|
||||
|
||||
Nach Änderungen solltest du den Service neu starten:
|
||||
Nach Änderungen muss der Service neu gestartet werden:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart adguard-shield
|
||||
@@ -41,21 +41,24 @@ Das ist besonders wichtig beim Umstieg von der Shell-Version auf die Go-Version.
|
||||
Nach dem Bearbeiten der Konfiguration:
|
||||
|
||||
```bash
|
||||
# API-Verbindung testen
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
|
||||
# Dry-Run: zeigt, was gesperrt würde, ohne die Firewall zu verändern
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
```
|
||||
|
||||
`test` prüft die AdGuard-Home-API. `dry-run` zeigt, was AdGuard Shield sperren würde, ohne die Firewall zu verändern.
|
||||
---
|
||||
|
||||
## 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 |
|
||||
| `ADGUARD_PASS` | `changeme` | Passwort für die API |
|
||||
| `ADGUARD_USER` | `admin` | Benutzername für die API-Authentifizierung |
|
||||
| `ADGUARD_PASS` | `changeme` | Passwort für die API-Authentifizierung |
|
||||
|
||||
Beispiel lokal:
|
||||
### Beispiel: Lokale Instanz
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="http://127.0.0.1:3000"
|
||||
@@ -63,10 +66,12 @@ ADGUARD_USER="admin"
|
||||
ADGUARD_PASS="sehr-geheim"
|
||||
```
|
||||
|
||||
Beispiel mit HTTPS:
|
||||
### Beispiel: Entfernte Instanz mit HTTPS
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="https://dns.example.com"
|
||||
ADGUARD_USER="admin"
|
||||
ADGUARD_PASS="geheim"
|
||||
```
|
||||
|
||||
AdGuard Shield ruft intern diesen Endpunkt ab:
|
||||
@@ -75,54 +80,55 @@ AdGuard Shield ruft intern diesen Endpunkt ab:
|
||||
/control/querylog?limit=<API_QUERY_LIMIT>&response_status=all
|
||||
```
|
||||
|
||||
Hinweis: Der HTTP-Client akzeptiert auch selbstsignierte TLS-Zertifikate. Das erleichtert lokale Setups, ersetzt aber keine saubere Absicherung der AdGuard-Home-Oberfläche.
|
||||
**Hinweis:** Der HTTP-Client akzeptiert auch selbstsignierte TLS-Zertifikate. Das erleichtert lokale Setups, ersetzt aber keine saubere Absicherung der AdGuard-Home-Oberfläche.
|
||||
|
||||
---
|
||||
|
||||
## Querylog und Polling
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---:|---|
|
||||
| `CHECK_INTERVAL` | `10` | Abstand zwischen Querylog-Abfragen in Sekunden |
|
||||
| `API_QUERY_LIMIT` | `500` | Anzahl der Querylog-Einträge pro API-Abfrage |
|
||||
| `API_QUERY_LIMIT` | `500` | Anzahl der Querylog-Einträge pro API-Abfrage (max. 5000) |
|
||||
|
||||
Empfehlung:
|
||||
### Empfehlungen
|
||||
|
||||
- `CHECK_INTERVAL=10` ist ein guter Standard.
|
||||
- Bei sehr hohem DNS-Aufkommen kann `API_QUERY_LIMIT` erhöht werden.
|
||||
- Wenn `API_QUERY_LIMIT` zu niedrig ist, können Spitzen im Querylog zwischen zwei Polls teilweise verpasst werden.
|
||||
- Sehr kurze Intervalle erzeugen mehr API-Last auf AdGuard Home.
|
||||
| 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 | Spitzen im Querylog können zwischen zwei Polls verpasst werden |
|
||||
| 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_MAX_REQUESTS` | `30` | Maximale Anfragen pro Client und Domain im Zeitfenster |
|
||||
| `RATE_LIMIT_WINDOW` | `60` | Zeitfenster in Sekunden |
|
||||
|
||||
Beispiel:
|
||||
Das bedeutet: Wenn ein Client dieselbe Domain mehr als 30-mal innerhalb von 60 Sekunden abfragt, wird er als auffällig erkannt und gesperrt.
|
||||
|
||||
```bash
|
||||
RATE_LIMIT_MAX_REQUESTS=30
|
||||
RATE_LIMIT_WINDOW=60
|
||||
```
|
||||
### Empfohlene Startwerte
|
||||
|
||||
Das bedeutet: Wenn ein Client dieselbe Domain mehr als 30-mal innerhalb von 60 Sekunden abfragt, wird er auffällig.
|
||||
| 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 |
|
||||
|
||||
Gute Startwerte:
|
||||
**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.
|
||||
|
||||
| Umgebung | Vorschlag |
|
||||
|---|---|
|
||||
| kleines Heimnetz | `30` in `60s` |
|
||||
| viele Clients | `60` bis `120` in `60s` |
|
||||
| sehr aktive Resolver/Forwarder | zuerst Whitelist prüfen, dann höher setzen |
|
||||
|
||||
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.
|
||||
---
|
||||
|
||||
## Subdomain-Flood-Erkennung
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---:|---|
|
||||
| `SUBDOMAIN_FLOOD_ENABLED` | `true` | aktiviert die Erkennung zufälliger Subdomains |
|
||||
| `SUBDOMAIN_FLOOD_MAX_UNIQUE` | `50` | maximale Anzahl eindeutiger Subdomains pro Client und Basisdomain |
|
||||
| `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:
|
||||
@@ -133,148 +139,154 @@ f8x9.example.com
|
||||
zz12.example.com
|
||||
```
|
||||
|
||||
Dabei zählt AdGuard Shield nicht die Gesamtzahl der Anfragen, sondern die Anzahl unterschiedlicher Subdomains unter derselben Basisdomain.
|
||||
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.
|
||||
|
||||
Beispiel:
|
||||
### Hinweise
|
||||
|
||||
```bash
|
||||
SUBDOMAIN_FLOOD_ENABLED=true
|
||||
SUBDOMAIN_FLOOD_MAX_UNIQUE=50
|
||||
SUBDOMAIN_FLOOD_WINDOW=60
|
||||
```
|
||||
- Multi-Part-TLDs wie `.co.uk` werden korrekt als Basisdomain erkannt.
|
||||
- CDNs und manche Apps nutzen legitim viele Subdomains. Betroffene Clients whitelisten oder Grenzwert erhöhen.
|
||||
|
||||
Wenn ein Client innerhalb von 60 Sekunden mehr als 50 unterschiedliche Subdomains von `example.com` abfragt, wird er gesperrt.
|
||||
|
||||
Hinweise:
|
||||
|
||||
- Direkte Anfragen an `example.com` zählen hier nicht.
|
||||
- Multi-Part-TLDs wie `.co.uk` werden berücksichtigt.
|
||||
- CDNs und manche Apps nutzen viele Subdomains. Wenn legitime Clients betroffen sind, den Grenzwert erhöhen oder passende Clients whitelisten.
|
||||
---
|
||||
|
||||
## DNS-Flood-Watchlist
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `DNS_FLOOD_WATCHLIST_ENABLED` | `false` | aktiviert die Watchlist |
|
||||
| `DNS_FLOOD_WATCHLIST` | leer | kommagetrennte Domainliste |
|
||||
| `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.
|
||||
Die Watchlist ist für Domains gedacht, bei denen eine Überschreitung sofort hart behandelt werden soll, ohne progressive Stufen.
|
||||
|
||||
Beispiel:
|
||||
### Beispiel
|
||||
|
||||
```bash
|
||||
DNS_FLOOD_WATCHLIST_ENABLED=true
|
||||
DNS_FLOOD_WATCHLIST="microsoft.com,google.com,apple.com"
|
||||
```
|
||||
|
||||
Wenn ein Client dann `login.microsoft.com` über das Rate-Limit bringt, wird sofort permanent gesperrt, weil `login.microsoft.com` zur Watchlist-Domain `microsoft.com` gehört.
|
||||
### Matching-Logik
|
||||
|
||||
Folgen:
|
||||
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.
|
||||
|
||||
- Grund: `dns-flood-watchlist`
|
||||
- Sperrdauer: permanent
|
||||
- Progressive-Ban-Dauer wird übersprungen
|
||||
- AbuseIPDB-Reporting kann ausgelöst werden, wenn aktiviert
|
||||
### 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 |
|
||||
| `BAN_DURATION` | `3600` | Basisdauer temporärer Monitor-Sperren in Sekunden (1 Stunde) |
|
||||
| `IPTABLES_CHAIN` | `ADGUARD_SHIELD` | Name der eigenen Firewall-Chain |
|
||||
| `BLOCKED_PORTS` | `53 443 853` | Ports, die für gesperrte Clients blockiert werden |
|
||||
| `FIREWALL_BACKEND` | `ipset` | Firewall-Backend der Go-Version |
|
||||
| `BLOCKED_PORTS` | `53 443 853` | Ports, die für gesperrte Clients blockiert werden (Leerzeichen-getrennt) |
|
||||
| `FIREWALL_BACKEND` | `ipset` | Firewall-Backend (ipset + iptables) |
|
||||
| `FIREWALL_MODE` | `host` | Verkehrsweg der AdGuard-Home-Installation |
|
||||
| `DRY_RUN` | `false` | Konfigurationsweiter Testmodus ohne echte Sperren |
|
||||
|
||||
Standardports:
|
||||
### Blockierte Ports
|
||||
|
||||
| Port | Zweck |
|
||||
|---:|---|
|
||||
| `53` | klassisches DNS über UDP/TCP |
|
||||
| `443` | DNS-over-HTTPS, sofern AdGuard Home darüber erreichbar ist |
|
||||
| `853` | DNS-over-TLS und DNS-over-QUIC |
|
||||
| `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) |
|
||||
|
||||
Die Firewall wird über `ipset` und `iptables`/`ip6tables` gesteuert. Für IPv4 und IPv6 gibt es getrennte Sets:
|
||||
### Firewall-Modi
|
||||
|
||||
```text
|
||||
adguard_shield_v4
|
||||
adguard_shield_v6
|
||||
```
|
||||
| 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` |
|
||||
|
||||
`FIREWALL_MODE` legt fest, in welche Host-Chain AdGuard Shield die Schutzregeln einhängt:
|
||||
Details zu den Docker-Modi stehen in [Docker-Installationen](docker.md).
|
||||
|
||||
| Modus | Einsatz |
|
||||
|---|---|
|
||||
| `host` | klassische AdGuard-Home-Installation direkt auf dem Host |
|
||||
| `docker-host` | AdGuard Home läuft in Docker mit `network_mode: host`; Alias von `host` |
|
||||
| `docker-bridge` | AdGuard Home läuft in Docker mit veröffentlichten Ports, z.B. `53:53` |
|
||||
| `hybrid` | schützt Host-Ports und Docker-Forwarding gleichzeitig |
|
||||
|
||||
Bei `host`/`docker-host` wird die eigene Chain aus `INPUT` angesprungen. Bei `docker-bridge` wird sie aus `DOCKER-USER` angesprungen, weil Docker veröffentlichte Ports über NAT und `FORWARD` verarbeitet. Details stehen in [Docker-Installationen](docker.md).
|
||||
---
|
||||
|
||||
## Whitelist
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `WHITELIST` | `127.0.0.1,::1` | IPs, die nie gesperrt werden |
|
||||
| `WHITELIST` | `127.0.0.1,::1` | IPs, die nie gesperrt werden (kommagetrennt) |
|
||||
|
||||
Beispiel:
|
||||
### Beispiel
|
||||
|
||||
```bash
|
||||
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.10,fd00::1"
|
||||
```
|
||||
|
||||
Empfohlen sind:
|
||||
### Empfohlene Whitelist-Einträge
|
||||
|
||||
- Localhost: `127.0.0.1`, `::1`
|
||||
- Router/Gateway
|
||||
- Admin- oder Management-IPs
|
||||
- Monitoring-Systeme
|
||||
- interne Resolver oder Forwarder
|
||||
- eigene VPN-Endpunkte, falls sie viele Anfragen bündeln
|
||||
| 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.
|
||||
**Wichtig:** Die Whitelist wird vor jeder Sperre geprüft. Das gilt für automatische, manuelle, GeoIP- und externe Blocklist-Sperren.
|
||||
|
||||
---
|
||||
|
||||
## Progressive Sperren
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---:|---|
|
||||
| `PROGRESSIVE_BAN_ENABLED` | `true` | Wiederholungstäter stufenweise länger sperren |
|
||||
| `PROGRESSIVE_BAN_MULTIPLIER` | `2` | Multiplikator pro Stufe |
|
||||
| `PROGRESSIVE_BAN_MAX_LEVEL` | `5` | ab dieser Stufe permanent sperren, `0` bedeutet nie permanent durch Stufe |
|
||||
| `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 |
|
||||
|
||||
Beispiel mit Standardwerten:
|
||||
### Stufenverlauf mit Standardwerten
|
||||
|
||||
| Vergehen | Stufe | Dauer |
|
||||
|---:|---:|---|
|
||||
| 1 | 1 | 1 Stunde |
|
||||
| 2 | 2 | 2 Stunden |
|
||||
| 3 | 3 | 4 Stunden |
|
||||
| 4 | 4 | 8 Stunden |
|
||||
| 5 | 5 | permanent |
|
||||
| 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.
|
||||
|
||||
Wartung:
|
||||
### Verwaltungsbefehle
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield offense-status
|
||||
sudo /opt/adguard-shield/adguard-shield offense-cleanup
|
||||
sudo /opt/adguard-shield/adguard-shield reset-offenses 192.168.1.100
|
||||
sudo /opt/adguard-shield/adguard-shield offense-status # Zähler anzeigen
|
||||
sudo /opt/adguard-shield/adguard-shield offense-cleanup # Abgelaufene entfernen
|
||||
sudo /opt/adguard-shield/adguard-shield reset-offenses # Alle zurücksetzen
|
||||
sudo /opt/adguard-shield/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` | `DEBUG`, `INFO`, `WARN` oder `ERROR` |
|
||||
| `LOG_LEVEL` | `INFO` | Minimales Log-Level |
|
||||
|
||||
`LOG_FILE` enthält Start/Stop, Worker-Läufe, Sperren, Freigaben, Warnungen und Fehler. Query-Inhalte werden nicht dauerhaft ins Log geschrieben.
|
||||
### Verfügbare Log-Level
|
||||
|
||||
CLI:
|
||||
| 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
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
@@ -282,7 +294,9 @@ sudo /opt/adguard-shield/adguard-shield logs-follow debug
|
||||
sudo /opt/adguard-shield/adguard-shield live
|
||||
```
|
||||
|
||||
Für produktiven Betrieb ist `INFO` sinnvoll. Für Fehlersuche kurzzeitig `DEBUG` verwenden.
|
||||
**Hinweis:** Query-Inhalte werden nicht dauerhaft ins Log geschrieben. Für Query-nahe Diagnose ist die Live-Ansicht gedacht.
|
||||
|
||||
---
|
||||
|
||||
## State und Runtime
|
||||
|
||||
@@ -291,31 +305,49 @@ Für produktiven Betrieb ist `INFO` sinnvoll. Für Fehlersuche kurzzeitig `DEBUG
|
||||
| `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 |
|
||||
|
||||
SQLite-Datei:
|
||||
### SQLite-Datei
|
||||
|
||||
```text
|
||||
${STATE_DIR}/adguard-shield.db
|
||||
```
|
||||
|
||||
Weitere Dateien in `STATE_DIR`:
|
||||
### Weitere Dateien in STATE_DIR
|
||||
|
||||
- Caches für externe Listen
|
||||
- gespeicherte Firewall-Regeln bei `firewall-save`
|
||||
- SQLite-WAL-Dateien
|
||||
| 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` | `ntfy`, `discord`, `slack`, `gotify` oder `generic` |
|
||||
| `NOTIFY_WEBHOOK_URL` | leer | Webhook-URL für Discord, Slack, Gotify oder Generic |
|
||||
| `NOTIFY_TYPE` | `ntfy` | Benachrichtigungskanal |
|
||||
| `NOTIFY_WEBHOOK_URL` | leer | Webhook-URL (nicht für ntfy) |
|
||||
| `NTFY_SERVER_URL` | `https://ntfy.sh` | Ntfy-Server |
|
||||
| `NTFY_TOPIC` | leer | Ntfy-Topic |
|
||||
| `NTFY_TOKEN` | leer | optionaler Access-Token |
|
||||
| `NTFY_PRIORITY` | `4` | Ntfy-Priorität von 1 bis 5 |
|
||||
| `NTFY_TOKEN` | leer | Optionaler Ntfy-Access-Token |
|
||||
| `NTFY_PRIORITY` | `4` | Ntfy-Priorität (1–5) |
|
||||
|
||||
Ntfy-Beispiel:
|
||||
### 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
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
@@ -325,7 +357,7 @@ NTFY_TOPIC="mein-adguard-shield"
|
||||
NTFY_PRIORITY="4"
|
||||
```
|
||||
|
||||
Discord-Beispiel:
|
||||
### Beispiel: Discord
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
@@ -333,22 +365,40 @@ NOTIFY_TYPE="discord"
|
||||
NOTIFY_WEBHOOK_URL="https://discord.com/api/webhooks/..."
|
||||
```
|
||||
|
||||
Details stehen in [Benachrichtigungen](benachrichtigungen.md).
|
||||
Details zu allen Kanälen stehen in [Benachrichtigungen](benachrichtigungen.md).
|
||||
|
||||
---
|
||||
|
||||
## E-Mail-Reports
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `REPORT_ENABLED` | `false` | Report-Funktion logisch aktivieren |
|
||||
| `REPORT_INTERVAL` | `weekly` | `daily`, `weekly`, `biweekly` oder `monthly` |
|
||||
| `REPORT_INTERVAL` | `weekly` | Versandintervall |
|
||||
| `REPORT_TIME` | `08:00` | Versandzeit im Format `HH:MM` |
|
||||
| `REPORT_EMAIL_TO` | `admin@example.com` | Empfänger |
|
||||
| `REPORT_EMAIL_FROM` | `adguard-shield@example.com` | Absender |
|
||||
| `REPORT_FORMAT` | `html` | `html` oder `txt` |
|
||||
| `REPORT_MAIL_CMD` | `msmtp` | Mailprogramm |
|
||||
| `REPORT_BUSIEST_DAY_RANGE` | `30` | Zeitraum in Tagen für "Aktivster Tag"; aktuell als Kompatibilitätsparameter vorhanden |
|
||||
| `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" (Kompatibilitätsparameter) |
|
||||
|
||||
Beispiel:
|
||||
### Verfügbare Intervalle
|
||||
|
||||
| Intervall | Versand |
|
||||
|---|---|
|
||||
| `daily` | Täglich zur konfigurierten Uhrzeit |
|
||||
| `weekly` | Montags zur konfigurierten Uhrzeit |
|
||||
| `biweekly` | Am 1. und 15. des Monats |
|
||||
| `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
|
||||
|
||||
```bash
|
||||
REPORT_ENABLED=true
|
||||
@@ -360,7 +410,7 @@ REPORT_FORMAT="html"
|
||||
REPORT_MAIL_CMD="msmtp"
|
||||
```
|
||||
|
||||
Cron installieren:
|
||||
### Cron-Job installieren
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-install
|
||||
@@ -368,16 +418,18 @@ sudo /opt/adguard-shield/adguard-shield report-install
|
||||
|
||||
Details stehen in [E-Mail Report](report.md).
|
||||
|
||||
---
|
||||
|
||||
## Externe Whitelist
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `EXTERNAL_WHITELIST_ENABLED` | `false` | externe Whitelist aktivieren |
|
||||
| `EXTERNAL_WHITELIST_URLS` | leer | kommagetrennte URLs |
|
||||
| `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:
|
||||
### Beispiel
|
||||
|
||||
```bash
|
||||
EXTERNAL_WHITELIST_ENABLED=true
|
||||
@@ -385,51 +437,47 @@ EXTERNAL_WHITELIST_URLS="https://example.com/trusted.txt"
|
||||
EXTERNAL_WHITELIST_INTERVAL=300
|
||||
```
|
||||
|
||||
Listenformat:
|
||||
### Listenformat
|
||||
|
||||
```text
|
||||
# Hostnamen werden regelmäßig aufgelöst
|
||||
# Hostnamen werden regelmäßig per DNS aufgelöst
|
||||
mein-router.dyndns.org
|
||||
vpn.example.com
|
||||
|
||||
# IPs und Netze
|
||||
# IPs und Netze direkt
|
||||
192.168.1.10
|
||||
10.0.0.0/24
|
||||
2001:db8::1
|
||||
```
|
||||
|
||||
Mehrere Listen:
|
||||
### Mehrere Listen
|
||||
|
||||
```bash
|
||||
EXTERNAL_WHITELIST_URLS="https://example.com/a.txt,https://example.net/b.txt"
|
||||
```
|
||||
|
||||
Verhalten:
|
||||
### Verhalten
|
||||
|
||||
- Hostnamen werden per DNS aufgelöst.
|
||||
- Aufgelöste IPs landen in SQLite.
|
||||
- Bereits aktive Sperren werden aufgehoben, wenn die IP später in der Whitelist auftaucht.
|
||||
- Kommentare und Inline-Kommentare werden unterstützt.
|
||||
- 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.
|
||||
- Kommentare (`#`) und Inline-Kommentare werden unterstützt.
|
||||
|
||||
Manuell synchronisieren:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield whitelist-sync
|
||||
```
|
||||
---
|
||||
|
||||
## Externe Blocklist
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `EXTERNAL_BLOCKLIST_ENABLED` | `false` | externe Blocklist aktivieren |
|
||||
| `EXTERNAL_BLOCKLIST_URLS` | leer | kommagetrennte URLs |
|
||||
| `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 |
|
||||
| `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:
|
||||
### Beispiel
|
||||
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_ENABLED=true
|
||||
@@ -440,26 +488,7 @@ EXTERNAL_BLOCKLIST_AUTO_UNBAN=true
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=false
|
||||
```
|
||||
|
||||
Listenformat:
|
||||
|
||||
```text
|
||||
# IPv4
|
||||
203.0.113.50
|
||||
198.51.100.0/24
|
||||
|
||||
# IPv6
|
||||
2001:db8::dead:beef
|
||||
2001:db8::/32
|
||||
|
||||
# Hostnamen
|
||||
bad-actor.example.com
|
||||
|
||||
# Hosts-Datei-Format wird erkannt
|
||||
0.0.0.0 malware.example.net
|
||||
127.0.0.1 tracker.example.org
|
||||
```
|
||||
|
||||
Unterstützt:
|
||||
### Unterstützte Listenformate
|
||||
|
||||
| Format | Beispiel |
|
||||
|---|---|
|
||||
@@ -472,42 +501,38 @@ Unterstützt:
|
||||
| Kommentar | `# Text` |
|
||||
| Inline-Kommentar | `203.0.113.50 # Grund` |
|
||||
|
||||
Nicht sinnvoll und wird übersprungen:
|
||||
### 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
|
||||
- Nicht auflösbare Hostnamen
|
||||
- Blocking-Antworten wie `0.0.0.0` oder `::`
|
||||
|
||||
Hinweise:
|
||||
### Hinweise
|
||||
|
||||
- Große Listen können viele Sperren erzeugen. `EXTERNAL_BLOCKLIST_NOTIFY=false` ist deshalb der sichere Standard.
|
||||
- Wenn ein Hostname mehrere IPs liefert, werden alle aufgelösten IPs verarbeitet.
|
||||
- Hostnamen mit mehreren IPs: Alle aufgelösten IPs werden verarbeitet.
|
||||
- IPs aus der Whitelist werden nicht gesperrt.
|
||||
- Bei `EXTERNAL_BLOCKLIST_AUTO_UNBAN=true` werden entfernte Einträge wieder freigegeben.
|
||||
- Bei `EXTERNAL_BLOCKLIST_AUTO_UNBAN=true` werden entfernte Einträge automatisch wieder freigegeben.
|
||||
|
||||
Manuell synchronisieren:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-sync
|
||||
```
|
||||
|
||||
Dateiformat-Empfehlungen:
|
||||
### Dateiformat-Empfehlungen
|
||||
|
||||
- UTF-8 ohne BOM
|
||||
- Unix-Zeilenenden `LF`
|
||||
- Unix-Zeilenenden (`LF`)
|
||||
- IP-Listen und Hostname-Listen möglichst getrennt pflegen
|
||||
|
||||
---
|
||||
|
||||
## AbuseIPDB
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `ABUSEIPDB_ENABLED` | `false` | AbuseIPDB-Reporting aktivieren |
|
||||
| `ABUSEIPDB_API_KEY` | leer | API-Key |
|
||||
| `ABUSEIPDB_CATEGORIES` | `4` | Kategorien, kommagetrennt möglich |
|
||||
| `ABUSEIPDB_API_KEY` | leer | API-Key von abuseipdb.com |
|
||||
| `ABUSEIPDB_CATEGORIES` | `4` | Kategorien, kommagetrennt (siehe [abuseipdb.com/categories](https://www.abuseipdb.com/categories)) |
|
||||
|
||||
Beispiel:
|
||||
### Beispiel
|
||||
|
||||
```bash
|
||||
ABUSEIPDB_ENABLED=true
|
||||
@@ -515,33 +540,55 @@ ABUSEIPDB_API_KEY="dein-api-key"
|
||||
ABUSEIPDB_CATEGORIES="4"
|
||||
```
|
||||
|
||||
Gemeldet werden nur permanente Monitor-Sperren:
|
||||
### Was gemeldet wird
|
||||
|
||||
- Watchlist-Treffer
|
||||
- Progressive-Ban-Sperren auf Maximalstufe
|
||||
| Wird gemeldet | Wird nicht gemeldet |
|
||||
|---|---|
|
||||
| Watchlist-Treffer (permanent) | Temporäre Sperren |
|
||||
| Progressive-Ban auf Maximalstufe (permanent) | GeoIP-Sperren |
|
||||
| | Externe Blocklist-Sperren |
|
||||
| | Manuelle Sperren |
|
||||
|
||||
Nicht gemeldet werden:
|
||||
|
||||
- temporäre Sperren
|
||||
- GeoIP-Sperren
|
||||
- externe Blocklist-Sperren
|
||||
- manuelle Sperren
|
||||
---
|
||||
|
||||
## GeoIP-Länderfilter
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|---|---|---|
|
||||
| `GEOIP_ENABLED` | `false` | GeoIP-Filter aktivieren |
|
||||
| `GEOIP_MODE` | `blocklist` | `blocklist` oder `allowlist` |
|
||||
| `GEOIP_COUNTRIES` | leer | ISO-3166-1-Alpha-2-Ländercodes |
|
||||
| `GEOIP_CHECK_INTERVAL` | `0` | Legacy-Parameter; die Go-Version nutzt den zentralen Query-Poller |
|
||||
| `GEOIP_NOTIFY` | `true` | Benachrichtigungen bei GeoIP-Sperren |
|
||||
| `GEOIP_SKIP_PRIVATE` | `true` | private/lokale IPs überspringen |
|
||||
| `GEOIP_LICENSE_KEY` | leer | MaxMind-License-Key für Auto-Download |
|
||||
| `GEOIP_MMDB_PATH` | leer | manueller Pfad zur MaxMind-MMDB |
|
||||
| `GEOIP_CACHE_TTL` | `86400` | Cache-Zeit in Sekunden |
|
||||
| `GEOIP_MODE` | `blocklist` | Filtermodus |
|
||||
| `GEOIP_COUNTRIES` | leer | Ländercodes nach ISO 3166-1 Alpha-2 |
|
||||
| `GEOIP_CHECK_INTERVAL` | `0` | Legacy-Parameter (Go-Version nutzt den zentralen Poller) |
|
||||
| `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) |
|
||||
|
||||
Blocklist-Modus:
|
||||
### 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](https://de.wikipedia.org/wiki/ISO-3166-1-Kodierliste).
|
||||
|
||||
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
|
||||
|
||||
```bash
|
||||
GEOIP_ENABLED=true
|
||||
@@ -549,9 +596,9 @@ GEOIP_MODE="blocklist"
|
||||
GEOIP_COUNTRIES="CN,RU,KP,IR"
|
||||
```
|
||||
|
||||
Damit werden öffentliche Clients aus diesen Ländern gesperrt.
|
||||
Damit werden öffentliche DNS-Clients aus China, Russland, Nordkorea und dem Iran gesperrt.
|
||||
|
||||
Allowlist-Modus:
|
||||
### Beispiel: Allowlist-Modus
|
||||
|
||||
```bash
|
||||
GEOIP_ENABLED=true
|
||||
@@ -559,62 +606,66 @@ GEOIP_MODE="allowlist"
|
||||
GEOIP_COUNTRIES="DE,AT,CH"
|
||||
```
|
||||
|
||||
Damit werden nur diese Länder erlaubt. Andere öffentliche Länder werden gesperrt.
|
||||
Damit werden nur Clients aus Deutschland, Österreich und der Schweiz erlaubt. Alle anderen öffentlichen Länder werden gesperrt.
|
||||
|
||||
Private IPs:
|
||||
### Private IPs
|
||||
|
||||
```bash
|
||||
GEOIP_SKIP_PRIVATE=true
|
||||
```
|
||||
|
||||
Damit werden unter anderem private Netze, Loopback, Link-Local und CGNAT übersprungen.
|
||||
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:
|
||||
| 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 |
|
||||
|
||||
1. `GEOIP_MMDB_PATH`, wenn gesetzt
|
||||
2. automatisch geladene MaxMind-Datenbank, wenn `GEOIP_LICENSE_KEY` gesetzt ist
|
||||
3. Legacy-Fallback über `geoiplookup` oder `geoiplookup6`
|
||||
|
||||
Automatischer MaxMind-Download:
|
||||
### Automatischer MaxMind-Download
|
||||
|
||||
```bash
|
||||
GEOIP_LICENSE_KEY="dein_maxmind_license_key"
|
||||
```
|
||||
|
||||
Die Datenbank wird unter `/opt/adguard-shield/geoip/` gespeichert und nach 24 Stunden erneuert.
|
||||
Die Datenbank wird unter `/opt/adguard-shield/geoip/` gespeichert und nach 24 Stunden automatisch erneuert.
|
||||
|
||||
Manueller Pfad:
|
||||
### GeoIP-Befehle
|
||||
|
||||
```bash
|
||||
GEOIP_MMDB_PATH="/usr/share/GeoIP/GeoLite2-Country.mmdb"
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-status # Status anzeigen
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-lookup 8.8.8.8 # IP nachschlagen
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-sync # Clients prüfen
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush-cache # Cache leeren
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush # Alle GeoIP-Sperren aufheben
|
||||
```
|
||||
|
||||
Nützliche Befehle:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-status
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-lookup 8.8.8.8
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-sync
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush-cache
|
||||
```
|
||||
---
|
||||
|
||||
## Protokollerkennung
|
||||
|
||||
AdGuard Shield liest das Feld `client_proto` aus der AdGuard-Home-API.
|
||||
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 |
|
||||
| leer oder `dns` | `DNS` | Klassisches DNS |
|
||||
| `doh` | `DoH` | DNS-over-HTTPS |
|
||||
| `dot` | `DoT` | DNS-over-TLS |
|
||||
| `doq` | `DoQ` | DNS-over-QUIC |
|
||||
| `dnscrypt` | `DNSCrypt` | DNSCrypt |
|
||||
| `dnscrypt` | `DNSCrypt` | DNSCrypt-Protokoll |
|
||||
|
||||
Die Sperre blockiert die konfigurierten Ports unabhängig davon, welches Protokoll den Verstoß ausgelöst hat.
|
||||
Die Sperre blockiert immer alle konfigurierten Ports, unabhängig davon, welches Protokoll den Verstoß ausgelöst hat.
|
||||
|
||||
## Beispielkonfiguration für ein Heimnetz
|
||||
---
|
||||
|
||||
## Beispielkonfiguration: Heimnetz
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="http://127.0.0.1:3000"
|
||||
@@ -646,7 +697,7 @@ EXTERNAL_BLOCKLIST_ENABLED=false
|
||||
EXTERNAL_WHITELIST_ENABLED=false
|
||||
```
|
||||
|
||||
## Beispielkonfiguration für einen öffentlichen Resolver
|
||||
## Beispielkonfiguration: Öffentlicher Resolver
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="https://dns.example.com"
|
||||
@@ -670,6 +721,11 @@ 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="..."
|
||||
|
||||
@@ -678,7 +734,7 @@ NOTIFY_TYPE="ntfy"
|
||||
NTFY_TOPIC="adguard-shield-prod"
|
||||
```
|
||||
|
||||
Vor produktiver Aktivierung:
|
||||
### Vor produktiver Aktivierung
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
|
||||
207
docs/report.md
207
docs/report.md
@@ -4,55 +4,57 @@ AdGuard Shield kann Statistik-Reports direkt aus der SQLite-Datenbank erzeugen u
|
||||
|
||||
## Was der Report enthält
|
||||
|
||||
Der Report basiert auf:
|
||||
Der Report basiert auf der SQLite-Datenbank:
|
||||
|
||||
```text
|
||||
/var/lib/adguard-shield/adguard-shield.db
|
||||
```
|
||||
|
||||
Ausgewertet werden vor allem:
|
||||
### Ausgewertete Daten
|
||||
|
||||
- `ban_history`
|
||||
- `active_bans`
|
||||
| Bereich | Inhalt |
|
||||
|---|---|
|
||||
| Zeitraum | Start- und Enddatum des Berichtszeitraums |
|
||||
| Sperren | Anzahl der Sperren im Zeitraum |
|
||||
| Freigaben | Anzahl der Freigaben im Zeitraum |
|
||||
| Aktive Sperren | Derzeit aktive Sperren zum Zeitpunkt der Report-Erstellung |
|
||||
| Top-Clients | Die am häufigsten gesperrten Client-IPs |
|
||||
| Sperrgründe | Aufschlüsselung nach Grund (Rate-Limit, Subdomain-Flood, GeoIP usw.) |
|
||||
| Sperrquellen | Aufschlüsselung nach Quelle (Monitor, GeoIP, Blocklist, manuell) |
|
||||
| Letzte Ereignisse | Die letzten 20 Einträge aus der Ban-History |
|
||||
|
||||
Inhalte:
|
||||
|
||||
- Zeitraum des Reports
|
||||
- Anzahl Sperren im Zeitraum
|
||||
- Anzahl Freigaben im Zeitraum
|
||||
- aktuell aktive Sperren
|
||||
- Top-Clients
|
||||
- Gründe der Sperren
|
||||
- Quellen aktiver Sperren
|
||||
- letzte Ereignisse aus der History
|
||||
---
|
||||
|
||||
## Konfiguration
|
||||
|
||||
```bash
|
||||
REPORT_ENABLED=false
|
||||
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"
|
||||
REPORT_BUSIEST_DAY_RANGE=30
|
||||
```
|
||||
| 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 (`html` oder `txt`) |
|
||||
| `REPORT_MAIL_CMD` | `msmtp` | Mailprogramm für den Versand |
|
||||
| `REPORT_BUSIEST_DAY_RANGE` | `30` | Kompatibilitätsparameter für den Zeitraum "Aktivster Tag" |
|
||||
|
||||
Parameter:
|
||||
### Versandintervalle
|
||||
|
||||
| Parameter | Bedeutung |
|
||||
| Intervall | Versandzeitpunkt |
|
||||
|---|---|
|
||||
| `REPORT_ENABLED` | dokumentiert, ob Reports gewünscht sind; der Cron-Job wird über `report-install` angelegt |
|
||||
| `REPORT_INTERVAL` | `daily`, `weekly`, `biweekly` oder `monthly` |
|
||||
| `REPORT_TIME` | Uhrzeit im Format `HH:MM` |
|
||||
| `REPORT_EMAIL_TO` | Empfängeradresse |
|
||||
| `REPORT_EMAIL_FROM` | Absenderadresse |
|
||||
| `REPORT_FORMAT` | `html` oder `txt` |
|
||||
| `REPORT_MAIL_CMD` | Mailprogramm, z.B. `msmtp` |
|
||||
| `REPORT_BUSIEST_DAY_RANGE` | Kompatibilitätsparameter für den Zeitraum "Aktivster Tag" |
|
||||
| `daily` | Täglich zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `weekly` | Montags zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `biweekly` | Am 1. und 15. des Monats zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `monthly` | Am 1. des Monats zur Uhrzeit aus `REPORT_TIME` |
|
||||
|
||||
Beispiel:
|
||||
### Formate
|
||||
|
||||
| Format | Beschreibung | Empfehlung |
|
||||
|---|---|---|
|
||||
| `html` | HTML-formatierte E-Mail mit Tabellen und Formatierung | Standard-Mail-Clients |
|
||||
| `txt` | Reiner Text ohne Formatierung | Einfache Mail-Setups, Log-Ablage |
|
||||
|
||||
### Beispielkonfiguration
|
||||
|
||||
```bash
|
||||
REPORT_ENABLED=true
|
||||
@@ -64,31 +66,58 @@ REPORT_FORMAT="html"
|
||||
REPORT_MAIL_CMD="msmtp"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Befehle
|
||||
|
||||
### Konfiguration und Cron-Status anzeigen
|
||||
|
||||
```bash
|
||||
# Konfiguration und Cron-Status anzeigen
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
```
|
||||
|
||||
# HTML-Report in Datei schreiben
|
||||
### HTML-Report in Datei schreiben
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate html /tmp/adguard-shield-report.html
|
||||
```
|
||||
|
||||
# Text-Report auf stdout ausgeben
|
||||
Die Datei kann im Browser geöffnet werden, um das Ergebnis zu prüfen.
|
||||
|
||||
### Text-Report auf stdout ausgeben
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
```
|
||||
|
||||
# Testmail senden
|
||||
### Testmail senden
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
```
|
||||
|
||||
# aktuellen Report erzeugen und versenden
|
||||
Sendet eine einfache Testmail. Erst wenn diese ankommt, lohnt sich die Fehlersuche am eigentlichen Report.
|
||||
|
||||
### Aktuellen Report erzeugen und versenden
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
```
|
||||
|
||||
# Cron-Job installieren
|
||||
### Cron-Job installieren
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-install
|
||||
```
|
||||
|
||||
# Cron-Job entfernen
|
||||
### Cron-Job entfernen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-remove
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mailversand
|
||||
|
||||
AdGuard Shield übergibt die fertige Mail an ein lokales Mailprogramm. Der Standard ist:
|
||||
@@ -97,26 +126,38 @@ AdGuard Shield übergibt die fertige Mail an ein lokales Mailprogramm. Der Stand
|
||||
REPORT_MAIL_CMD="msmtp"
|
||||
```
|
||||
|
||||
Minimaler Ablauf mit `msmtp`:
|
||||
### Einrichtung mit msmtp
|
||||
|
||||
```bash
|
||||
# msmtp installieren
|
||||
sudo apt install msmtp msmtp-mta
|
||||
|
||||
# Testmail senden
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
```
|
||||
|
||||
`report-test` sendet eine einfache Testmail. Erst wenn diese funktioniert, lohnt sich die Fehlersuche am eigentlichen Report.
|
||||
### Eigene Mailprogramm-Argumente
|
||||
|
||||
Wenn dein Mailprogramm zusätzliche Argumente braucht, können sie in `REPORT_MAIL_CMD` stehen. AdGuard Shield hängt intern `-t` an, damit Empfänger und Header aus der generierten Mail gelesen werden.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
REPORT_MAIL_CMD="msmtp --account=default"
|
||||
```
|
||||
|
||||
### Alternativen zu msmtp
|
||||
|
||||
| Programm | `REPORT_MAIL_CMD` |
|
||||
|---|---|
|
||||
| msmtp | `msmtp` |
|
||||
| sendmail | `sendmail` |
|
||||
| ssmtp | `ssmtp` |
|
||||
| Benutzerdefiniert | Vollständiger Pfad zum Programm |
|
||||
|
||||
---
|
||||
|
||||
## Automatischer Versand
|
||||
|
||||
Cron installieren:
|
||||
### Cron-Job installieren
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-install
|
||||
@@ -134,57 +175,67 @@ Der Cron-Eintrag ruft das installierte Binary mit der installierten Konfiguratio
|
||||
/opt/adguard-shield/adguard-shield -config /opt/adguard-shield/adguard-shield.conf report-send
|
||||
```
|
||||
|
||||
Zeitplan nach `REPORT_INTERVAL`:
|
||||
### Zeitplan nach Intervall
|
||||
|
||||
| Intervall | Cron-Verhalten |
|
||||
|---|---|
|
||||
| `daily` | täglich zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `weekly` | montags zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `biweekly` | am 1. und 15. des Monats |
|
||||
| `monthly` | am 1. des Monats |
|
||||
| `daily` | Täglich zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `weekly` | Montags zur Uhrzeit aus `REPORT_TIME` |
|
||||
| `biweekly` | Am 1. und 15. des Monats |
|
||||
| `monthly` | Am 1. des Monats |
|
||||
|
||||
Cron entfernen:
|
||||
### Cron-Job entfernen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-remove
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manuelle Prüfung
|
||||
|
||||
Status:
|
||||
### Schritt 1: Status prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
```
|
||||
|
||||
Report lokal erzeugen:
|
||||
### Schritt 2: Report lokal erzeugen
|
||||
|
||||
```bash
|
||||
# HTML-Report zum Ansehen im Browser
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate html /tmp/adguard-shield-report.html
|
||||
|
||||
# Text-Report in der Konsole
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
```
|
||||
|
||||
Versand testen:
|
||||
### Schritt 3: Versand testen
|
||||
|
||||
```bash
|
||||
# Einfache Testmail
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
|
||||
# Vollständigen Report senden
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
```
|
||||
|
||||
Logs:
|
||||
### Schritt 4: Logs prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
sudo journalctl -u cron --no-pager -n 100
|
||||
```
|
||||
|
||||
Je nach Distribution heißt der Cron-Service auch `cron`, `crond` oder wird über das allgemeine Syslog protokolliert.
|
||||
Je nach Distribution heißt der Cron-Service `cron`, `crond` oder wird über das allgemeine Syslog protokolliert.
|
||||
|
||||
---
|
||||
|
||||
## Häufige Probleme
|
||||
|
||||
### `REPORT_EMAIL_TO ist leer`
|
||||
|
||||
Setze einen Empfänger:
|
||||
Setze einen Empfänger in der Konfiguration:
|
||||
|
||||
```bash
|
||||
REPORT_EMAIL_TO="admin@example.com"
|
||||
@@ -192,52 +243,42 @@ REPORT_EMAIL_TO="admin@example.com"
|
||||
|
||||
### Mailprogramm nicht gefunden
|
||||
|
||||
Prüfen:
|
||||
Prüfe, ob das Mailprogramm installiert ist:
|
||||
|
||||
```bash
|
||||
which msmtp
|
||||
```
|
||||
|
||||
Installieren:
|
||||
Installiere es bei Bedarf:
|
||||
|
||||
```bash
|
||||
sudo apt install msmtp msmtp-mta
|
||||
```
|
||||
|
||||
Oder `REPORT_MAIL_CMD` auf dein vorhandenes Mailprogramm setzen.
|
||||
Oder setze `REPORT_MAIL_CMD` auf dein vorhandenes Mailprogramm.
|
||||
|
||||
### Cron läuft, aber keine Mail kommt an
|
||||
|
||||
Prüfen:
|
||||
Prüfe die Konfiguration und den Cron-Job:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
sudo cat /etc/cron.d/adguard-shield-report
|
||||
```
|
||||
|
||||
Achte darauf, dass:
|
||||
**Checkliste:**
|
||||
|
||||
- `REPORT_EMAIL_TO` stimmt
|
||||
- `REPORT_MAIL_CMD` im Cron-PATH verfügbar ist
|
||||
- der lokale Mailer für root konfiguriert ist
|
||||
- Spam-Ordner geprüft wurde
|
||||
- ausgehende SMTP-Verbindungen erlaubt sind
|
||||
| Prüfpunkt | Beschreibung |
|
||||
|---|---|
|
||||
| Empfänger | `REPORT_EMAIL_TO` korrekt gesetzt? |
|
||||
| Mailprogramm | `REPORT_MAIL_CMD` im Cron-PATH verfügbar? |
|
||||
| Root-Konfiguration | Mailer für root konfiguriert? (msmtp benötigt `/root/.msmtprc` oder `/etc/msmtprc`) |
|
||||
| Spam | Spam-Ordner geprüft? |
|
||||
| SMTP | Ausgehende SMTP-Verbindungen erlaubt? (Port 587/465) |
|
||||
|
||||
## HTML und TXT
|
||||
### Format beim Generieren überschreiben
|
||||
|
||||
HTML ist für normale E-Mail-Clients angenehmer zu lesen:
|
||||
|
||||
```bash
|
||||
REPORT_FORMAT="html"
|
||||
```
|
||||
|
||||
TXT ist robuster für sehr einfache Mail-Setups oder Log-Ablage:
|
||||
|
||||
```bash
|
||||
REPORT_FORMAT="txt"
|
||||
```
|
||||
|
||||
Du kannst das Format beim manuellen Generieren überschreiben:
|
||||
Du kannst das Format unabhängig von der Konfiguration wählen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
|
||||
@@ -4,41 +4,55 @@ Dieses Dokument hilft beim Eingrenzen typischer Probleme im Betrieb. Die Reihenf
|
||||
|
||||
## Erste Diagnose
|
||||
|
||||
Diese Befehle liefern meistens schon genug Hinweise:
|
||||
Diese fünf Befehle liefern meistens schon genug Hinweise, um ein Problem einzugrenzen:
|
||||
|
||||
```bash
|
||||
# 1. Läuft der Service?
|
||||
sudo systemctl status adguard-shield
|
||||
|
||||
# 2. Was sagt das Journal?
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
|
||||
# 3. Funktioniert die API?
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
|
||||
# 4. Was ist der aktuelle Zustand?
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
|
||||
# 5. Gibt es Warnungen oder Fehler?
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
```
|
||||
|
||||
Wenn du aktuelle Queries sehen willst:
|
||||
Wenn du aktuelle Queries und den Echtzeit-Zustand sehen willst:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield live
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service startet nicht
|
||||
|
||||
Prüfen:
|
||||
### Prüfen
|
||||
|
||||
```bash
|
||||
sudo systemctl status adguard-shield
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
```
|
||||
|
||||
Typische Ursachen:
|
||||
### Typische Ursachen
|
||||
|
||||
- Konfigurationsdatei fehlt oder hat falsche Rechte
|
||||
- Binary fehlt oder ist nicht ausführbar
|
||||
- `iptables`, `ip6tables` oder `ipset` fehlen
|
||||
- AdGuard-Home-API ist nicht erreichbar
|
||||
- alte Shell-Artefakte verursachen Konflikte
|
||||
- systemd-Unit wurde manuell geändert, aber `daemon-reload` fehlt
|
||||
| Ursache | Lösung |
|
||||
|---|---|
|
||||
| Konfigurationsdatei fehlt | `/opt/adguard-shield/adguard-shield.conf` prüfen |
|
||||
| Falsche Dateirechte | `sudo chmod 600 /opt/adguard-shield/adguard-shield.conf` |
|
||||
| Binary fehlt oder nicht ausführbar | `ls -l /opt/adguard-shield/adguard-shield` prüfen |
|
||||
| Systempakete fehlen | `which iptables ip6tables ipset systemctl` prüfen |
|
||||
| API nicht erreichbar | Erst AdGuard Home starten |
|
||||
| Alte Shell-Artefakte | Go-Installer meldet Konflikte, alte Version deinstallieren |
|
||||
| Unit manuell geändert | `sudo systemctl daemon-reload` ausführen |
|
||||
|
||||
Nützliche Prüfungen:
|
||||
### Nützliche Prüfbefehle
|
||||
|
||||
```bash
|
||||
ls -l /opt/adguard-shield/adguard-shield
|
||||
@@ -47,15 +61,17 @@ which iptables ip6tables ipset systemctl
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verbindung zu AdGuard Home schlägt fehl
|
||||
|
||||
Test:
|
||||
### Test
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
```
|
||||
|
||||
Prüfe in `/opt/adguard-shield/adguard-shield.conf`:
|
||||
### Konfiguration prüfen
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="http://127.0.0.1:3000"
|
||||
@@ -63,17 +79,17 @@ ADGUARD_USER="admin"
|
||||
ADGUARD_PASS="..."
|
||||
```
|
||||
|
||||
Häufige Fehler:
|
||||
### Häufige Fehler und Lösungen
|
||||
|
||||
| Symptom | Mögliche Ursache |
|
||||
|---|---|
|
||||
| HTTP 401/403 | Benutzername oder Passwort falsch |
|
||||
| HTTP 404 | falsche URL oder AdGuard Home nicht hinter dieser URL |
|
||||
| Timeout | Firewall, DNS, falsche IP, Dienst nicht erreichbar |
|
||||
| connection refused | AdGuard Home läuft nicht oder anderer Port |
|
||||
| keine Querylog-Einträge | Querylog in AdGuard Home deaktiviert oder leer |
|
||||
| Symptom | Mögliche Ursache | Lösung |
|
||||
|---|---|---|
|
||||
| HTTP 401/403 | Benutzername oder Passwort falsch | Zugangsdaten in der Konfiguration prüfen |
|
||||
| HTTP 404 | Falsche URL oder falscher Port | URL und Port prüfen, AdGuard-Home-Weboberfläche testen |
|
||||
| Timeout | Firewall, DNS-Problem oder falsche IP | Netzwerk und Erreichbarkeit prüfen |
|
||||
| Connection refused | AdGuard Home läuft nicht oder anderer Port | `systemctl status AdGuardHome` prüfen |
|
||||
| Keine Querylog-Einträge | Querylog deaktiviert oder leer | In AdGuard Home prüfen: Einstellungen > Querylog |
|
||||
|
||||
Direkt testen:
|
||||
### Direkt testen (unabhängig von AdGuard Shield)
|
||||
|
||||
```bash
|
||||
curl -k -u "admin:passwort" "http://127.0.0.1:3000/control/querylog?limit=1&response_status=all"
|
||||
@@ -81,9 +97,11 @@ curl -k -u "admin:passwort" "http://127.0.0.1:3000/control/querylog?limit=1&resp
|
||||
|
||||
Passe URL und Zugangsdaten entsprechend an.
|
||||
|
||||
---
|
||||
|
||||
## Keine Sperren trotz vieler Anfragen
|
||||
|
||||
Prüfen:
|
||||
### Prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield live --once
|
||||
@@ -91,46 +109,53 @@ sudo /opt/adguard-shield/adguard-shield history 50
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level debug --limit 100
|
||||
```
|
||||
|
||||
Mögliche Ursachen:
|
||||
### Mögliche Ursachen und Lösungen
|
||||
|
||||
- `RATE_LIMIT_MAX_REQUESTS` ist zu hoch
|
||||
- `RATE_LIMIT_WINDOW` ist zu kurz
|
||||
- `API_QUERY_LIMIT` ist zu niedrig und verpasst Spitzen
|
||||
- Client steht in `WHITELIST`
|
||||
- externe Whitelist enthält die IP
|
||||
- AdGuard Home sieht nicht die echte Client-IP, sondern nur einen Proxy/Forwarder
|
||||
- Querylog enthält die Anfragen nicht
|
||||
- `DRY_RUN=true` ist gesetzt
|
||||
| Ursache | Lösung |
|
||||
|---|---|
|
||||
| `RATE_LIMIT_MAX_REQUESTS` zu hoch | Grenzwert senken oder `live` beobachten |
|
||||
| `RATE_LIMIT_WINDOW` zu kurz | Zeitfenster verlängern |
|
||||
| `API_QUERY_LIMIT` zu niedrig | Erhöhen, damit Spitzen nicht verpasst werden |
|
||||
| Client steht in `WHITELIST` | Whitelist prüfen |
|
||||
| Externe Whitelist enthält die IP | `whitelist-status` prüfen |
|
||||
| Proxy/Forwarder maskiert echte Client-IPs | AdGuard Home sieht nur die Forwarder-IP; Forwarder whitelisten |
|
||||
| Querylog enthält die Anfragen nicht | In AdGuard Home prüfen, ob Querylog aktiviert ist |
|
||||
| `DRY_RUN=true` ist gesetzt | In der Konfiguration auf `false` setzen |
|
||||
|
||||
Wichtig bei Proxies und Forwardern: Wenn AdGuard Home nur eine einzige interne IP sieht, zählt AdGuard Shield auch nur diese IP. In solchen Setups muss die Architektur geprüft oder der Forwarder gewhitelistet werden.
|
||||
**Wichtig bei Proxies und Forwardern:** Wenn AdGuard Home nur eine einzige interne IP sieht (z.B. die IP eines Routers oder Reverse Proxy), zählt AdGuard Shield auch nur diese IP. In solchen Setups muss die Architektur geprüft oder der Forwarder gewhitelistet werden.
|
||||
|
||||
---
|
||||
|
||||
## Zu viele Sperren
|
||||
|
||||
Erst Übersicht:
|
||||
### Übersicht verschaffen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield history 100
|
||||
```
|
||||
|
||||
Dann Ursachen einordnen:
|
||||
### Ursachen und Gegenmaßnahmen
|
||||
|
||||
| Ursache | Gegenmaßnahme |
|
||||
|---|---|
|
||||
| legitimer Client fragt häufig dieselbe Domain | Client whitelisten oder Limit erhöhen |
|
||||
| Router/Resolver bündelt viele Clients | Router/Resolver whitelisten |
|
||||
| Legitimer Client fragt häufig dieselbe Domain | Client whitelisten oder `RATE_LIMIT_MAX_REQUESTS` erhöhen |
|
||||
| Router/Resolver bündelt viele Clients | Router/Resolver in `WHITELIST` aufnehmen |
|
||||
| CDN/App erzeugt viele Subdomains | `SUBDOMAIN_FLOOD_MAX_UNIQUE` erhöhen |
|
||||
| externe Blocklist ist sehr groß | `blocklist-status` prüfen und Benachrichtigungen deaktiviert lassen |
|
||||
| GeoIP Allowlist zu eng | Länder prüfen oder `GEOIP_MODE` ändern |
|
||||
| Externe Blocklist ist sehr groß | `blocklist-status` prüfen und ggf. Liste anpassen |
|
||||
| GeoIP Allowlist zu eng | Länder prüfen oder `GEOIP_MODE` wechseln |
|
||||
|
||||
Falsch gesperrte IP freigeben:
|
||||
### Falsch gesperrte IP freigeben
|
||||
|
||||
```bash
|
||||
# Sperre aufheben
|
||||
sudo /opt/adguard-shield/adguard-shield unban 192.168.1.100
|
||||
|
||||
# Offense-Zähler zurücksetzen (damit progressive Sperren nicht sofort eskalieren)
|
||||
sudo /opt/adguard-shield/adguard-shield reset-offenses 192.168.1.100
|
||||
```
|
||||
|
||||
Dauerhaft ausnehmen:
|
||||
### Dauerhaft ausnehmen
|
||||
|
||||
```bash
|
||||
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.100"
|
||||
@@ -142,24 +167,35 @@ Danach:
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Firewall prüfen
|
||||
|
||||
Status:
|
||||
### Status über AdGuard Shield
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-status
|
||||
```
|
||||
|
||||
Direkt prüfen:
|
||||
### Direkte Prüfung mit Systembefehlen
|
||||
|
||||
```bash
|
||||
# ipsets anzeigen
|
||||
sudo ipset list adguard_shield_v4
|
||||
sudo ipset list adguard_shield_v6
|
||||
|
||||
# iptables-Regeln anzeigen
|
||||
sudo iptables -n -L ADGUARD_SHIELD --line-numbers -v
|
||||
sudo ip6tables -n -L ADGUARD_SHIELD --line-numbers -v
|
||||
|
||||
# Prüfen, ob Chain in INPUT eingehängt ist
|
||||
sudo iptables -n -L INPUT --line-numbers -v | grep ADGUARD
|
||||
|
||||
# Bei Docker Bridge: DOCKER-USER prüfen
|
||||
sudo iptables -n -L DOCKER-USER --line-numbers -v | grep ADGUARD
|
||||
```
|
||||
|
||||
Firewall neu aufbauen:
|
||||
### Firewall neu aufbauen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-remove
|
||||
@@ -169,40 +205,47 @@ sudo systemctl restart adguard-shield
|
||||
|
||||
Nach dem Neustart werden aktive Sperren aus SQLite wieder in die ipsets geschrieben.
|
||||
|
||||
---
|
||||
|
||||
## Sperren bleiben nach Ablauf aktiv
|
||||
|
||||
Prüfen:
|
||||
### Prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield history 100
|
||||
```
|
||||
|
||||
Temporäre Sperren werden beim Start und während des Pollings auf Ablauf geprüft. Wenn eine Sperre permanent ist, wird sie nicht automatisch freigegeben.
|
||||
Temporäre Sperren werden beim Start und während jedes Pollings auf Ablauf geprüft. Wenn eine Sperre als permanent angezeigt wird, wird sie nicht automatisch freigegeben.
|
||||
|
||||
Permanent sind typischerweise:
|
||||
### Permanente Sperren (gewollt)
|
||||
|
||||
- DNS-Flood-Watchlist-Treffer
|
||||
- Progressive-Ban-Maximalstufe
|
||||
- manuelle `ban`-Sperren
|
||||
- GeoIP-Sperren
|
||||
- externe Blocklist mit `EXTERNAL_BLOCKLIST_BAN_DURATION=0`
|
||||
| Typ | Warum permanent |
|
||||
|---|---|
|
||||
| DNS-Flood-Watchlist-Treffer | Sofortiger Permanent-Ban |
|
||||
| Progressive-Ban auf Maximalstufe | Eskalation durch wiederholte Verstöße |
|
||||
| Manuelle `ban`-Sperren | Manuell gesetzt, manuell aufheben |
|
||||
| GeoIP-Sperren | Permanent bis Konfigurationsänderung |
|
||||
| Externe Blocklist mit `BAN_DURATION=0` | Permanent bis IP aus Liste entfernt |
|
||||
|
||||
Manuell freigeben:
|
||||
### Manuell freigeben
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield unban 192.168.1.100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dry-Run verwenden
|
||||
|
||||
Dry-Run ist ideal für neue Regeln:
|
||||
Dry-Run ist ideal, um neue Konfigurationen zu prüfen, bevor sie produktiv gehen:
|
||||
|
||||
```bash
|
||||
# Dry-Run starten (Strg+C zum Beenden)
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
```
|
||||
|
||||
Währenddessen:
|
||||
Währenddessen die Ergebnisse prüfen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield history 50
|
||||
@@ -210,215 +253,291 @@ sudo /opt/adguard-shield/adguard-shield history 50
|
||||
|
||||
Im Dry-Run werden mögliche Sperren als `DRY` protokolliert. Es entstehen keine aktiven Sperren und keine Firewall-Änderungen.
|
||||
|
||||
---
|
||||
|
||||
## Externe Whitelist
|
||||
|
||||
Status:
|
||||
### Status prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield whitelist-status
|
||||
```
|
||||
|
||||
Manuell synchronisieren:
|
||||
### Manuell synchronisieren
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield whitelist-sync
|
||||
```
|
||||
|
||||
Typische Probleme:
|
||||
### Typische Probleme
|
||||
|
||||
- URL nicht erreichbar
|
||||
- Datei enthält Windows-Zeilenenden oder BOM
|
||||
- Hostname ist nicht auflösbar
|
||||
- Einträge enthalten Ports oder URLs statt IP/Hostname
|
||||
- DNS-Auflösung liefert `0.0.0.0`, weil AdGuard den Host blockiert
|
||||
| Problem | Lösung |
|
||||
|---|---|
|
||||
| URL nicht erreichbar | URL im Browser oder mit `curl` testen |
|
||||
| Windows-Zeilenenden oder BOM | Datei in UTF-8 ohne BOM und mit `LF`-Zeilenenden speichern |
|
||||
| Hostname nicht auflösbar | DNS-Auflösung prüfen, ggf. alternativen Hostnamen verwenden |
|
||||
| Einträge enthalten Ports oder URLs | Nur IPs, CIDR-Netze und Hostnamen werden unterstützt |
|
||||
| DNS liefert `0.0.0.0` | AdGuard blockiert den Host; Ausnahme in AdGuard Home einrichten |
|
||||
|
||||
Format prüfen:
|
||||
### Erwartetes Listenformat
|
||||
|
||||
```text
|
||||
192.168.1.100
|
||||
10.0.0.0/24
|
||||
trusted.example.com
|
||||
192.168.1.100 # IPv4-Adresse
|
||||
10.0.0.0/24 # CIDR-Netz
|
||||
trusted.example.com # Hostname (wird per DNS aufgelöst)
|
||||
# Kommentare sind erlaubt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Externe Blocklist
|
||||
|
||||
Status:
|
||||
### Status prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-status
|
||||
```
|
||||
|
||||
Manuell synchronisieren:
|
||||
### Manuell synchronisieren
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-sync
|
||||
```
|
||||
|
||||
Alle externen Blocklist-Sperren freigeben:
|
||||
### Alle Blocklist-Sperren freigeben
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-flush
|
||||
```
|
||||
|
||||
Wenn zu viele IPs gesperrt werden:
|
||||
### Zu viele IPs gesperrt?
|
||||
|
||||
1. `EXTERNAL_BLOCKLIST_URLS` prüfen.
|
||||
2. Liste manuell ansehen.
|
||||
3. Whitelist für eigene IPs ergänzen.
|
||||
4. `EXTERNAL_BLOCKLIST_NOTIFY=false` lassen.
|
||||
5. Bei Bedarf `EXTERNAL_BLOCKLIST_AUTO_UNBAN=true` setzen.
|
||||
1. `EXTERNAL_BLOCKLIST_URLS` prüfen: Welche Listen sind konfiguriert?
|
||||
2. Liste manuell ansehen: Wie viele Einträge enthält sie?
|
||||
3. Whitelist ergänzen: Eigene IPs sollten dort stehen.
|
||||
4. `EXTERNAL_BLOCKLIST_NOTIFY=false` belassen, um den Benachrichtigungskanal nicht zu überfluten.
|
||||
5. `EXTERNAL_BLOCKLIST_AUTO_UNBAN=true` setzen, damit entfernte Einträge automatisch freigegeben werden.
|
||||
|
||||
---
|
||||
|
||||
## GeoIP
|
||||
|
||||
Status:
|
||||
### Status prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-status
|
||||
```
|
||||
|
||||
Einzelne IP prüfen:
|
||||
### Einzelne IP prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-lookup 8.8.8.8
|
||||
```
|
||||
|
||||
Cache leeren:
|
||||
### Cache leeren
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush-cache
|
||||
```
|
||||
|
||||
Alle GeoIP-Sperren freigeben:
|
||||
### Alle GeoIP-Sperren freigeben
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush
|
||||
```
|
||||
|
||||
Typische Ursachen:
|
||||
### Typische Probleme und Lösungen
|
||||
|
||||
| Problem | Lösung |
|
||||
|---|---|
|
||||
| keine Länder erkannt | MaxMind-Key, MMDB-Pfad oder `geoiplookup` prüfen |
|
||||
| private IPs werden nicht geprüft | `GEOIP_SKIP_PRIVATE=true` ist aktiv, das ist Standard |
|
||||
| zu viele Länder gesperrt | `GEOIP_MODE` und `GEOIP_COUNTRIES` prüfen |
|
||||
| Allowlist sperrt fast alles | im Allowlist-Modus sind nur genannte Länder erlaubt |
|
||||
| Keine Länder erkannt | MaxMind-Key, MMDB-Pfad oder `geoiplookup`-Befehl prüfen |
|
||||
| Private IPs werden nicht geprüft | `GEOIP_SKIP_PRIVATE=true` ist Standard und korrekt |
|
||||
| Zu viele Länder gesperrt | `GEOIP_MODE` und `GEOIP_COUNTRIES` prüfen |
|
||||
| Allowlist sperrt fast alles | Im Allowlist-Modus sind nur genannte Länder erlaubt; alle anderen werden gesperrt |
|
||||
| Datenbank nicht gefunden | `GEOIP_LICENSE_KEY` oder `GEOIP_MMDB_PATH` setzen |
|
||||
| Datenbank veraltet | `geoip-flush-cache` und Service neu starten |
|
||||
|
||||
### Ländercodes nachschlagen
|
||||
|
||||
Die GeoIP-Ländercodes folgen dem Standard ISO 3166-1 Alpha-2. Eine vollständige Liste findest du in der [ISO-3166-1-Kodierliste auf Wikipedia](https://de.wikipedia.org/wiki/ISO-3166-1-Kodierliste).
|
||||
|
||||
---
|
||||
|
||||
## Reports
|
||||
|
||||
Status:
|
||||
### Status prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
```
|
||||
|
||||
Test:
|
||||
### Funktionstest
|
||||
|
||||
```bash
|
||||
# Testmail senden
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
|
||||
# Text-Report in der Konsole ansehen
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
```
|
||||
|
||||
Wenn keine Mail ankommt:
|
||||
### Keine Mail kommt an?
|
||||
|
||||
- `REPORT_EMAIL_TO` gesetzt?
|
||||
- `REPORT_MAIL_CMD` vorhanden?
|
||||
- Mailer für root konfiguriert?
|
||||
- Cron installiert?
|
||||
- Spam-Ordner geprüft?
|
||||
| Prüfpunkt | Befehl / Aktion |
|
||||
|---|---|
|
||||
| `REPORT_EMAIL_TO` gesetzt? | Konfiguration prüfen |
|
||||
| `REPORT_MAIL_CMD` vorhanden? | `which msmtp` |
|
||||
| Mailer für root konfiguriert? | `/root/.msmtprc` oder `/etc/msmtprc` prüfen |
|
||||
| Cron installiert? | `sudo cat /etc/cron.d/adguard-shield-report` |
|
||||
| Spam-Ordner geprüft? | E-Mail-Provider prüfen |
|
||||
| SMTP-Port offen? | Ausgehende Verbindung auf Port 587/465 testen |
|
||||
|
||||
Cron prüfen:
|
||||
### Cron prüfen
|
||||
|
||||
```bash
|
||||
sudo cat /etc/cron.d/adguard-shield-report
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Benachrichtigungen
|
||||
|
||||
Prüfen:
|
||||
### Prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
```
|
||||
|
||||
Häufige Ursachen:
|
||||
### Checkliste
|
||||
|
||||
- `NOTIFY_ENABLED=false`
|
||||
- falscher `NOTIFY_TYPE`
|
||||
- Webhook-URL leer
|
||||
- Ntfy-Topic leer
|
||||
- Token ungültig
|
||||
- ausgehende HTTPS-Verbindung blockiert
|
||||
- externe Blocklist meldet nichts, weil `EXTERNAL_BLOCKLIST_NOTIFY=false`
|
||||
- GeoIP meldet nichts, weil `GEOIP_NOTIFY=false`
|
||||
| Prüfpunkt | Beschreibung |
|
||||
|---|---|
|
||||
| `NOTIFY_ENABLED=true` | Benachrichtigungen global aktiviert? |
|
||||
| `NOTIFY_TYPE` | Korrekt geschrieben? (`ntfy`, `discord`, `slack`, `gotify`, `generic`) |
|
||||
| Webhook-URL | Gesetzt und erreichbar? |
|
||||
| Ntfy-Topic | Nicht leer? |
|
||||
| Token | Gültig und nicht abgelaufen? |
|
||||
| Netzwerk | Ausgehende HTTPS-Verbindungen möglich? |
|
||||
| Modul-Schalter | `EXTERNAL_BLOCKLIST_NOTIFY` und `GEOIP_NOTIFY` separat prüfen |
|
||||
|
||||
Bei `generic` Webhook kannst du testweise einen lokalen HTTP-Empfänger oder einen Request-Inspector (z.B. webhook.site) verwenden, um den gesendeten Payload zu sehen.
|
||||
|
||||
---
|
||||
|
||||
## SQLite direkt auswerten
|
||||
|
||||
Für tiefergehende Analysen:
|
||||
Für tiefergehende Analysen kannst du die SQLite-Datenbank direkt abfragen:
|
||||
|
||||
### Sperren nach Quelle und Grund
|
||||
|
||||
```bash
|
||||
sudo sqlite3 /var/lib/adguard-shield/adguard-shield.db \
|
||||
"select source, reason, count(*) from active_bans group by source, reason order by count(*) desc;"
|
||||
"SELECT source, reason, count(*) FROM active_bans GROUP BY source, reason ORDER BY count(*) DESC;"
|
||||
```
|
||||
|
||||
Letzte History:
|
||||
### Letzte History-Einträge
|
||||
|
||||
```bash
|
||||
sudo sqlite3 /var/lib/adguard-shield/adguard-shield.db \
|
||||
"select timestamp_text, action, client_ip, domain, reason from ban_history order by id desc limit 20;"
|
||||
"SELECT timestamp_text, action, client_ip, domain, reason FROM ban_history ORDER BY id DESC LIMIT 20;"
|
||||
```
|
||||
|
||||
Offense-Zähler:
|
||||
### Offense-Zähler
|
||||
|
||||
```bash
|
||||
sudo sqlite3 /var/lib/adguard-shield/adguard-shield.db \
|
||||
"select client_ip, offense_level, last_offense from offense_tracking order by offense_level desc;"
|
||||
"SELECT client_ip, offense_level, last_offense FROM offense_tracking ORDER BY offense_level DESC;"
|
||||
```
|
||||
|
||||
### Whitelist-Cache
|
||||
|
||||
```bash
|
||||
sudo sqlite3 /var/lib/adguard-shield/adguard-shield.db \
|
||||
"SELECT ip, source FROM whitelist_cache ORDER BY ip;"
|
||||
```
|
||||
|
||||
### GeoIP-Cache
|
||||
|
||||
```bash
|
||||
sudo sqlite3 /var/lib/adguard-shield/adguard-shield.db \
|
||||
"SELECT ip, country_code FROM geoip_cache ORDER BY ip LIMIT 50;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alte Shell-Artefakte entfernen
|
||||
|
||||
Wenn der Installer alte Dateien meldet, zuerst sauber migrieren. Typische alte Dateien:
|
||||
|
||||
```text
|
||||
adguard-shield.sh
|
||||
iptables-helper.sh
|
||||
external-blocklist-worker.sh
|
||||
external-whitelist-worker.sh
|
||||
geoip-worker.sh
|
||||
offense-cleanup-worker.sh
|
||||
report-generator.sh
|
||||
unban-expired.sh
|
||||
adguard-shield-watchdog.sh
|
||||
```
|
||||
| Datei | Funktion in der alten Version |
|
||||
|---|---|
|
||||
| `adguard-shield.sh` | Hauptskript |
|
||||
| `iptables-helper.sh` | Firewall-Management |
|
||||
| `external-blocklist-worker.sh` | Blocklist-Synchronisation |
|
||||
| `external-whitelist-worker.sh` | Whitelist-Synchronisation |
|
||||
| `geoip-worker.sh` | GeoIP-Prüfung |
|
||||
| `offense-cleanup-worker.sh` | Offense-Bereinigung |
|
||||
| `report-generator.sh` | Report-Erstellung |
|
||||
| `unban-expired.sh` | Ablauf temporärer Sperren |
|
||||
| `adguard-shield-watchdog.sh` | Watchdog-Skript |
|
||||
|
||||
Die Go-Version ersetzt diese Funktionen durch das eine Binary. Alte Worker sollten nicht parallel laufen.
|
||||
|
||||
Details zur Migration stehen in der [Update-Anleitung](update.md).
|
||||
|
||||
---
|
||||
|
||||
## Service hart zurücksetzen
|
||||
|
||||
Wenn der Zustand unklar ist:
|
||||
Wenn der Zustand unklar ist und ein sauberer Neustart nötig ist:
|
||||
|
||||
```bash
|
||||
# Service stoppen
|
||||
sudo systemctl stop adguard-shield
|
||||
|
||||
# Firewall-Struktur entfernen
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-remove
|
||||
|
||||
# Service neu starten (baut Firewall aus SQLite wieder auf)
|
||||
sudo systemctl start adguard-shield
|
||||
|
||||
# Status prüfen
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
```
|
||||
|
||||
Das entfernt die Firewall-Struktur und lässt den Daemon sie beim Start wieder aus SQLite aufbauen.
|
||||
Das entfernt die Firewall-Struktur und lässt den Daemon sie beim Start wieder aus dem SQLite-State aufbauen. Aktive Sperren bleiben in der Datenbank erhalten.
|
||||
|
||||
---
|
||||
|
||||
## Deinstallation
|
||||
|
||||
Konfiguration behalten:
|
||||
### Konfiguration behalten
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield uninstall --keep-config
|
||||
```
|
||||
|
||||
Alles entfernen:
|
||||
### Alles entfernen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield uninstall
|
||||
```
|
||||
|
||||
Ohne `--keep-config` werden Installationsverzeichnis, State-Verzeichnis und Logdatei entfernt.
|
||||
|
||||
---
|
||||
|
||||
## Zusammenfassung: Wichtigste Diagnosebefehle
|
||||
|
||||
| Befehl | Zweck |
|
||||
|---|---|
|
||||
| `systemctl status adguard-shield` | Service-Status prüfen |
|
||||
| `journalctl -u adguard-shield -n 100` | Systemd-Journal ansehen |
|
||||
| `test` | API-Verbindung prüfen |
|
||||
| `status` | Aktuellen Zustand und aktive Sperren anzeigen |
|
||||
| `live` | Echtzeit-Ansicht mit Queries, Sperren und Logs |
|
||||
| `history 100` | Ban-History anzeigen |
|
||||
| `logs --level warn --limit 100` | Warnungen und Fehler anzeigen |
|
||||
| `firewall-status` | Firewall-Regeln und ipsets anzeigen |
|
||||
| `dry-run` | Konfiguration testen ohne echte Sperren |
|
||||
|
||||
186
docs/update.md
186
docs/update.md
@@ -5,7 +5,7 @@ AdGuard Shield wird in der Go-Version über das Binary selbst installiert und ak
|
||||
## Kurzfassung
|
||||
|
||||
```bash
|
||||
# neues Linux-Binary bereitstellen
|
||||
# Neues Linux-Binary bereitstellen
|
||||
chmod +x ./adguard-shield
|
||||
|
||||
# Update durchführen
|
||||
@@ -14,7 +14,7 @@ sudo ./adguard-shield update
|
||||
|
||||
Am Ende fragt der Updater, ob AdGuard Shield direkt neu gestartet werden soll.
|
||||
|
||||
Danach prüfen:
|
||||
### Nach dem Update prüfen
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield install-status
|
||||
@@ -22,11 +22,13 @@ sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo journalctl -u adguard-shield --no-pager -n 50
|
||||
```
|
||||
|
||||
## Woher kommt das neue Binary?
|
||||
---
|
||||
|
||||
## Neues Binary beziehen
|
||||
|
||||
Du brauchst ein fertiges Linux-Binary. Das kann aus einem Release, aus CI oder aus einem lokalen Build kommen.
|
||||
|
||||
Release-Binary für v1.0.0 herunterladen:
|
||||
### Variante A: Release-Binary herunterladen
|
||||
|
||||
```bash
|
||||
curl -fL -o adguard-shield-linux-amd64.tar.gz \
|
||||
@@ -35,13 +37,13 @@ tar -xzf adguard-shield-linux-amd64.tar.gz
|
||||
chmod +x ./adguard-shield
|
||||
```
|
||||
|
||||
Build mit lokal installiertem Go:
|
||||
### Variante B: Lokal mit Go bauen
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o adguard-shield ./cmd/adguard-shieldd
|
||||
```
|
||||
|
||||
Build ohne lokale Go-Installation mit Docker:
|
||||
### Variante C: Per Docker bauen (ohne lokales Go)
|
||||
|
||||
```bash
|
||||
docker run --rm -v "$PWD":/src -w /src \
|
||||
@@ -51,41 +53,59 @@ docker run --rm -v "$PWD":/src -w /src \
|
||||
|
||||
Auf dem Zielserver muss Go nicht installiert sein, wenn dort nur das fertige Binary ausgeführt wird.
|
||||
|
||||
---
|
||||
|
||||
## Was `update` macht
|
||||
|
||||
Der Update-Befehl nutzt intern dieselbe Routine wie die Installation:
|
||||
|
||||
1. Linux- und root-Rechte prüfen.
|
||||
2. Auf alte Shell-Artefakte prüfen.
|
||||
3. Systemabhängigkeiten prüfen, sofern nicht `--skip-deps` gesetzt ist.
|
||||
4. Installationsverzeichnis sicherstellen.
|
||||
5. neues Binary nach `/opt/adguard-shield/adguard-shield` kopieren.
|
||||
6. Konfiguration migrieren.
|
||||
7. systemd-Service neu schreiben.
|
||||
8. `systemctl daemon-reload` ausführen.
|
||||
9. Autostart aktivieren, sofern nicht `--no-enable` gesetzt ist.
|
||||
10. fragen, ob der Service direkt neu gestartet werden soll.
|
||||
| Schritt | Aktion |
|
||||
|---:|---|
|
||||
| 1 | Linux- und Root-Rechte prüfen |
|
||||
| 2 | Auf alte Shell-Artefakte prüfen |
|
||||
| 3 | Systemabhängigkeiten prüfen (sofern nicht `--skip-deps`) |
|
||||
| 4 | Installationsverzeichnis sicherstellen |
|
||||
| 5 | Neues Binary nach `/opt/adguard-shield/adguard-shield` kopieren |
|
||||
| 6 | Konfiguration migrieren (vorhandene Werte behalten, neue ergänzen) |
|
||||
| 7 | systemd-Service neu schreiben |
|
||||
| 8 | `systemctl daemon-reload` |
|
||||
| 9 | Autostart aktivieren (sofern nicht `--no-enable`) |
|
||||
| 10 | Nachfrage: Service direkt neu starten |
|
||||
|
||||
---
|
||||
|
||||
## Konfigurationsmigration
|
||||
|
||||
Vorhandene Werte bleiben erhalten. Neue Parameter werden ergänzt.
|
||||
Vorhandene Werte bleiben erhalten. Neue Parameter werden am Ende der Datei ergänzt. Der Installer überschreibt keine bestehenden Einstellungen.
|
||||
|
||||
Wenn eine Migration nötig ist:
|
||||
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield.conf # aktualisierte Konfiguration
|
||||
/opt/adguard-shield/adguard-shield.conf.old # Backup der vorherigen Datei
|
||||
```
|
||||
| Datei | Inhalt |
|
||||
|---|---|
|
||||
| `adguard-shield.conf` | Aktualisierte Konfiguration mit alten + neuen Parametern |
|
||||
| `adguard-shield.conf.old` | Backup der vorherigen Datei |
|
||||
|
||||
Nach dem Update solltest du prüfen:
|
||||
### Änderungen prüfen
|
||||
|
||||
```bash
|
||||
sudo diff -u /opt/adguard-shield/adguard-shield.conf.old /opt/adguard-shield/adguard-shield.conf
|
||||
```
|
||||
|
||||
Falls `diff` keine Datei findet, war keine Konfigurationsmigration nötig.
|
||||
Falls `diff` keine `.old`-Datei findet, war keine Konfigurationsmigration nötig.
|
||||
|
||||
## Update mit Service-Neustart
|
||||
### Neue Parameter prüfen
|
||||
|
||||
Nach dem Update solltest du die neu ergänzten Parameter überprüfen und bei Bedarf anpassen:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Update-Optionen
|
||||
|
||||
### Update mit Service-Neustart
|
||||
|
||||
Wenn der Service nach dem Update direkt laufen soll, bestätige die Nachfrage am Ende mit `j`.
|
||||
|
||||
@@ -98,141 +118,167 @@ sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
## Update ohne Paketprüfung
|
||||
### Update ohne Paketprüfung
|
||||
|
||||
```bash
|
||||
sudo ./adguard-shield update --skip-deps
|
||||
```
|
||||
|
||||
Das ist sinnvoll, wenn du sicher weißt, dass `iptables`, `ip6tables`, `ipset` und `systemctl` vorhanden sind oder wenn Paketinstallation auf deinem System nicht über `apt-get` laufen soll.
|
||||
Sinnvoll, wenn `iptables`, `ip6tables`, `ipset` und `systemctl` bereits vorhanden sind oder die Paketinstallation nicht über `apt-get` laufen soll.
|
||||
|
||||
## Update in anderem Installationsverzeichnis
|
||||
### Update mit expliziter Konfigurationsquelle
|
||||
|
||||
```bash
|
||||
sudo ./adguard-shield update --config-source ./adguard-shield.conf
|
||||
```
|
||||
|
||||
### Update in anderem Installationsverzeichnis
|
||||
|
||||
```bash
|
||||
sudo ./adguard-shield update --install-dir /opt/adguard-shield-test
|
||||
```
|
||||
|
||||
Beachte: Die systemd-Unit heißt weiterhin `adguard-shield.service`. Mehrere parallele produktive Installationen über dieselbe Unit sind nicht vorgesehen.
|
||||
**Hinweis:** Die systemd-Unit heißt weiterhin `adguard-shield.service`. Mehrere parallele produktive Installationen über dieselbe Unit sind nicht vorgesehen.
|
||||
|
||||
---
|
||||
|
||||
## Migration von der alten Shell-Version
|
||||
|
||||
Die Go-Version erkennt alte Shell-Artefakte und bricht ab, wenn sie noch vorhanden sind.
|
||||
|
||||
Typische Funde:
|
||||
### Typische alte Artefakte
|
||||
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield.sh
|
||||
/opt/adguard-shield/iptables-helper.sh
|
||||
/opt/adguard-shield/external-blocklist-worker.sh
|
||||
/opt/adguard-shield/external-whitelist-worker.sh
|
||||
/opt/adguard-shield/geoip-worker.sh
|
||||
/opt/adguard-shield/offense-cleanup-worker.sh
|
||||
/opt/adguard-shield/report-generator.sh
|
||||
/opt/adguard-shield/unban-expired.sh
|
||||
/etc/systemd/system/adguard-shield-watchdog.service
|
||||
/etc/systemd/system/adguard-shield-watchdog.timer
|
||||
```
|
||||
| Datei | Funktion in der alten Version |
|
||||
|---|---|
|
||||
| `adguard-shield.sh` | Hauptskript |
|
||||
| `iptables-helper.sh` | Firewall-Management |
|
||||
| `external-blocklist-worker.sh` | Blocklist-Synchronisation |
|
||||
| `external-whitelist-worker.sh` | Whitelist-Synchronisation |
|
||||
| `geoip-worker.sh` | GeoIP-Prüfung |
|
||||
| `offense-cleanup-worker.sh` | Offense-Bereinigung |
|
||||
| `report-generator.sh` | Report-Erstellung |
|
||||
| `unban-expired.sh` | Ablauf temporärer Sperren |
|
||||
| `adguard-shield-watchdog.service` | Watchdog-Service |
|
||||
| `adguard-shield-watchdog.timer` | Watchdog-Timer |
|
||||
|
||||
Warum Abbruch?
|
||||
### Warum bricht der Installer ab?
|
||||
|
||||
Die alte und die neue Version würden sonst dieselbe Firewall, dieselbe Konfiguration und dieselben Sperren verwalten. Das kann zu schwer nachvollziehbaren Zuständen führen.
|
||||
Die alte und die neue Version würden sonst dieselbe Firewall, dieselbe Konfiguration und dieselben Sperren verwalten. Das kann zu schwer nachvollziehbaren Zuständen führen, bei denen zwei Implementierungen sich gegenseitig die Regeln überschreiben.
|
||||
|
||||
Empfohlener Migrationsablauf:
|
||||
### Empfohlener Migrationsablauf
|
||||
|
||||
```bash
|
||||
# Konfiguration sichern
|
||||
# 1. Konfiguration sichern
|
||||
sudo cp /opt/adguard-shield/adguard-shield.conf /root/adguard-shield.conf.backup
|
||||
|
||||
# alte Shell-Version mit deren Uninstaller entfernen
|
||||
# dabei Konfiguration behalten, falls der alte Uninstaller diese Option anbietet
|
||||
# 2. Alte Shell-Version mit deren Uninstaller entfernen
|
||||
# (dabei Konfiguration behalten, falls der alte Uninstaller diese Option anbietet)
|
||||
|
||||
# neues Go-Binary installieren und alte Konfiguration als Quelle nutzen
|
||||
# 3. Neues Go-Binary installieren und alte Konfiguration als Quelle nutzen
|
||||
sudo ./adguard-shield install --config-source /root/adguard-shield.conf.backup
|
||||
|
||||
# prüfen
|
||||
# 4. API-Verbindung prüfen
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
|
||||
# 5. Dry-Run: prüfen, was gesperrt würde
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
|
||||
# 6. Produktiven Service starten
|
||||
sudo systemctl start adguard-shield
|
||||
sudo systemctl status adguard-shield
|
||||
```
|
||||
|
||||
Wenn der Go-Installer Legacy-Dateien meldet, entferne nur die gemeldeten alten Artefakte der Shell-Version. Keine fremden Firewall-Regeln oder unrelated Dateien löschen.
|
||||
**Wichtig:** Wenn der Go-Installer Legacy-Dateien meldet, entferne nur die gemeldeten alten Artefakte der Shell-Version. Keine fremden Firewall-Regeln oder unrelated Dateien löschen.
|
||||
|
||||
---
|
||||
|
||||
## Nach dem Update prüfen
|
||||
|
||||
Installation:
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield install-status
|
||||
```
|
||||
|
||||
Service:
|
||||
### Service
|
||||
|
||||
```bash
|
||||
sudo systemctl status adguard-shield
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
```
|
||||
|
||||
API:
|
||||
### API-Verbindung
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
```
|
||||
|
||||
Runtime:
|
||||
### Laufzeitstatus
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield live --once
|
||||
```
|
||||
|
||||
Firewall:
|
||||
### Firewall
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rollback
|
||||
|
||||
Ein Rollback besteht aus zwei Teilen: altes Binary wieder bereitstellen und passende Konfiguration verwenden.
|
||||
|
||||
Vorgehen:
|
||||
|
||||
1. Service stoppen.
|
||||
2. altes Binary nach `/opt/adguard-shield/adguard-shield` kopieren.
|
||||
3. optional `adguard-shield.conf.old` zurückkopieren.
|
||||
4. Service starten.
|
||||
|
||||
Beispiel:
|
||||
### Schritt-für-Schritt
|
||||
|
||||
```bash
|
||||
# 1. Service stoppen
|
||||
sudo systemctl stop adguard-shield
|
||||
|
||||
# 2. Altes Binary wiederherstellen
|
||||
sudo cp ./adguard-shield-alte-version /opt/adguard-shield/adguard-shield
|
||||
sudo chmod +x /opt/adguard-shield/adguard-shield
|
||||
|
||||
# 3. Service starten
|
||||
sudo systemctl start adguard-shield
|
||||
```
|
||||
|
||||
Wenn die Konfiguration zurückgesetzt werden soll:
|
||||
### Konfiguration zurücksetzen (optional)
|
||||
|
||||
```bash
|
||||
sudo cp /opt/adguard-shield/adguard-shield.conf.old /opt/adguard-shield/adguard-shield.conf
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
Hinweis: SQLite-Schema-Migrationen sind aktuell sehr konservativ. Trotzdem solltest du vor größeren Updates ein Backup von `/var/lib/adguard-shield/adguard-shield.db` erstellen, wenn dir History und aktive Sperren wichtig sind.
|
||||
**Hinweis:** SQLite-Schema-Migrationen sind aktuell sehr konservativ. Trotzdem solltest du vor größeren Updates ein Backup der Datenbank erstellen, wenn dir History und aktive Sperren wichtig sind.
|
||||
|
||||
---
|
||||
|
||||
## Backup vor größeren Updates
|
||||
|
||||
```bash
|
||||
# Service kurz stoppen für konsistentes Backup
|
||||
sudo systemctl stop adguard-shield
|
||||
|
||||
# Konfiguration und Datenbank sichern
|
||||
sudo cp /opt/adguard-shield/adguard-shield.conf /root/adguard-shield.conf.$(date +%F)
|
||||
sudo cp /var/lib/adguard-shield/adguard-shield.db /root/adguard-shield.db.$(date +%F)
|
||||
|
||||
# Service wieder starten
|
||||
sudo systemctl start adguard-shield
|
||||
```
|
||||
|
||||
### WAL-Dateien beachten
|
||||
|
||||
Bei laufendem SQLite mit WAL können zusätzliche Dateien existieren:
|
||||
|
||||
```text
|
||||
adguard-shield.db-wal
|
||||
adguard-shield.db-shm
|
||||
```
|
||||
| Datei | Beschreibung |
|
||||
|---|---|
|
||||
| `adguard-shield.db` | Hauptdatenbank |
|
||||
| `adguard-shield.db-wal` | Write-Ahead-Log (enthält noch nicht in die Hauptdatei geschriebene Daten) |
|
||||
| `adguard-shield.db-shm` | Shared-Memory-Datei |
|
||||
|
||||
Am saubersten ist ein kurzer Service-Stop während des Backups.
|
||||
Am saubersten ist ein kurzer Service-Stop während des Backups. So wird sichergestellt, dass alle WAL-Einträge in die Hauptdatei geschrieben werden.
|
||||
|
||||
Reference in New Issue
Block a user