feat!: Migration auf Go-Binary
BREAKING CHANGE: Die alte Shell-Version muss vor der Installation der Go-Version deinstalliert werden.
This commit is contained in:
@@ -1,15 +1,59 @@
|
||||
# Dokumentation
|
||||
|
||||
Hier findest du die vollständige Dokumentation zu AdGuard Shield.
|
||||
Willkommen in der Dokumentation von AdGuard Shield.
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
AdGuard Shield ist ein Go-Daemon, der das Query Log von AdGuard Home auswertet, auffällige DNS-Clients erkennt und diese über eine eigene Firewall-Struktur sperrt. Die Dokumentation ist bewusst ausführlich gehalten: Sie soll nicht nur Befehle auflisten, sondern erklären, was im Hintergrund passiert, welche Werte sinnvoll sind und wie du Fehler sauber eingrenzt.
|
||||
|
||||
| Dokument | Beschreibung |
|
||||
## Schnellnavigation
|
||||
|
||||
| Dokument | Wofür es gedacht ist |
|
||||
|---|---|
|
||||
| [Architektur & Funktionsweise](architektur.md) | Überblick über den Systemaufbau, Datenfluss und die internen Komponenten |
|
||||
| [Befehle & Nutzung](befehle.md) | Alle verfügbaren Befehle des Installers, des Hauptskripts und des Watchdogs |
|
||||
| [Konfiguration](konfiguration.md) | Beschreibung aller Konfigurationsparameter in `adguard-shield.conf` |
|
||||
| [Webhook-Benachrichtigungen](benachrichtigungen.md) | Einrichtung von Push-Benachrichtigungen über Telegram, Discord, Gotify u.a. |
|
||||
| [E-Mail Report](report.md) | Konfiguration des automatischen Statistik-Reports per E-Mail |
|
||||
| [Update-Anleitung](update.md) | Schritt-für-Schritt-Anleitung zum Aktualisieren einer bestehenden Installation |
|
||||
| [Tipps & Troubleshooting](tipps-und-troubleshooting.md) | Best Practices, häufige Probleme und deren Lösungen |
|
||||
| [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 |
|
||||
| [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 |
|
||||
|
||||
## Wichtigster Unterschied zur alten Shell-Version
|
||||
|
||||
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:
|
||||
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
Die meisten Befehle beginnen daher mit:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield <befehl>
|
||||
```
|
||||
|
||||
Für Installation oder Update nutzt du das neue Binary aus dem Repository, Release oder Build-Verzeichnis:
|
||||
|
||||
```bash
|
||||
sudo ./adguard-shield install
|
||||
sudo ./adguard-shield update
|
||||
```
|
||||
|
||||
## Empfohlener Lesefluss
|
||||
|
||||
Wenn du AdGuard Shield neu einrichtest:
|
||||
|
||||
1. Lies zuerst [Architektur & Funktionsweise](architektur.md), damit klar ist, was genau gesperrt wird.
|
||||
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).
|
||||
|
||||
@@ -1,232 +1,407 @@
|
||||
# Architektur & Funktionsweise
|
||||
|
||||
## Überblick
|
||||
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.
|
||||
|
||||
```
|
||||
┌─────────────────────┐
|
||||
│ Client Anfragen │
|
||||
│ (DNS/DoH/DoT/DoQ) │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐ ┌──────────────────────┐
|
||||
│ AdGuard Home │────▶ │ Query Log (API) │
|
||||
│ DNS Server │ └──────────┬───────────┘
|
||||
└─────────────────────┘ │
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ adguard-shield.sh │
|
||||
│ (Monitor Script) │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
┌──────────────┼──────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ iptables │ │ Log │ │ Webhook │
|
||||
│ DROP │ │ Datei │ │ Notify │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
## Kurzüberblick
|
||||
|
||||
AdGuard Shield besteht in der Go-Version aus einem einzelnen Binary:
|
||||
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield
|
||||
```
|
||||
|
||||
## Ablauf einer Sperre
|
||||
Das Binary übernimmt alle Aufgaben, die früher auf mehrere Shell-Skripte verteilt waren:
|
||||
|
||||
### Rate-Limit-Sperre
|
||||
- Querylog-Polling über die AdGuard-Home-API
|
||||
- Erkennung von Rate-Limit-Verstößen
|
||||
- Erkennung von Random-Subdomain-Floods
|
||||
- DNS-Flood-Watchlist mit sofortigem Permanent-Ban
|
||||
- Verwaltung aktiver Sperren in SQLite
|
||||
- Firewall-Steuerung über `ipset`, `iptables` und `ip6tables`
|
||||
- automatische Freigabe abgelaufener temporärer Sperren
|
||||
- externe Blocklisten und externe Whitelists
|
||||
- GeoIP-Länderfilter
|
||||
- progressive Sperren für Wiederholungstäter
|
||||
- Benachrichtigungen und AbuseIPDB-Reporting
|
||||
- E-Mail-Reports
|
||||
|
||||
1. Client `192.168.1.50` fragt `microsoft.com` 45x in 60 Sekunden an
|
||||
2. Monitor fragt die AdGuard Home API alle 10 Sekunden ab (`/control/querylog`)
|
||||
3. Die Anfragen werden pro Client+Domain-Kombination gezählt
|
||||
4. Monitor erkennt: 45 > 30 (Limit überschritten)
|
||||
5. Prüfung: Ist der Client auf der Whitelist? → Nein
|
||||
6. **Progressive Sperren:** Offense-Level wird geprüft/erhöht, Sperrdauer berechnet
|
||||
7. iptables-Regel wird erstellt: `DROP` für `192.168.1.50` auf allen DNS-Ports
|
||||
8. State-Datei wird angelegt: `/var/lib/adguard-shield/192.168.1.50.ban`
|
||||
9. Offense-Datei wird aktualisiert: `/var/lib/adguard-shield/192.168.1.50.offenses`
|
||||
10. Ban-History Eintrag wird in `/var/log/adguard-shield-bans.log` geschrieben
|
||||
11. Log-Eintrag + optionale Webhook-Benachrichtigung
|
||||
12. Nach Ablauf der (progressiven) Sperrdauer: automatische Entsperrung + History-Eintrag
|
||||
## Datenfluss
|
||||
|
||||
### Subdomain-Flood-Sperre (Random Subdomain Attack)
|
||||
|
||||
1. Client `10.0.0.99` fragt `abc123.microsoft.com`, `xyz456.microsoft.com`, ... ab
|
||||
2. Monitor extrahiert die **Basisdomain** (`microsoft.com`) aus jeder Anfrage
|
||||
3. Pro Client wird gezählt, wie viele **eindeutige Subdomains** einer Basisdomain im Zeitfenster abgefragt wurden
|
||||
4. Monitor erkennt: 63 eindeutige Subdomains > 50 (Schwellwert überschritten)
|
||||
5. Prüfung: Ist der Client auf der Whitelist? → Nein
|
||||
6. Sperre wird ausgeführt mit Domain `*.microsoft.com` und Grund `subdomain-flood`
|
||||
7. Progressive Sperren greifen auch hier — Wiederholungstäter werden stufenweise länger gesperrt
|
||||
|
||||
> **Hinweis:** Die Subdomain-Flood-Erkennung hat ein eigenes Zeitfenster (`SUBDOMAIN_FLOOD_WINDOW`) und einen eigenen Schwellwert (`SUBDOMAIN_FLOOD_MAX_UNIQUE`), unabhängig von den Rate-Limit-Einstellungen.
|
||||
|
||||
### DNS-Flood-Watchlist-Sperre
|
||||
|
||||
1. Client `10.0.0.42` fragt `microsoft.com` 35x in 60 Sekunden an
|
||||
2. Monitor erkennt: 35 > 30 (Limit überschritten)
|
||||
3. Domain `microsoft.com` steht auf der DNS-Flood-Watchlist → **sofortige permanente Sperre**
|
||||
4. Progressive-Ban-Stufe wird ignoriert — kein stufenweises Hochstufen
|
||||
5. IP wird an AbuseIPDB gemeldet (falls aktiviert)
|
||||
6. Permanente Sperre bleibt bis zur manuellen Freigabe aktiv
|
||||
|
||||
> **Hinweis:** Die Watchlist greift sowohl bei normalen Rate-Limit-Verstößen als auch bei Subdomain-Flood-Erkennungen. Subdomains werden automatisch erkannt: `foo.microsoft.com` matcht den Watchlist-Eintrag `microsoft.com`.
|
||||
|
||||
## iptables Strategie
|
||||
|
||||
Das Tool erstellt eine eigene Chain `ADGUARD_SHIELD`:
|
||||
|
||||
```
|
||||
INPUT Chain
|
||||
├── ... (bestehende Regeln bleiben unberührt)
|
||||
├── -p tcp --dport 53 → ADGUARD_SHIELD
|
||||
├── -p udp --dport 53 → ADGUARD_SHIELD
|
||||
├── -p tcp --dport 443 → ADGUARD_SHIELD
|
||||
├── -p udp --dport 443 → ADGUARD_SHIELD
|
||||
├── -p tcp --dport 853 → ADGUARD_SHIELD
|
||||
├── -p udp --dport 853 → ADGUARD_SHIELD
|
||||
└── ...
|
||||
|
||||
ADGUARD_SHIELD Chain
|
||||
├── -s 192.168.1.50 → DROP (gesperrter Client)
|
||||
├── -s 10.0.0.25 → DROP (gesperrter Client)
|
||||
└── RETURN (alle anderen passieren)
|
||||
```text
|
||||
Clients
|
||||
|
|
||||
| DNS, DoH, DoT, DoQ, DNSCrypt
|
||||
v
|
||||
AdGuard Home
|
||||
|
|
||||
| /control/querylog
|
||||
v
|
||||
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
|
||||
SQLite State
|
||||
|
|
||||
v
|
||||
ipset + iptables/ip6tables
|
||||
|
|
||||
v
|
||||
DNS-relevante Ports werden für gesperrte Clients blockiert
|
||||
```
|
||||
|
||||
**Vorteile der eigenen Chain:**
|
||||
- Greift nicht in bestehende Firewall-Regeln ein
|
||||
- Kann komplett geflusht werden ohne andere Regeln zu beeinflussen
|
||||
- Einfaches Debugging per `iptables -L ADGUARD_SHIELD`
|
||||
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.
|
||||
|
||||
## State-Management (SQLite)
|
||||
## Laufzeit im produktiven Betrieb
|
||||
|
||||
Alle Laufzeitdaten werden in einer zentralen SQLite-Datenbank gespeichert:
|
||||
Der systemd-Service startet den Daemon so:
|
||||
|
||||
```bash
|
||||
/opt/adguard-shield/adguard-shield -config /opt/adguard-shield/adguard-shield.conf run
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Querylog-Poller
|
||||
|
||||
Der Daemon ruft regelmäßig den AdGuard-Home-Endpunkt ab:
|
||||
|
||||
```text
|
||||
/control/querylog?limit=<API_QUERY_LIMIT>&response_status=all
|
||||
```
|
||||
|
||||
Gesteuert wird das über:
|
||||
|
||||
```bash
|
||||
CHECK_INTERVAL=10
|
||||
API_QUERY_LIMIT=500
|
||||
```
|
||||
|
||||
Aus jedem Querylog-Eintrag werden diese Informationen extrahiert:
|
||||
|
||||
| Feld | Verwendung |
|
||||
|---|---|
|
||||
| Zeitstempel | Bestimmt, ob die Anfrage im aktuellen Zeitfenster liegt |
|
||||
| Client-IP | Schlüssel für Rate-Limit, Whitelist, GeoIP und Firewall |
|
||||
| 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.
|
||||
|
||||
## Rate-Limit-Sperre
|
||||
|
||||
Eine Rate-Limit-Sperre entsteht, wenn ein Client dieselbe Domain innerhalb des konfigurierten Fensters zu oft abfragt.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
RATE_LIMIT_MAX_REQUESTS=30
|
||||
RATE_LIMIT_WINDOW=60
|
||||
```
|
||||
|
||||
Ablauf:
|
||||
|
||||
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.
|
||||
3. AdGuard Shield zählt pro Client und Domain.
|
||||
4. `45 > 30`, also ist das Limit überschritten.
|
||||
5. Die IP wird gegen statische und externe Whitelists geprüft.
|
||||
6. Falls die Domain nicht auf der Watchlist steht, entsteht eine normale `rate-limit`-Sperre.
|
||||
7. Bei aktivem Progressive-Ban wird die aktuelle Offense-Stufe berechnet.
|
||||
8. Die IP wird in SQLite gespeichert und per Firewall blockiert.
|
||||
9. History, Log und optionale Benachrichtigung werden geschrieben.
|
||||
|
||||
## 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:
|
||||
|
||||
```text
|
||||
a8f3.example.com
|
||||
k29x.example.com
|
||||
z9p1.example.com
|
||||
```
|
||||
|
||||
AdGuard Shield extrahiert daraus die Basisdomain `example.com` und zählt pro Client, wie viele unterschiedliche Subdomains im Fenster vorkommen.
|
||||
|
||||
Gesteuert wird das über:
|
||||
|
||||
```bash
|
||||
SUBDOMAIN_FLOOD_ENABLED=true
|
||||
SUBDOMAIN_FLOOD_MAX_UNIQUE=50
|
||||
SUBDOMAIN_FLOOD_WINDOW=60
|
||||
```
|
||||
|
||||
Ablauf:
|
||||
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
```bash
|
||||
DNS_FLOOD_WATCHLIST_ENABLED=true
|
||||
DNS_FLOOD_WATCHLIST="microsoft.com,google.com"
|
||||
```
|
||||
|
||||
Matching:
|
||||
|
||||
- `microsoft.com` matcht `microsoft.com`
|
||||
- `login.microsoft.com` matcht ebenfalls `microsoft.com`
|
||||
- `evil-microsoft.com` matcht nicht
|
||||
|
||||
Bei einem Treffer:
|
||||
|
||||
- Reason wird `dns-flood-watchlist`
|
||||
- Sperre ist 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
|
||||
|
||||
## Progressive Sperren
|
||||
|
||||
Progressive Sperren erhöhen die Sperrdauer bei wiederholten Monitor-Sperren. Das Verhalten ähnelt fail2ban.
|
||||
|
||||
Standard:
|
||||
|
||||
```bash
|
||||
BAN_DURATION=3600
|
||||
PROGRESSIVE_BAN_ENABLED=true
|
||||
PROGRESSIVE_BAN_MULTIPLIER=2
|
||||
PROGRESSIVE_BAN_MAX_LEVEL=5
|
||||
PROGRESSIVE_BAN_RESET_AFTER=86400
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
| Vergehen | Stufe | Dauer |
|
||||
|---|---:|---|
|
||||
| 1 | 1 | 1 Stunde |
|
||||
| 2 | 2 | 2 Stunden |
|
||||
| 3 | 3 | 4 Stunden |
|
||||
| 4 | 4 | 8 Stunden |
|
||||
| 5 | 5 | 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.
|
||||
|
||||
Progressive Sperren gelten für Monitor-Sperren. GeoIP- und externe Blocklist-Sperren haben eigene Regeln.
|
||||
|
||||
## Firewall-Modell
|
||||
|
||||
AdGuard Shield nutzt eine eigene Chain und zwei ipsets:
|
||||
|
||||
```text
|
||||
ADGUARD_SHIELD
|
||||
adguard_shield_v4
|
||||
adguard_shield_v6
|
||||
```
|
||||
|
||||
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` |
|
||||
|
||||
Für klassische Installationen und Docker mit Host-Netzwerk sieht das so aus:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Die Ports kommen aus:
|
||||
|
||||
```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.
|
||||
|
||||
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
|
||||
|
||||
## SQLite-State
|
||||
|
||||
Der zentrale Zustand liegt standardmäßig hier:
|
||||
|
||||
```text
|
||||
/var/lib/adguard-shield/adguard-shield.db
|
||||
```
|
||||
|
||||
Die Datenbank enthält folgende Tabellen:
|
||||
Wichtige Tabellen:
|
||||
|
||||
| Tabelle | Beschreibung |
|
||||
|---------|--------------|
|
||||
| `active_bans` | Aktive Sperren (IP, Domain, Sperrdauer, Offense-Level, Grund, Quelle, GeoIP) |
|
||||
| `offense_tracking` | Offense-Zähler für progressive Sperren (Level, letztes/erstes Vergehen) |
|
||||
| `ban_history` | Vollständige Ban-History (alle Sperren und Entsperrungen) |
|
||||
| `whitelist_cache` | Cache der aufgelösten externen Whitelist-IPs |
|
||||
| `schema_version` | Datenbank-Schema-Version für zukünftige Migrationen |
|
||||
| Tabelle | Inhalt |
|
||||
|---|---|
|
||||
| `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 |
|
||||
|
||||
**Vorteile gegenüber Flat-Files:**
|
||||
- Schnellere Abfragen, besonders bei vielen aktiven Sperren
|
||||
- Atomare Transaktionen — kein Datenverlust bei Stromausfall
|
||||
- WAL-Modus für parallelen Lese-/Schreibzugriff
|
||||
- Indexierte Suche nach IP, Zeitstempel, Quelle und Aktion
|
||||
- Kompakte Speicherung statt tausender Einzeldateien
|
||||
Die Datenbank nutzt WAL-Modus und einen Busy-Timeout, damit Daemon und CLI-Befehle gleichzeitig lesen können.
|
||||
|
||||
Die zentrale Datenbankbibliothek (`db.sh`) wird von allen Scripts per `source db.sh` eingebunden und stellt typisierte Funktionen für alle Tabellen bereit (z.B. `db_ban_insert`, `db_offense_get_level`, `db_history_add`).
|
||||
## Verzeichnisstruktur
|
||||
|
||||
### Migration von Flat-Files
|
||||
Nach einer Standardinstallation sieht die Struktur so aus:
|
||||
|
||||
Beim Update auf die SQLite-Version werden bestehende Flat-File-Daten (`.ban`, `.offenses`, Ban-History-Log, Whitelist-Cache) automatisch in die Datenbank migriert. Die alten Dateien werden als Backup nach `/var/lib/adguard-shield/.backup_pre_sqlite/` verschoben. Die Migration läuft einmalig beim Update und zeigt den Fortschritt im Terminal an.
|
||||
|
||||
## Dateistruktur nach Installation
|
||||
|
||||
```
|
||||
```text
|
||||
/opt/adguard-shield/
|
||||
├── adguard-shield.sh # Haupt-Monitor-Script
|
||||
├── adguard-shield.conf # Konfiguration (chmod 600)
|
||||
├── adguard-shield.conf.old # Backup der Konfig nach Update
|
||||
├── adguard-shield-watchdog.sh # Watchdog Health-Check-Script
|
||||
├── iptables-helper.sh # iptables Verwaltung
|
||||
├── external-blocklist-worker.sh # Externer Blocklist-Worker
|
||||
├── external-whitelist-worker.sh # Externer Whitelist-Worker (DNS-Auflösung)
|
||||
├── geoip-worker.sh # GeoIP-Länderfilter-Worker
|
||||
├── offense-cleanup-worker.sh # Aufräumen abgelaufener Offense-Zähler (nice 19, idle I/O)
|
||||
├── db.sh # SQLite Datenbank-Bibliothek (wird von allen Scripts eingebunden)
|
||||
├── unban-expired.sh # Cron-basiertes Entsperren
|
||||
└── geoip/ # Auto-Download MaxMind GeoLite2 DB (optional)
|
||||
├── adguard-shield # Go-Binary
|
||||
├── adguard-shield.conf # Konfiguration, chmod 600
|
||||
├── adguard-shield.conf.old # Backup nach Konfigurationsmigration
|
||||
└── geoip/ # automatische MaxMind-Downloads
|
||||
|
||||
/etc/systemd/system/
|
||||
├── adguard-shield.service # systemd Service (Autostart aktiv)
|
||||
├── adguard-shield-watchdog.service # systemd Watchdog-Unit (oneshot)
|
||||
└── adguard-shield-watchdog.timer # systemd Timer (alle 5 Min.)
|
||||
└── adguard-shield.service
|
||||
|
||||
/var/lib/adguard-shield/
|
||||
├── adguard-shield.db # SQLite-Datenbank (Bans, Offenses, History, Whitelist-Cache)
|
||||
├── .migration_v1_complete # Marker: Flat-File-Migration abgeschlossen
|
||||
├── .backup_pre_sqlite/ # Backup der alten Flat-Files nach Migration
|
||||
├── external-blocklist/ # Cache für externe Blocklisten
|
||||
├── external-whitelist/ # Cache für externe Whitelisten
|
||||
└── geoip-cache/ # Cache für GeoIP-Lookups (24h)
|
||||
├── adguard-shield.db
|
||||
├── external-blocklist/
|
||||
├── external-whitelist/
|
||||
├── iptables-rules.v4
|
||||
└── iptables-rules.v6
|
||||
|
||||
/var/log/
|
||||
├── adguard-shield.log # Laufzeit-Log
|
||||
└── adguard-shield-bans.log # Ban-History (Legacy, wird nach Migration nicht mehr geschrieben)
|
||||
└── adguard-shield.log
|
||||
```
|
||||
|
||||
## Installer-Architektur
|
||||
## Hintergrundjobs im Daemon
|
||||
|
||||
Der Installer (`install.sh`) bietet ein interaktives Menü und folgende Funktionen:
|
||||
Es gibt in der Go-Version keine separaten Worker-Skripte mehr. Diese Aufgaben laufen als Goroutines im Daemon:
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|--------|--------------|
|
||||
| `install` | Vollständige Neuinstallation (Abhängigkeiten, Dateien, Konfiguration, Service, Watchdog) |
|
||||
| `update` | Update mit automatischer Konfigurations-Migration, Datenbank-Migration, Watchdog-Aktivierung und Service-Neustart |
|
||||
| `uninstall` | Deinstallation mit optionalem Behalten der Konfiguration |
|
||||
| `status` | Installationsstatus, Version und Service-Status anzeigen |
|
||||
| `--help` | Hilfe und Befehlsübersicht |
|
||||
| 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 |
|
||||
|
||||
### Konfigurations-Migration beim Update
|
||||
Externe Whitelist und Blocklist laufen sofort beim Start einmalig und danach im jeweiligen Intervall.
|
||||
|
||||
```
|
||||
┌─────────────────────────┐ ┌─────────────────────────┐
|
||||
│ Bestehende Konfig │ │ Neue Konfig (Repo) │
|
||||
│ (Benutzer-Settings) │ │ (mit neuen Parametern) │
|
||||
└───────────┬─────────────┘ └───────────┬─────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────────────────────────────────┐
|
||||
│ Konfigurations-Migration │
|
||||
│ 1. Backup als .conf.old erstellen │
|
||||
│ 2. Alle Schlüssel vergleichen │
|
||||
│ 3. Neue Schlüssel zur Konfig ergänzen │
|
||||
│ 4. Bestehende Werte NICHT ändern │
|
||||
└──────────────────────┬───────────────────┘
|
||||
▼
|
||||
┌──────────────────────────┐
|
||||
│ Aktualisierte Konfig │
|
||||
│ (alte Werte + neue Keys) │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
## Whitelist-Logik
|
||||
|
||||
## Ban-History
|
||||
Vor jeder Sperre wird geprüft, ob die IP vertrauenswürdig ist.
|
||||
|
||||
Jede Sperre und Entsperrung wird dauerhaft in der SQLite-Datenbank protokolliert (Tabelle `ban_history`). Das ermöglicht eine lückenlose Nachvollziehbarkeit mit indexierter Suche nach IP, Zeitstempel und Aktion.
|
||||
Quellen:
|
||||
|
||||
**Gespeicherte Felder pro Eintrag:**
|
||||
| Feld | Beschreibung |
|
||||
|------|--------------|
|
||||
| `timestamp_epoch` | Unix-Zeitstempel |
|
||||
| `timestamp_text` | Lesbarer Zeitstempel |
|
||||
| `action` | `BAN` oder `UNBAN` |
|
||||
| `client_ip` | Betroffene IP-Adresse |
|
||||
| `domain` | Angefragte Domain |
|
||||
| `count` | Anzahl der Anfragen |
|
||||
| `duration` | Sperrdauer |
|
||||
| `protocol` | Verwendetes DNS-Protokoll |
|
||||
| `reason` | Sperrgrund |
|
||||
- statische `WHITELIST` aus der Konfiguration
|
||||
- aufgelöste IPs aus externen Whitelists
|
||||
|
||||
**Mögliche Gründe (GRUND-Spalte):**
|
||||
| Grund | Bedeutung |
|
||||
|-------|----------|
|
||||
| `rate-limit` | Automatische Sperre wegen Limit-Überschreitung |
|
||||
| `subdomain-flood` | Sperre wegen zu vieler eindeutiger Subdomains einer Basisdomain |
|
||||
| `dns-flood-watchlist` | Sofortige permanente Sperre + AbuseIPDB-Meldung (Domain auf der Watchlist) |
|
||||
| `dry-run` | Im Dry-Run erkannt (nicht wirklich gesperrt) |
|
||||
| `dry-run (subdomain-flood)` | Subdomain-Flood im Dry-Run erkannt |
|
||||
| `dry-run (dns-flood-watchlist)` | Watchlist-Treffer im Dry-Run erkannt |
|
||||
| `expired` | Automatisch entsperrt nach Ablauf der Sperrdauer |
|
||||
| `expired-cron` | Entsperrt durch den Cron-Job (`unban-expired.sh`) |
|
||||
| `manual` | Manuell entsperrt per `unban`-Befehl |
|
||||
| `manual-flush` | Entsperrt durch `flush`-Befehl (alle Sperren aufgehoben) |
|
||||
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.
|
||||
|
||||
## GeoIP-Logik
|
||||
|
||||
GeoIP arbeitet nur mit öffentlichen IPs, wenn `GEOIP_SKIP_PRIVATE=true` gesetzt ist. Private Netze, Loopback, Link-Local und CGNAT werden übersprungen.
|
||||
|
||||
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 |
|
||||
|
||||
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.
|
||||
|
||||
## AbuseIPDB-Reporting
|
||||
|
||||
AbuseIPDB wird nur für permanente Monitor-Sperren genutzt:
|
||||
|
||||
- DNS-Flood-Watchlist-Treffer
|
||||
- Progressive-Ban-Sperren, die die maximale Stufe erreicht haben
|
||||
|
||||
Nicht gemeldet werden:
|
||||
|
||||
- temporäre Rate-Limit-Sperren
|
||||
- manuelle Sperren
|
||||
- GeoIP-Sperren
|
||||
- externe Blocklist-Sperren
|
||||
|
||||
Voraussetzung:
|
||||
|
||||
**History anzeigen:**
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh history # letzte 50
|
||||
sudo /opt/adguard-shield/adguard-shield.sh history 200 # letzte 200
|
||||
ABUSEIPDB_ENABLED=true
|
||||
ABUSEIPDB_API_KEY="..."
|
||||
```
|
||||
|
||||
## History und Logs
|
||||
|
||||
Es gibt zwei unterschiedliche Blickwinkel:
|
||||
|
||||
| Quelle | Inhalt |
|
||||
|---|---|
|
||||
| `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
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
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.
|
||||
|
||||
977
docs/befehle.md
977
docs/befehle.md
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,47 @@
|
||||
# Webhook-Benachrichtigungen
|
||||
# Benachrichtigungen
|
||||
|
||||
Das Tool kann beim Starten und Stoppen des Services sowie bei Sperren und Entsperrungen Benachrichtigungen an verschiedene Dienste senden.
|
||||
AdGuard Shield kann Ereignisse an Ntfy, Discord, Slack, Gotify oder einen eigenen Webhook senden. Benachrichtigungen sind optional und werden über `adguard-shield.conf` gesteuert.
|
||||
|
||||
## Aktivierung
|
||||
Typische Ereignisse:
|
||||
|
||||
In der Konfiguration (`adguard-shield.conf`):
|
||||
- Service gestartet
|
||||
- Service gestoppt
|
||||
- automatische Sperre
|
||||
- manuelle Sperre
|
||||
- GeoIP-Sperre
|
||||
- externe Blocklist-Sperre, falls separat aktiviert
|
||||
- Freigabe
|
||||
- Bulk-Freigabe, zum Beispiel durch `flush`
|
||||
|
||||
## Grundkonfiguration
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="<typ>"
|
||||
NOTIFY_WEBHOOK_URL="<url>"
|
||||
NOTIFY_TYPE="ntfy"
|
||||
```
|
||||
|
||||
Mögliche Typen:
|
||||
|
||||
```text
|
||||
ntfy
|
||||
discord
|
||||
slack
|
||||
gotify
|
||||
generic
|
||||
```
|
||||
|
||||
Nach Änderungen:
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="ntfy"
|
||||
@@ -23,28 +51,29 @@ NTFY_TOKEN=""
|
||||
NTFY_PRIORITY="4"
|
||||
```
|
||||
|
||||
> **Hinweis:** Bei Ntfy wird `NOTIFY_WEBHOOK_URL` nicht benötigt – Server-URL und Topic werden separat konfiguriert.
|
||||
Eigene Ntfy-Instanz:
|
||||
|
||||
**Eigene Ntfy-Instanz:**
|
||||
```bash
|
||||
NTFY_SERVER_URL="https://ntfy.mein-server.de"
|
||||
NTFY_SERVER_URL="https://ntfy.example.com"
|
||||
NTFY_TOPIC="dns-security"
|
||||
NTFY_TOKEN="tk_mein_geheimer_token"
|
||||
NTFY_TOKEN="tk_geheimer_token"
|
||||
```
|
||||
|
||||
**Prioritäten:**
|
||||
| Wert | Bedeutung |
|
||||
|------|-----------|
|
||||
| 1 | Minimum |
|
||||
| 2 | Niedrig |
|
||||
| 3 | Standard |
|
||||
| 4 | Hoch |
|
||||
| 5 | Maximum |
|
||||
Prioritäten:
|
||||
|
||||
**Token erstellen (Self-hosted):**
|
||||
1. Ntfy Web-UI → Benutzer/Tokens
|
||||
2. Token kopieren und in `NTFY_TOKEN` eintragen
|
||||
3. Bei ntfy.sh: Account erstellen → Access Token generieren
|
||||
| Wert | Bedeutung |
|
||||
|---:|---|
|
||||
| `1` | Minimum |
|
||||
| `2` | Niedrig |
|
||||
| `3` | Standard |
|
||||
| `4` | Hoch |
|
||||
| `5` | Maximum |
|
||||
|
||||
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.
|
||||
|
||||
## Discord
|
||||
|
||||
@@ -54,21 +83,16 @@ NOTIFY_TYPE="discord"
|
||||
NOTIFY_WEBHOOK_URL="https://discord.com/api/webhooks/xxx/yyy"
|
||||
```
|
||||
|
||||
**Webhook erstellen:**
|
||||
1. Discord Server → Servereinstellungen → Integrationen → Webhooks
|
||||
2. Neuer Webhook → URL kopieren
|
||||
Webhook erstellen:
|
||||
|
||||
## Gotify
|
||||
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.
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="gotify"
|
||||
NOTIFY_WEBHOOK_URL="https://gotify.example.com/message?token=xxx"
|
||||
```
|
||||
|
||||
**Token erstellen:**
|
||||
1. Gotify Web-UI → Apps → App erstellen
|
||||
2. Token kopieren und in die URL einfügen
|
||||
Discord erhält den Inhalt als `content`.
|
||||
|
||||
## Slack
|
||||
|
||||
@@ -78,144 +102,223 @@ NOTIFY_TYPE="slack"
|
||||
NOTIFY_WEBHOOK_URL="https://hooks.slack.com/services/xxx/yyy/zzz"
|
||||
```
|
||||
|
||||
**Webhook erstellen:**
|
||||
1. Slack App → Incoming Webhooks aktivieren
|
||||
2. Webhook-URL kopieren
|
||||
Slack erhält den Inhalt als `text`.
|
||||
|
||||
## Generic (eigener Endpoint)
|
||||
Einrichtung grob:
|
||||
|
||||
1. Slack-App mit Incoming Webhooks einrichten.
|
||||
2. Webhook für den gewünschten Channel aktivieren.
|
||||
3. Webhook-URL in die Konfiguration kopieren.
|
||||
|
||||
## Gotify
|
||||
|
||||
```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:
|
||||
|
||||
1. Gotify-Weboberfläche öffnen.
|
||||
2. Apps auswählen.
|
||||
3. App erstellen.
|
||||
4. Token in die URL einsetzen.
|
||||
|
||||
## Generic Webhook
|
||||
|
||||
Für eigene Automatisierung:
|
||||
|
||||
```bash
|
||||
NOTIFY_ENABLED=true
|
||||
NOTIFY_TYPE="generic"
|
||||
NOTIFY_WEBHOOK_URL="https://your-server.com/webhook"
|
||||
NOTIFY_WEBHOOK_URL="https://example.com/adguard-shield-webhook"
|
||||
```
|
||||
|
||||
Sendet einen POST mit JSON-Body:
|
||||
AdGuard Shield sendet einen `POST` mit JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "🚫 AdGuard Shield Ban auf dns1\n---\nIP: 192.168.1.50\nHostname: client.local\nGrund: 45x microsoft.com in 60s via DNS, Rate-Limit\nDauer: 1h 0m\n\nWhois: https://www.whois.com/whois/192.168.1.50\nAbuseIPDB: https://www.abuseipdb.com/check/192.168.1.50",
|
||||
"action": "ban",
|
||||
"title": "AdGuard Shield",
|
||||
"message": "AdGuard Shield Ban auf dns1\n---\nIP: 192.168.1.50\nHostname: client.local\nGrund: 45x example.com in 60s via DNS, Rate-Limit\nDauer: 1h 0m [Stufe 1/5]\n\nAbuseIPDB: https://www.abuseipdb.com/check/192.168.1.50",
|
||||
"client": "192.168.1.50",
|
||||
"domain": "microsoft.com"
|
||||
"action": "ban"
|
||||
}
|
||||
```
|
||||
|
||||
## Benachrichtigungen und externe Blocklisten
|
||||
Mögliche `action`-Werte:
|
||||
|
||||
Bei Sperren aus der **externen Blocklist** werden Benachrichtigungen separat über `EXTERNAL_BLOCKLIST_NOTIFY` gesteuert — unabhängig von `NOTIFY_ENABLED`.
|
||||
| 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 |
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|-----------|----------|--------------|
|
||||
| `EXTERNAL_BLOCKLIST_NOTIFY` | `false` | Benachrichtigungen bei Blocklist-Sperren aktivieren |
|
||||
## Externe Blocklist und Benachrichtigungen
|
||||
|
||||
> **Wichtig:** Bei großen Listen `EXTERNAL_BLOCKLIST_NOTIFY=false` belassen. Beim ersten Sync (oder nach einem `blocklist-flush`) werden alle IPs der Liste auf einmal gesperrt — mit `true` würde das zu einer Nachrichten-Flut im Notification-Channel führen. Nur auf `true` setzen, wenn die Liste sehr klein ist.
|
||||
Für Sperren aus externen Blocklisten gibt es einen zusätzlichen Schalter:
|
||||
|
||||
## Beispiel-Nachrichten
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=false
|
||||
```
|
||||
|
||||
Warum separat?
|
||||
|
||||
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.
|
||||
|
||||
Empfehlung:
|
||||
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=false
|
||||
```
|
||||
|
||||
Nur bei kleinen, kuratierten Listen:
|
||||
|
||||
```bash
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=true
|
||||
```
|
||||
|
||||
## GeoIP-Benachrichtigungen
|
||||
|
||||
GeoIP hat ebenfalls einen eigenen Schalter:
|
||||
|
||||
```bash
|
||||
GEOIP_NOTIFY=true
|
||||
```
|
||||
|
||||
Wenn GeoIP aktiv ist, aber keine Nachrichten für GeoIP-Sperren gesendet werden sollen:
|
||||
|
||||
```bash
|
||||
GEOIP_NOTIFY=false
|
||||
```
|
||||
|
||||
## Bulk-Freigaben
|
||||
|
||||
Diese Befehle können viele IPs auf einmal freigeben:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield flush
|
||||
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.
|
||||
|
||||
## AbuseIPDB-Hinweis in Nachrichten
|
||||
|
||||
Bei permanenten Monitor-Sperren kann AdGuard Shield zusätzlich an AbuseIPDB melden.
|
||||
|
||||
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.
|
||||
|
||||
AbuseIPDB wird nicht für GeoIP- oder externe Blocklist-Sperren verwendet.
|
||||
|
||||
## Beispielinhalte
|
||||
|
||||
### Service gestartet
|
||||
**Überschrift:** ✅ AdGuard Shield
|
||||
|
||||
> 🟢 AdGuard Shield v0.9.0 wurde auf dns1 gestartet.
|
||||
```text
|
||||
AdGuard Shield v1.0.0 wurde auf dns1 gestartet.
|
||||
```
|
||||
|
||||
### Service gestoppt
|
||||
**Überschrift:** 🚨 🛡️ AdGuard Shield
|
||||
|
||||
> 🔴 AdGuard Shield v0.9.0 wurde auf dns1 gestoppt.
|
||||
```text
|
||||
AdGuard Shield v1.0.0 wurde auf dns1 gestoppt.
|
||||
```
|
||||
|
||||
### Watchdog — Service wiederhergestellt
|
||||
**Überschrift:** 🔄 AdGuard Shield Watchdog
|
||||
### Rate-Limit-Sperre
|
||||
|
||||
> 🔄 AdGuard Shield Watchdog auf dns1
|
||||
> ---
|
||||
> Der Service war ausgefallen und wurde automatisch neu gestartet.
|
||||
> Versuch: 1
|
||||
```text
|
||||
AdGuard Shield Ban auf dns1
|
||||
---
|
||||
IP: 192.0.2.50
|
||||
Hostname: client.example.com
|
||||
Grund: 45x example.com in 60s via DNS, Rate-Limit
|
||||
Dauer: 1h 0m [Stufe 1/5]
|
||||
|
||||
### Watchdog — Recovery fehlgeschlagen
|
||||
**Überschrift:** 🚨 AdGuard Shield Watchdog
|
||||
AbuseIPDB: https://www.abuseipdb.com/check/192.0.2.50
|
||||
```
|
||||
|
||||
> 🚨 AdGuard Shield Watchdog auf dns1
|
||||
> ---
|
||||
> Der Service konnte NICHT automatisch neu gestartet werden!
|
||||
> Manuelles Eingreifen erforderlich.
|
||||
> Fehlversuche: 1
|
||||
> Letzter Fehler: (systemd Statusausgabe)
|
||||
### Watchlist-Sperre
|
||||
|
||||
### Sperre (Ban)
|
||||
**Überschrift:** 🚨 🛡️ AdGuard Shield
|
||||
```text
|
||||
AdGuard Shield Ban auf dns1
|
||||
IP wurde an AbuseIPDB gemeldet
|
||||
---
|
||||
IP: 192.0.2.51
|
||||
Hostname: unknown
|
||||
Grund: 75x microsoft.com in 60s via DoH, DNS-Flood-Watchlist
|
||||
Dauer: PERMANENT
|
||||
|
||||
> 🚫 AdGuard Shield Ban auf dns1
|
||||
> ---
|
||||
> IP: 95.71.42.116
|
||||
> Hostname: example-host.provider.net
|
||||
> Grund: 153x radioportal.techniverse.net in 60s via DNS, Rate-Limit
|
||||
> Dauer: 1h 0m [Stufe 1/5]
|
||||
>
|
||||
> Whois: https://www.whois.com/whois/95.71.42.116
|
||||
> AbuseIPDB: https://www.abuseipdb.com/check/95.71.42.116
|
||||
AbuseIPDB: https://www.abuseipdb.com/check/192.0.2.51
|
||||
```
|
||||
|
||||
Bei permanenter Sperre mit aktiviertem AbuseIPDB-Reporting erscheint zusätzlich:
|
||||
### GeoIP-Sperre
|
||||
|
||||
> 🚫 AdGuard Shield Ban auf dns1
|
||||
> ⚠️ IP wurde an AbuseIPDB gemeldet
|
||||
> ---
|
||||
> IP: 95.71.42.116
|
||||
> Hostname: example-host.provider.net
|
||||
> Grund: 153x radioportal.techniverse.net in 60s via DNS, Rate-Limit
|
||||
> Dauer: PERMANENT [Stufe 5/5]
|
||||
>
|
||||
> Whois: https://www.whois.com/whois/95.71.42.116
|
||||
> AbuseIPDB: https://www.abuseipdb.com/check/95.71.42.116
|
||||
```text
|
||||
AdGuard Shield GeoIP-Sperre auf dns1
|
||||
---
|
||||
IP: 203.0.113.10
|
||||
Land: BR
|
||||
Modus: Blocklist
|
||||
Dauer: PERMANENT
|
||||
|
||||
Bei DNS-Flood-Watchlist-Treffer (sofort permanent, ohne Stufe):
|
||||
AbuseIPDB: https://www.abuseipdb.com/check/203.0.113.10
|
||||
```
|
||||
|
||||
> 🚫 AdGuard Shield Ban auf dns1
|
||||
> ⚠️ IP wurde an AbuseIPDB gemeldet
|
||||
> ---
|
||||
> IP: 95.71.42.116
|
||||
> Hostname: example-host.provider.net
|
||||
> Grund: 45x microsoft.com in 60s via DNS, DNS-Flood-Watchlist
|
||||
> Dauer: PERMANENT
|
||||
>
|
||||
> Whois: https://www.whois.com/whois/95.71.42.116
|
||||
> AbuseIPDB: https://www.abuseipdb.com/check/95.71.42.116
|
||||
### Freigabe
|
||||
|
||||
### Entsperrung (Unban)
|
||||
**Überschrift:** ✅ AdGuard Shield
|
||||
```text
|
||||
AdGuard Shield Freigabe auf dns1
|
||||
---
|
||||
IP: 192.0.2.50
|
||||
Hostname: client.example.com
|
||||
|
||||
> ✅ AdGuard Shield Freigabe auf dns1
|
||||
> ---
|
||||
> IP: 95.71.42.116
|
||||
> Hostname: example-host.provider.net
|
||||
>
|
||||
> AbuseIPDB: https://www.abuseipdb.com/check/95.71.42.116
|
||||
AbuseIPDB: https://www.abuseipdb.com/check/192.0.2.50
|
||||
```
|
||||
|
||||
### Externe Blocklist – Sperre
|
||||
**Überschrift:** 🚨 🛡️ AdGuard Shield
|
||||
### Bulk-Freigabe
|
||||
|
||||
> 🚫 AdGuard Shield Ban auf dns1 (Externe Blocklist)
|
||||
> ---
|
||||
> IP: 203.0.113.50
|
||||
> Hostname: bad-actor.example.com
|
||||
>
|
||||
> Whois: https://www.whois.com/whois/203.0.113.50
|
||||
> AbuseIPDB: https://www.abuseipdb.com/check/203.0.113.50
|
||||
```text
|
||||
AdGuard Shield Bulk-Freigabe auf dns1
|
||||
---
|
||||
Freigegebene IPs: 28
|
||||
Aktion: Manual-Flush
|
||||
```
|
||||
|
||||
### Externe Blocklist – Entsperrung
|
||||
**Überschrift:** ✅ AdGuard Shield
|
||||
## Fehlersuche
|
||||
|
||||
> ✅ AdGuard Shield Freigabe auf dns1 (Externe Blocklist)
|
||||
> ---
|
||||
> IP: 203.0.113.50
|
||||
> Hostname: bad-actor.example.com
|
||||
>
|
||||
> AbuseIPDB: https://www.abuseipdb.com/check/203.0.113.50
|
||||
Wenn keine Benachrichtigung ankommt:
|
||||
|
||||
### Hinweise
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
```
|
||||
|
||||
- Der **Hostname** der IP wird automatisch per Reverse-DNS aufgelöst (`dig`, `host` oder `getent`). Ist kein PTR-Record vorhanden, wird `(unbekannt)` angezeigt.
|
||||
- Der **Servername** (`dns1` in den Beispielen) wird dynamisch über `$(hostname)` ermittelt und zeigt, auf welchem Server das Ereignis stattfand.
|
||||
- Die **Überschrift** unterscheidet sich je nach Aktion:
|
||||
- 🚨 🛡️ bei Sperren und Service-Stopp
|
||||
- ✅ bei Freigaben und Service-Start
|
||||
- Bei **permanenten Sperren** mit aktiviertem AbuseIPDB-Reporting wird ein Hinweis eingeblendet, dass die IP an AbuseIPDB gemeldet wurde.
|
||||
Prüfe:
|
||||
|
||||
- `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
|
||||
|
||||
Bei `generic` kannst du testweise einen lokalen HTTP-Empfänger oder einen Request-Inspector verwenden.
|
||||
|
||||
## 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.
|
||||
|
||||
52
docs/docker.md
Normal file
52
docs/docker.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# 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.
|
||||
|
||||
## 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"` |
|
||||
|
||||
`docker-host` verhält sich technisch wie `host`: Die DNS-Pakete landen in der Host-`INPUT`-Chain.
|
||||
|
||||
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.
|
||||
|
||||
## Beispiele
|
||||
|
||||
Klassisch oder Docker Host Network:
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="host"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
Docker Bridge mit Port-Publishing:
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="docker-bridge"
|
||||
BLOCKED_PORTS="53 443 853"
|
||||
```
|
||||
|
||||
Unklarer Übergangszustand:
|
||||
|
||||
```bash
|
||||
FIREWALL_MODE="hybrid"
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
Nach einer Änderung:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart adguard-shield
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-status
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
405
docs/report.md
405
docs/report.md
@@ -1,19 +1,58 @@
|
||||
# E-Mail Report
|
||||
|
||||
AdGuard Shield kann regelmäßig einen Statistik-Report per E-Mail versenden. Der Report enthält eine Übersicht über alle Sperren, die auffälligsten IPs, meistbetroffene Domains und weitere Statistiken.
|
||||
AdGuard Shield kann Statistik-Reports direkt aus der SQLite-Datenbank erzeugen und per E-Mail versenden. Es gibt in der Go-Version keinen separaten `report-generator.sh` mehr.
|
||||
|
||||
## Voraussetzungen
|
||||
## Was der Report enthält
|
||||
|
||||
Der Server muss E-Mails versenden können. Empfohlen wird **msmtp** als leichtgewichtiger SMTP-Client.
|
||||
Der Report basiert auf:
|
||||
|
||||
**Anleitung zur Einrichtung von msmtp:**
|
||||
👉 [Linux: Einfach E-Mails versenden mit msmtp](https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/)
|
||||
```text
|
||||
/var/lib/adguard-shield/adguard-shield.db
|
||||
```
|
||||
|
||||
Alternativ funktioniert auch `sendmail`, `mail` oder ein anderer Befehl, der E-Mails über stdin entgegennimmt.
|
||||
Ausgewertet werden vor allem:
|
||||
|
||||
## Aktivierung
|
||||
- `ban_history`
|
||||
- `active_bans`
|
||||
|
||||
In der Konfiguration (`adguard-shield.conf`):
|
||||
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:
|
||||
|
||||
| Parameter | Bedeutung |
|
||||
|---|---|
|
||||
| `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" |
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
REPORT_ENABLED=true
|
||||
@@ -25,252 +64,182 @@ REPORT_FORMAT="html"
|
||||
REPORT_MAIL_CMD="msmtp"
|
||||
```
|
||||
|
||||
Anschließend den Cron-Job einrichten:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/report-generator.sh install
|
||||
```
|
||||
|
||||
## Konfigurationsparameter
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|-----------|----------|--------------|
|
||||
| `REPORT_ENABLED` | `false` | Report-Funktion aktivieren |
|
||||
| `REPORT_INTERVAL` | `weekly` | Versandintervall (siehe unten) |
|
||||
| `REPORT_TIME` | `08:00` | Uhrzeit für den Versand (HH:MM, 24h) |
|
||||
| `REPORT_EMAIL_TO` | *(leer)* | E-Mail-Empfänger |
|
||||
| `REPORT_EMAIL_FROM` | `adguard-shield@hostname` | E-Mail-Absender |
|
||||
| `REPORT_FORMAT` | `html` | Format: `html` oder `txt` |
|
||||
| `REPORT_MAIL_CMD` | `msmtp` | Mail-Befehl (`msmtp`, `sendmail`, `mail`) |
|
||||
| `REPORT_BUSIEST_DAY_RANGE` | `30` | Zeitraum in Tagen für „Aktivster Tag“ (0 = Berichtszeitraum) |
|
||||
|
||||
### Versandintervalle
|
||||
|
||||
| Wert | Beschreibung |
|
||||
|------|-------------|
|
||||
| `daily` | Täglich zur konfigurierten Uhrzeit |
|
||||
| `weekly` | Wöchentlich am Montag |
|
||||
| `biweekly` | Alle zwei Wochen am Montag |
|
||||
| `monthly` | Monatlich am 1. des Monats |
|
||||
|
||||
## Report-Inhalte
|
||||
|
||||
Der Report enthält folgende Statistiken:
|
||||
|
||||
### Zeitraum-Schnellübersicht *(immer ganz oben)*
|
||||
|
||||
Eine Vergleichstabelle mit Live-Zahlen für vier feste Zeitfenster – unabhängig vom konfigurierten `REPORT_INTERVAL`:
|
||||
|
||||
| Zeitraum | Sperren | Entsperrungen | Eindeutige IPs | Permanent gebannt |
|
||||
|----------|---------|---------------|----------------|-------------------|
|
||||
| Heute *(nur nach 20:00 Uhr)* | … | … | … | … |
|
||||
| Gestern | … | … | … | … |
|
||||
| Letzte 7 Tage | … | … | … | … |
|
||||
| Letzte 14 Tage | … | … | … | … |
|
||||
| Letzte 30 Tage | … | … | … | … |
|
||||
|
||||
Im HTML-Format wird **Gestern** grün hervorgehoben, **Heute** blau (erscheint nur ab 20:00 Uhr).
|
||||
- **Gestern** umfasst exakt 00:00:00 – 23:59:59 des gestrigen Tages.
|
||||
- **Heute** umfasst den laufenden Tag von 00:00:00 bis zum Zeitpunkt der Reportgenerierung und wird nur eingeblendet, wenn der Report nach 20:00 Uhr erstellt wird.
|
||||
Die übrigen Zeiträume laufen vom Starttag 00:00 Uhr bis zum Zeitpunkt der Reportgenerierung.
|
||||
|
||||
> **Hinweis:** Die AbuseIPDB-Meldungen werden in der Schnellübersicht nicht mehr separat ausgewiesen, da sie immer mit einer Permanentsperre korrelieren – der Wert „Permanent gebannt" ist daher ausreichend. Die Gesamtanzahl der AbuseIPDB-Reports im Berichtszeitraum ist weiterhin in der allgemeinen Übersicht sichtbar.
|
||||
|
||||
### Übersicht (Berichtszeitraum)
|
||||
- Gesamtzahl der Sperren und Entsperrungen
|
||||
- Anzahl eindeutiger gesperrter IPs
|
||||
- Permanente Sperren
|
||||
- Aktuell aktive Sperren
|
||||
- AbuseIPDB-Reports
|
||||
|
||||
### Angriffsarten
|
||||
- Rate-Limit Sperren
|
||||
- Subdomain-Flood Sperren
|
||||
- Externe Blocklist Sperren
|
||||
- Aktivster Tag – wird über einen konfigurierbaren Zeitraum ermittelt (Standard: letzte 30 Tage, `REPORT_BUSIEST_DAY_RANGE`). Zeigt zusätzlich die Anzahl der Sperren an diesem Tag. Bei `REPORT_BUSIEST_DAY_RANGE=0` wird nur der Berichtszeitraum betrachtet.
|
||||
|
||||
### Top 10 Listen
|
||||
- **Auffälligste IPs** — Die 10 IPs mit den meisten Sperren (mit Balkendiagramm im HTML-Format)
|
||||
- **Meistbetroffene Domains** — Die 10 am häufigsten betroffenen Domains
|
||||
|
||||
### Weitere Details
|
||||
- **Protokoll-Verteilung** — Aufschlüsselung nach DNS, DoH, DoT, DoQ
|
||||
- **Letzte 10 Sperren** — Die aktuellsten Sperrereignisse mit Zeitstempel, IP, Domain und Grund
|
||||
|
||||
## Befehle
|
||||
|
||||
```bash
|
||||
# Report sofort generieren und versenden
|
||||
sudo /opt/adguard-shield/report-generator.sh send
|
||||
# Konfiguration und Cron-Status anzeigen
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
|
||||
# Test-E-Mail senden (prüft alle Voraussetzungen + Mailversand)
|
||||
sudo /opt/adguard-shield/report-generator.sh test
|
||||
# HTML-Report in Datei schreiben
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate html /tmp/adguard-shield-report.html
|
||||
|
||||
# Report als Datei generieren (auf stdout ausgeben)
|
||||
sudo /opt/adguard-shield/report-generator.sh generate
|
||||
# Text-Report auf stdout ausgeben
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
|
||||
# Report im spezifischen Format generieren
|
||||
sudo /opt/adguard-shield/report-generator.sh generate html > report.html
|
||||
sudo /opt/adguard-shield/report-generator.sh generate txt > report.txt
|
||||
# Testmail senden
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
|
||||
# Cron-Job für automatischen Versand einrichten
|
||||
sudo /opt/adguard-shield/report-generator.sh install
|
||||
# aktuellen Report erzeugen und versenden
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
|
||||
# Cron-Job installieren
|
||||
sudo /opt/adguard-shield/adguard-shield report-install
|
||||
|
||||
# Cron-Job entfernen
|
||||
sudo /opt/adguard-shield/report-generator.sh remove
|
||||
|
||||
# Report-Konfiguration und Cron-Status anzeigen
|
||||
sudo /opt/adguard-shield/report-generator.sh status
|
||||
sudo /opt/adguard-shield/adguard-shield report-remove
|
||||
```
|
||||
|
||||
## Report-Intervall ändern
|
||||
## Mailversand
|
||||
|
||||
Um das Intervall, die Uhrzeit oder andere Einstellungen zu ändern:
|
||||
AdGuard Shield übergibt die fertige Mail an ein lokales Mailprogramm. Der Standard ist:
|
||||
|
||||
```bash
|
||||
# 1. Konfiguration bearbeiten
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
# → z.B. REPORT_INTERVAL="weekly" auf "daily" ändern
|
||||
# → z.B. REPORT_TIME="09:00"
|
||||
|
||||
# 2. Cron-Job neu einrichten (überschreibt den alten automatisch)
|
||||
sudo /opt/adguard-shield/report-generator.sh install
|
||||
REPORT_MAIL_CMD="msmtp"
|
||||
```
|
||||
|
||||
> **Hinweis:** Der `install`-Befehl überschreibt den bestehenden Cron-Job mit den aktuellen Werten aus der Konfiguration. Ein vorheriges `remove` ist nicht nötig, schadet aber auch nicht.
|
||||
|
||||
Alternativ in zwei Schritten:
|
||||
Minimaler Ablauf mit `msmtp`:
|
||||
|
||||
```bash
|
||||
# Alten Cron-Job erst entfernen, dann neu anlegen
|
||||
sudo /opt/adguard-shield/report-generator.sh remove
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
sudo /opt/adguard-shield/report-generator.sh install
|
||||
```
|
||||
|
||||
## Templates
|
||||
|
||||
Die Report-Templates liegen unter:
|
||||
|
||||
```
|
||||
/opt/adguard-shield/templates/report.html # HTML-Template
|
||||
/opt/adguard-shield/templates/report.txt # TXT-Template
|
||||
```
|
||||
|
||||
Die Templates verwenden Platzhalter (z.B. `{{TOTAL_BANS}}`, `{{TOP10_IPS_TABLE}}`), die beim Generieren durch die tatsächlichen Werte ersetzt werden. Die Templates können nach Bedarf angepasst werden.
|
||||
|
||||
### Verfügbare Platzhalter
|
||||
|
||||
| Platzhalter | Beschreibung |
|
||||
|-------------|-------------|
|
||||
| `{{REPORT_PERIOD}}` | Berichtszeitraum mit Label |
|
||||
| `{{REPORT_DATE}}` | Erstellungsdatum des Reports |
|
||||
| `{{HOSTNAME}}` | Server-Hostname |
|
||||
| `{{VERSION}}` | AdGuard Shield Version |
|
||||
| `{{TOTAL_BANS}}` | Gesamtzahl Sperren |
|
||||
| `{{TOTAL_UNBANS}}` | Gesamtzahl Entsperrungen |
|
||||
| `{{UNIQUE_IPS}}` | Anzahl eindeutiger IPs |
|
||||
| `{{PERMANENT_BANS}}` | Permanente Sperren |
|
||||
| `{{ACTIVE_BANS}}` | Aktuell aktive Sperren |
|
||||
| `{{ABUSEIPDB_REPORTS}}` | Anzahl AbuseIPDB-Reports |
|
||||
| `{{RATELIMIT_BANS}}` | Rate-Limit Sperren |
|
||||
| `{{SUBDOMAIN_FLOOD_BANS}}` | Subdomain-Flood Sperren |
|
||||
| `{{EXTERNAL_BLOCKLIST_BANS}}` | Externe Blocklist Sperren |
|
||||
| `{{BUSIEST_DAY}}` | Aktivster Tag (Datum + Anzahl Sperren) |
|
||||
| `{{BUSIEST_DAY_LABEL}}` | Dynamisches Label für den aktivsten Tag (z.B. „Aktivster Tag (30 Tage)“) |
|
||||
| `{{TOP10_IPS_TABLE}}` | Top 10 IPs (HTML-Tabelle) |
|
||||
| `{{TOP10_IPS_TEXT}}` | Top 10 IPs (Text-Tabelle) |
|
||||
| `{{TOP10_DOMAINS_TABLE}}` | Top 10 Domains (HTML-Tabelle) |
|
||||
| `{{TOP10_DOMAINS_TEXT}}` | Top 10 Domains (Text-Tabelle) |
|
||||
| `{{PROTOCOL_TABLE}}` | Protokoll-Verteilung (HTML) |
|
||||
| `{{PROTOCOL_TEXT}}` | Protokoll-Verteilung (Text) |
|
||||
| `{{RECENT_BANS_TABLE}}` | Letzte Sperren (HTML) |
|
||||
| `{{RECENT_BANS_TEXT}}` | Letzte Sperren (Text) |
|
||||
|
||||
## Beispiel: Schnellstart
|
||||
|
||||
```bash
|
||||
# 1. msmtp installieren und konfigurieren
|
||||
sudo apt install msmtp msmtp-mta
|
||||
# Anleitung: https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/
|
||||
|
||||
# 2. Report-Konfiguration anpassen
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
# → REPORT_ENABLED=true
|
||||
# → REPORT_EMAIL_TO="deine@email.de"
|
||||
|
||||
# 3. Test-Mail senden (prüft alle Voraussetzungen)
|
||||
sudo /opt/adguard-shield/report-generator.sh test
|
||||
|
||||
# 4. Wenn die Test-Mail angekommen ist: echten Report testen
|
||||
sudo /opt/adguard-shield/report-generator.sh send
|
||||
|
||||
# 5. Automatischen Versand einrichten
|
||||
sudo /opt/adguard-shield/report-generator.sh install
|
||||
|
||||
# 6. Status prüfen
|
||||
sudo /opt/adguard-shield/report-generator.sh status
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
```
|
||||
|
||||
## Test-Mail
|
||||
`report-test` sendet eine einfache Testmail. Erst wenn diese funktioniert, lohnt sich die Fehlersuche am eigentlichen Report.
|
||||
|
||||
Bevor du den automatischen Versand einrichtest, kannst du mit dem `test`-Befehl prüfen, ob alles funktioniert:
|
||||
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
|
||||
sudo /opt/adguard-shield/report-generator.sh test
|
||||
REPORT_MAIL_CMD="msmtp --account=default"
|
||||
```
|
||||
|
||||
Der Test prüft Schritt für Schritt:
|
||||
## Automatischer Versand
|
||||
|
||||
1. **E-Mail-Empfänger** — Ist `REPORT_EMAIL_TO` konfiguriert?
|
||||
2. **E-Mail-Absender** — Zeigt den konfigurierten Absender an
|
||||
3. **Mail-Befehl** — Ist `msmtp` (oder der konfigurierte Befehl) installiert?
|
||||
4. **Report-Template** — Existiert das HTML/TXT-Template?
|
||||
5. **Ban-History** — Gibt es vorhandene Daten?
|
||||
6. **Test-Versand** — Sendet eine Test-E-Mail und prüft den Exit-Code
|
||||
Cron installieren:
|
||||
|
||||
Die Test-Mail enthält eine Übersicht der aktuellen Konfiguration und bestätigt, dass der Mailversand funktioniert.
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-install
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
Dadurch wird diese Datei geschrieben:
|
||||
|
||||
### E-Mail wird nicht versendet
|
||||
```text
|
||||
/etc/cron.d/adguard-shield-report
|
||||
```
|
||||
|
||||
1. Prüfe ob der Mail-Befehl installiert ist:
|
||||
```bash
|
||||
which msmtp
|
||||
```
|
||||
Der Cron-Eintrag ruft das installierte Binary mit der installierten Konfiguration auf:
|
||||
|
||||
2. Teste den Mailversand manuell:
|
||||
```bash
|
||||
echo "Test" | msmtp -t deine@email.de
|
||||
```
|
||||
```text
|
||||
/opt/adguard-shield/adguard-shield -config /opt/adguard-shield/adguard-shield.conf report-send
|
||||
```
|
||||
|
||||
3. Prüfe die msmtp-Konfiguration:
|
||||
```bash
|
||||
cat ~/.msmtprc
|
||||
# oder
|
||||
cat /etc/msmtprc
|
||||
```
|
||||
Zeitplan nach `REPORT_INTERVAL`:
|
||||
|
||||
4. Prüfe die Report-Konfiguration:
|
||||
```bash
|
||||
sudo /opt/adguard-shield/report-generator.sh status
|
||||
```
|
||||
| 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 |
|
||||
|
||||
### Report enthält keine Daten
|
||||
Cron entfernen:
|
||||
|
||||
Der Report basiert auf der Ban-History in der SQLite-Datenbank (`/var/lib/adguard-shield/adguard-shield.db`). Wenn keine Sperren im Berichtszeitraum vorhanden sind, zeigt der Report „Keine Daten" an.
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-remove
|
||||
```
|
||||
|
||||
### Cron-Job wird nicht ausgeführt
|
||||
## Manuelle Prüfung
|
||||
|
||||
1. Prüfe ob der Cron-Job angelegt wurde:
|
||||
```bash
|
||||
cat /etc/cron.d/adguard-shield-report
|
||||
```
|
||||
Status:
|
||||
|
||||
2. Prüfe die Cron-Logs:
|
||||
```bash
|
||||
grep adguard-shield /var/log/syslog
|
||||
# oder
|
||||
journalctl -u cron
|
||||
```
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
```
|
||||
|
||||
Report lokal erzeugen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate html /tmp/adguard-shield-report.html
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
```
|
||||
|
||||
Versand testen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
```
|
||||
|
||||
Logs:
|
||||
|
||||
```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.
|
||||
|
||||
## Häufige Probleme
|
||||
|
||||
### `REPORT_EMAIL_TO ist leer`
|
||||
|
||||
Setze einen Empfänger:
|
||||
|
||||
```bash
|
||||
REPORT_EMAIL_TO="admin@example.com"
|
||||
```
|
||||
|
||||
### Mailprogramm nicht gefunden
|
||||
|
||||
Prüfen:
|
||||
|
||||
```bash
|
||||
which msmtp
|
||||
```
|
||||
|
||||
Installieren:
|
||||
|
||||
```bash
|
||||
sudo apt install msmtp msmtp-mta
|
||||
```
|
||||
|
||||
Oder `REPORT_MAIL_CMD` auf dein vorhandenes Mailprogramm setzen.
|
||||
|
||||
### Cron läuft, aber keine Mail kommt an
|
||||
|
||||
Prüfen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
sudo cat /etc/cron.d/adguard-shield-report
|
||||
```
|
||||
|
||||
Achte darauf, dass:
|
||||
|
||||
- `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
|
||||
|
||||
## HTML und TXT
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate html /tmp/report.html
|
||||
```
|
||||
|
||||
@@ -1,287 +1,424 @@
|
||||
# Tipps & Troubleshooting
|
||||
|
||||
## Best Practices
|
||||
Dieses Dokument hilft beim Eingrenzen typischer Probleme im Betrieb. Die Reihenfolge ist bewusst praktisch: erst prüfen, ob der Dienst läuft, dann API, Firewall, Sperren, Listen und optionale Module.
|
||||
|
||||
- **Erst immer im Dry-Run testen**, bevor der scharfe Modus aktiviert wird
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh dry-run
|
||||
```
|
||||
- **Whitelist großzügig pflegen**: Eigene IPs, Router, wichtige Server nicht vergessen
|
||||
- **Sperrdauer anpassen**: Für DDoS-artige Muster ggf. länger sperren
|
||||
- **Logs regelmäßig prüfen**: Falsche Positive erkennen und Whitelist anpassen
|
||||
- **Ban-History nutzen**: `history`-Befehl zeigt alle vergangenen Sperren — hilfreich um Muster zu erkennen
|
||||
- **Log-Level auf DEBUG** setzen wenn etwas nicht funktioniert
|
||||
## Erste Diagnose
|
||||
|
||||
## Häufige Probleme
|
||||
|
||||
### API-Verbindung schlägt fehl
|
||||
Diese Befehle liefern meistens schon genug Hinweise:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh test
|
||||
sudo systemctl status adguard-shield
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
```
|
||||
|
||||
**Mögliche Ursachen:**
|
||||
- Falsche URL in `ADGUARD_URL` (Port prüfen!)
|
||||
- Falsche Zugangsdaten (`ADGUARD_USER` / `ADGUARD_PASS`)
|
||||
- AdGuard Home läuft nicht
|
||||
- Firewall blockiert lokale Verbindung
|
||||
- DNS-Auflösung des Hostnames fehlgeschlagen
|
||||
- SSL/TLS-Zertifikatfehler (bei HTTPS)
|
||||
Wenn du aktuelle Queries sehen willst:
|
||||
|
||||
#### Schritt-für-Schritt Diagnose
|
||||
|
||||
**1. Base-URL Erreichbarkeit prüfen (ohne Auth):**
|
||||
```bash
|
||||
# Vollständige Diagnose mit HTTP-Headern und Verbindungsdetails
|
||||
curl -ikv https://dns1.domain.com 2>&1
|
||||
|
||||
# Nur HTTP-Statuscode prüfen (schnell)
|
||||
curl -s -o /dev/null -w "%{http_code}\n" -k https://dns1.domain.com
|
||||
sudo /opt/adguard-shield/adguard-shield live
|
||||
```
|
||||
|
||||
> `-i` zeigt HTTP-Response-Header, `-k` ignoriert SSL-Fehler, `-v` zeigt Verbindungsdetails (DNS, TLS-Handshake, etc.)
|
||||
## Service startet nicht
|
||||
|
||||
Prüfen:
|
||||
|
||||
**2. DNS-Auflösung testen:**
|
||||
```bash
|
||||
# Hostname auflösen
|
||||
dig +short dns1.domain.com
|
||||
|
||||
# Oder mit nslookup
|
||||
nslookup dns1.domain.com
|
||||
sudo systemctl status adguard-shield
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
```
|
||||
|
||||
**3. Port-Erreichbarkeit testen:**
|
||||
```bash
|
||||
# TCP-Verbindung zum Port prüfen (z.B. Port 3000)
|
||||
nc -zv 127.0.0.1 3000
|
||||
Typische Ursachen:
|
||||
|
||||
# Oder mit curl
|
||||
curl -v telnet://127.0.0.1:3000
|
||||
```
|
||||
- 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
|
||||
|
||||
**4. API-Endpunkt mit Authentifizierung testen:**
|
||||
```bash
|
||||
# Query-Log abfragen (mit Auth + Response-Header)
|
||||
curl -i -u admin:passwort https://dns1.domain.com/control/querylog?limit=1
|
||||
|
||||
# Nur HTTP-Status zurückgeben
|
||||
curl -s -o /dev/null -w "%{http_code}\n" -u admin:passwort https://dns1.domain.com/control/querylog?limit=1
|
||||
```
|
||||
|
||||
**5. AdGuard Home Status-API prüfen:**
|
||||
```bash
|
||||
# Allgemeinen Status abfragen (benötigt keine Auth)
|
||||
curl -ik https://dns1.domain.com/control/status
|
||||
```
|
||||
|
||||
#### Typische Fehlercodes
|
||||
|
||||
| HTTP-Code | Bedeutung | Lösung |
|
||||
|-----------|-----------|--------|
|
||||
| `000` | Keine Verbindung | Host nicht erreichbar, DNS-Fehler oder Firewall |
|
||||
| `200` | Erfolg | Alles in Ordnung ✅ |
|
||||
| `301/302` | Weiterleitung | URL prüfen — evtl. fehlt `https://` oder Port |
|
||||
| `401` | Nicht autorisiert | `ADGUARD_USER` / `ADGUARD_PASS` prüfen |
|
||||
| `403` | Zugriff verweigert | Zugangsdaten oder IP-Beschränkung in AdGuard Home |
|
||||
| `404` | Nicht gefunden | URL falsch oder AdGuard Home Version zu alt |
|
||||
| `502/503` | Service nicht verfügbar | AdGuard Home läuft nicht oder wird gerade neu gestartet |
|
||||
|
||||
#### curl Exit-Codes
|
||||
|
||||
| Exit-Code | Bedeutung |
|
||||
|-----------|-----------|
|
||||
| `6` | DNS-Auflösung fehlgeschlagen — Hostname prüfen |
|
||||
| `7` | Verbindung abgelehnt — Läuft AdGuard Home? Port korrekt? |
|
||||
| `28` | Timeout — Host nicht erreichbar oder Firewall blockiert |
|
||||
| `35` | SSL/TLS-Handshake fehlgeschlagen |
|
||||
| `51` | SSL-Zertifikat: Hostname stimmt nicht überein |
|
||||
| `60` | SSL-Zertifikat: nicht vertrauenswürdig (selbstsigniert?) |
|
||||
|
||||
> **Tipp:** Bei selbstsignierten Zertifikaten `-k` an curl anhängen, um SSL-Fehler zu ignorieren. AdGuard Shield verwendet intern automatisch `-k` bei der API-Kommunikation.
|
||||
|
||||
**Lösung:** URL und Zugangsdaten in der Konfiguration anpassen:
|
||||
```bash
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
### iptables-Fehler: "Permission denied"
|
||||
|
||||
Das Script muss als **root** laufen, da iptables Root-Rechte benötigt.
|
||||
Nützliche Prüfungen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh start
|
||||
```
|
||||
|
||||
### Client wird fälschlich gesperrt
|
||||
|
||||
1. Client sofort entsperren:
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh unban 192.168.1.100
|
||||
```
|
||||
2. In der Ban-History prüfen, warum gesperrt wurde:
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh history | grep 192.168.1.100
|
||||
```
|
||||
3. Offense-Zähler für die IP zurücksetzen (damit die progressive Sperre wieder bei Stufe 1 beginnt):
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh reset-offenses 192.168.1.100
|
||||
```
|
||||
4. IP zur Whitelist hinzufügen in `adguard-shield.conf`
|
||||
5. Service neustarten:
|
||||
```bash
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
### Client wurde permanent gesperrt (Progressive Sperren)
|
||||
|
||||
Wenn eine IP die maximale Stufe der progressiven Sperren erreicht hat, wird sie permanent gesperrt und nicht automatisch aufgehoben.
|
||||
|
||||
1. IP entsperren:
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh unban 192.168.1.100
|
||||
```
|
||||
2. Offense-Zähler zurücksetzen:
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh reset-offenses 192.168.1.100
|
||||
```
|
||||
3. Prüfen ob die IP auf die Whitelist gehört, oder die Progressive-Ban-Einstellungen anpassen (`PROGRESSIVE_BAN_MAX_LEVEL` erhöhen oder auf `0` setzen für keine permanenten Sperren)
|
||||
|
||||
### Sperren überleben Reboot nicht
|
||||
|
||||
Das ist normal — iptables-Regeln sind flüchtig. Der **Service** erstellt die Chain beim Start automatisch neu. Aktive Sperren aus der SQLite-Datenbank werden aber nicht automatisch als iptables-Regeln wiederhergestellt.
|
||||
|
||||
**Optionen:**
|
||||
- `iptables-persistent` installieren (`apt install iptables-persistent`)
|
||||
- Oder den State beim Boot wiederherstellen lassen (Feature-Idee)
|
||||
|
||||
### Zu viele false positives
|
||||
|
||||
- `RATE_LIMIT_MAX_REQUESTS` erhöhen (z.B. 50 oder 100)
|
||||
- `RATE_LIMIT_WINDOW` vergrößern (z.B. 120 Sekunden)
|
||||
- Windows-Clients fragen manche Domains von Natur aus sehr oft an — Whitelist nutzen
|
||||
|
||||
### Subdomain-Flood-Erkennung sperrt legitime Clients
|
||||
|
||||
Manche Dienste (z.B. CDNs, Cloud-Dienste, Microsoft 365) nutzen von Natur aus viele verschiedene Subdomains. Falls ein legitimer Client fälschlicherweise durch die Subdomain-Flood-Erkennung gesperrt wird:
|
||||
|
||||
1. Client sofort entsperren:
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh unban <IP>
|
||||
```
|
||||
2. Schwellwert erhöhen — z.B. von 50 auf 100 oder 150:
|
||||
```bash
|
||||
SUBDOMAIN_FLOOD_MAX_UNIQUE=100
|
||||
```
|
||||
3. Zeitfenster vergrößern — z.B. auf 120 Sekunden:
|
||||
```bash
|
||||
SUBDOMAIN_FLOOD_WINDOW=120
|
||||
```
|
||||
4. Oder die IP zur Whitelist hinzufügen
|
||||
5. Im Zweifelsfall die Erkennung temporär deaktivieren:
|
||||
```bash
|
||||
SUBDOMAIN_FLOOD_ENABLED=false
|
||||
```
|
||||
|
||||
> **Tipp:** Im Dry-Run-Modus (`sudo /opt/adguard-shield/adguard-shield.sh dry-run`) kann man beobachten, welche Clients die Subdomain-Flood-Erkennung auslösen würden, ohne sie wirklich zu sperren.
|
||||
|
||||
### Monitor startet nicht (PID-File)
|
||||
|
||||
```bash
|
||||
# Altes PID-File entfernen
|
||||
sudo rm -f /var/run/adguard-shield.pid
|
||||
sudo systemctl start adguard-shield
|
||||
```
|
||||
|
||||
### Service ist ausgefallen und startet nicht mehr
|
||||
|
||||
Wenn systemd das Restart-Limit erreicht hat (z.B. `"Start request repeated too quickly"`), hilft der **Watchdog** — er prüft alle 5 Minuten ob der Service läuft und startet ihn automatisch neu.
|
||||
|
||||
**Watchdog-Status prüfen:**
|
||||
```bash
|
||||
# Timer-Status anzeigen
|
||||
sudo systemctl status adguard-shield-watchdog.timer
|
||||
|
||||
# Letzte Watchdog-Ausführungen anzeigen
|
||||
sudo systemctl list-timers adguard-shield-watchdog.timer
|
||||
|
||||
# Watchdog-Logs prüfen
|
||||
sudo journalctl -u adguard-shield-watchdog.service --no-pager -n 20
|
||||
```
|
||||
|
||||
**Manuelles Recovery (sofort):**
|
||||
```bash
|
||||
# systemd-Fehlerzähler zurücksetzen und Service starten
|
||||
sudo systemctl reset-failed adguard-shield.service
|
||||
sudo systemctl start adguard-shield.service
|
||||
```
|
||||
|
||||
**Watchdog nachträglich aktivieren:**
|
||||
```bash
|
||||
sudo systemctl enable adguard-shield-watchdog.timer
|
||||
sudo systemctl start adguard-shield-watchdog.timer
|
||||
```
|
||||
|
||||
> **Hinweis:** Der Watchdog sendet automatisch eine Benachrichtigung (falls `NOTIFY_ENABLED=true`), wenn er den Service wiederbeleben muss oder die Recovery fehlschlägt.
|
||||
|
||||
## Update durchführen
|
||||
|
||||
```bash
|
||||
# Repository aktualisieren
|
||||
cd /tmp/adguard-shield
|
||||
git pull
|
||||
|
||||
# Update ausführen (Konfig wird automatisch migriert, Service neu gestartet)
|
||||
sudo bash install.sh update
|
||||
```
|
||||
|
||||
**Was passiert beim Update:**
|
||||
- Alle Scripts werden aktualisiert
|
||||
- Konfiguration wird als `adguard-shield.conf.old` gesichert
|
||||
- Neue Konfigurationsparameter werden automatisch zur bestehenden Konfig ergänzt
|
||||
- Bestehende Einstellungen bleiben erhalten
|
||||
- Bestehende Flat-File-Daten werden einmalig in die SQLite-Datenbank migriert (mit Fortschrittsanzeige)
|
||||
- Service wird per `daemon-reload` neu geladen und automatisch neu gestartet
|
||||
|
||||
## Deinstallation
|
||||
|
||||
Ab Version 0.6 gibt es einen eigenständigen Uninstaller im Installationsverzeichnis. Die Deinstallation kann daher jederzeit durchgeführt werden, **ohne die originalen Installationsdateien (install.sh) behalten zu müssen**:
|
||||
|
||||
```bash
|
||||
# Empfohlen: direkt aus dem Installationsverzeichnis ausführen
|
||||
sudo bash /opt/adguard-shield/uninstall.sh
|
||||
|
||||
# Alternativ: über den Installer (sofern noch vorhanden)
|
||||
sudo bash install.sh uninstall
|
||||
```
|
||||
|
||||
Beide Wege sind gleichwertig — `install.sh uninstall` delegiert intern an `/opt/adguard-shield/uninstall.sh`.
|
||||
|
||||
Oder manuell:
|
||||
```bash
|
||||
sudo systemctl stop adguard-shield
|
||||
sudo systemctl disable adguard-shield
|
||||
sudo systemctl stop adguard-shield-watchdog.timer
|
||||
sudo systemctl disable adguard-shield-watchdog.timer
|
||||
sudo /opt/adguard-shield/iptables-helper.sh remove
|
||||
sudo rm -rf /opt/adguard-shield
|
||||
sudo rm -f /etc/systemd/system/adguard-shield.service
|
||||
sudo rm -f /etc/systemd/system/adguard-shield-watchdog.service
|
||||
sudo rm -f /etc/systemd/system/adguard-shield-watchdog.timer
|
||||
ls -l /opt/adguard-shield/adguard-shield
|
||||
ls -l /opt/adguard-shield/adguard-shield.conf
|
||||
which iptables ip6tables ipset systemctl
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
## Voraussetzungen
|
||||
## Verbindung zu AdGuard Home schlägt fehl
|
||||
|
||||
Folgende Pakete werden für den Betrieb benötigt und bei der Installation automatisch installiert:
|
||||
Test:
|
||||
|
||||
| Paket | Zweck |
|
||||
|-------|-------|
|
||||
| `curl` | API-Kommunikation mit AdGuard Home |
|
||||
| `jq` | JSON-Verarbeitung der API-Antworten |
|
||||
| `iptables` | Firewall-Regeln (IPv4 + IPv6) |
|
||||
| `gawk` | Textverarbeitung in Scripts |
|
||||
| `systemd` | Service-Management und Autostart |
|
||||
| `sqlite3` | Datenbank für State-Management, Ban-History und Offense-Tracking |
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
```
|
||||
|
||||
Diese werden bei `sudo bash install.sh install` automatisch geprüft und bei Bedarf über den Paketmanager (`apt`, `dnf`, `yum`, `pacman`) nachinstalliert.
|
||||
Prüfe in `/opt/adguard-shield/adguard-shield.conf`:
|
||||
|
||||
```bash
|
||||
ADGUARD_URL="http://127.0.0.1:3000"
|
||||
ADGUARD_USER="admin"
|
||||
ADGUARD_PASS="..."
|
||||
```
|
||||
|
||||
Häufige Fehler:
|
||||
|
||||
| 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 |
|
||||
|
||||
Direkt testen:
|
||||
|
||||
```bash
|
||||
curl -k -u "admin:passwort" "http://127.0.0.1:3000/control/querylog?limit=1&response_status=all"
|
||||
```
|
||||
|
||||
Passe URL und Zugangsdaten entsprechend an.
|
||||
|
||||
## Keine Sperren trotz vieler Anfragen
|
||||
|
||||
Prüfen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield live --once
|
||||
sudo /opt/adguard-shield/adguard-shield history 50
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level debug --limit 100
|
||||
```
|
||||
|
||||
Mögliche Ursachen:
|
||||
|
||||
- `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
|
||||
|
||||
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.
|
||||
|
||||
## Zu viele Sperren
|
||||
|
||||
Erst Übersicht:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield history 100
|
||||
```
|
||||
|
||||
Dann Ursachen einordnen:
|
||||
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
Falsch gesperrte IP freigeben:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield unban 192.168.1.100
|
||||
sudo /opt/adguard-shield/adguard-shield reset-offenses 192.168.1.100
|
||||
```
|
||||
|
||||
Dauerhaft ausnehmen:
|
||||
|
||||
```bash
|
||||
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.100"
|
||||
```
|
||||
|
||||
Danach:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
## Firewall prüfen
|
||||
|
||||
Status:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-status
|
||||
```
|
||||
|
||||
Direkt prüfen:
|
||||
|
||||
```bash
|
||||
sudo ipset list adguard_shield_v4
|
||||
sudo ipset list adguard_shield_v6
|
||||
sudo iptables -n -L ADGUARD_SHIELD --line-numbers -v
|
||||
sudo ip6tables -n -L ADGUARD_SHIELD --line-numbers -v
|
||||
```
|
||||
|
||||
Firewall neu aufbauen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-remove
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-create
|
||||
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:
|
||||
|
||||
```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.
|
||||
|
||||
Permanent sind typischerweise:
|
||||
|
||||
- DNS-Flood-Watchlist-Treffer
|
||||
- Progressive-Ban-Maximalstufe
|
||||
- manuelle `ban`-Sperren
|
||||
- GeoIP-Sperren
|
||||
- externe Blocklist mit `EXTERNAL_BLOCKLIST_BAN_DURATION=0`
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
```
|
||||
|
||||
Währenddessen:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield whitelist-status
|
||||
```
|
||||
|
||||
Manuell synchronisieren:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield whitelist-sync
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
Format prüfen:
|
||||
|
||||
```text
|
||||
192.168.1.100
|
||||
10.0.0.0/24
|
||||
trusted.example.com
|
||||
# Kommentare sind erlaubt
|
||||
```
|
||||
|
||||
## Externe Blocklist
|
||||
|
||||
Status:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-status
|
||||
```
|
||||
|
||||
Manuell synchronisieren:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-sync
|
||||
```
|
||||
|
||||
Alle externen Blocklist-Sperren freigeben:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield blocklist-flush
|
||||
```
|
||||
|
||||
Wenn zu viele IPs gesperrt werden:
|
||||
|
||||
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.
|
||||
|
||||
## GeoIP
|
||||
|
||||
Status:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-status
|
||||
```
|
||||
|
||||
Einzelne IP prüfen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-lookup 8.8.8.8
|
||||
```
|
||||
|
||||
Cache leeren:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush-cache
|
||||
```
|
||||
|
||||
Alle GeoIP-Sperren freigeben:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield geoip-flush
|
||||
```
|
||||
|
||||
Typische Ursachen:
|
||||
|
||||
| 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 |
|
||||
|
||||
## Reports
|
||||
|
||||
Status:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-status
|
||||
```
|
||||
|
||||
Test:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield report-test
|
||||
sudo /opt/adguard-shield/adguard-shield report-generate txt
|
||||
```
|
||||
|
||||
Wenn keine Mail ankommt:
|
||||
|
||||
- `REPORT_EMAIL_TO` gesetzt?
|
||||
- `REPORT_MAIL_CMD` vorhanden?
|
||||
- Mailer für root konfiguriert?
|
||||
- Cron installiert?
|
||||
- Spam-Ordner geprüft?
|
||||
|
||||
Cron prüfen:
|
||||
|
||||
```bash
|
||||
sudo cat /etc/cron.d/adguard-shield-report
|
||||
sudo /opt/adguard-shield/adguard-shield report-send
|
||||
```
|
||||
|
||||
## Benachrichtigungen
|
||||
|
||||
Prüfen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield logs --level warn --limit 100
|
||||
```
|
||||
|
||||
Häufige Ursachen:
|
||||
|
||||
- `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`
|
||||
|
||||
## SQLite direkt auswerten
|
||||
|
||||
Für tiefergehende Analysen:
|
||||
|
||||
```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;"
|
||||
```
|
||||
|
||||
Letzte History:
|
||||
|
||||
```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;"
|
||||
```
|
||||
|
||||
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;"
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
Die Go-Version ersetzt diese Funktionen durch das eine Binary. Alte Worker sollten nicht parallel laufen.
|
||||
|
||||
## Service hart zurücksetzen
|
||||
|
||||
Wenn der Zustand unklar ist:
|
||||
|
||||
```bash
|
||||
sudo systemctl stop adguard-shield
|
||||
sudo /opt/adguard-shield/adguard-shield firewall-remove
|
||||
sudo systemctl start adguard-shield
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
```
|
||||
|
||||
Das entfernt die Firewall-Struktur und lässt den Daemon sie beim Start wieder aus SQLite aufbauen.
|
||||
|
||||
## Deinstallation
|
||||
|
||||
Konfiguration behalten:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield uninstall --keep-config
|
||||
```
|
||||
|
||||
Alles entfernen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield uninstall
|
||||
```
|
||||
|
||||
Ohne `--keep-config` werden Installationsverzeichnis, State-Verzeichnis und Logdatei entfernt.
|
||||
|
||||
254
docs/update.md
254
docs/update.md
@@ -1,78 +1,238 @@
|
||||
# Update-Anleitung
|
||||
|
||||
## Voraussetzungen
|
||||
AdGuard Shield wird in der Go-Version über das Binary selbst installiert und aktualisiert. Es gibt kein `install.sh` und kein `update`-Shellskript mehr.
|
||||
|
||||
- AdGuard Shield ist bereits installiert (`/opt/adguard-shield/`)
|
||||
- Git ist installiert (`sudo apt install git`)
|
||||
- Zugriff auf den Server per SSH mit Root-Rechten
|
||||
|
||||
## Update durchführen
|
||||
|
||||
### 1. Git-Repository aktualisieren
|
||||
|
||||
Wechsle in das Verzeichnis, in dem du das Repository geklont hast, und hole die neueste Version:
|
||||
## Kurzfassung
|
||||
|
||||
```bash
|
||||
cd /pfad/zum/adguard-shield
|
||||
git pull
|
||||
# neues Linux-Binary bereitstellen
|
||||
chmod +x ./adguard-shield
|
||||
|
||||
# Update durchführen
|
||||
sudo ./adguard-shield update
|
||||
```
|
||||
|
||||
> **Hinweis:** Falls du das Repository z.B. nach `/opt/adguard-shield-repo` geklont hast:
|
||||
> ```bash
|
||||
> cd /opt/adguard-shield-repo
|
||||
> git pull
|
||||
> ```
|
||||
Am Ende fragt der Updater, ob AdGuard Shield direkt neu gestartet werden soll.
|
||||
|
||||
### 2. Update-Script ausführen
|
||||
Danach prüfen:
|
||||
|
||||
```bash
|
||||
sudo bash install.sh update
|
||||
sudo /opt/adguard-shield/adguard-shield install-status
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo journalctl -u adguard-shield --no-pager -n 50
|
||||
```
|
||||
|
||||
Das Update-Script macht automatisch folgendes:
|
||||
## Woher kommt das neue Binary?
|
||||
|
||||
1. **Abhängigkeiten prüfen** — Fehlende Pakete (inkl. `sqlite3`) werden nachinstalliert
|
||||
2. **Scripts aktualisieren** — Alle `.sh`-Dateien werden nach `/opt/adguard-shield/` kopiert
|
||||
3. **Konfigurations-Migration** — Neue Parameter werden automatisch zur bestehenden Konfiguration hinzugefügt, bestehende Einstellungen bleiben **unverändert**
|
||||
4. **Backup erstellen** — Die alte Konfiguration wird als `adguard-shield.conf.old` gesichert
|
||||
5. **Datenbank-Migration (in der v1.0.0)** — Bestehende Flat-File-Daten (`.ban`, `.offenses`, Ban-History-Log) werden einmalig in die SQLite-Datenbank migriert. Die alten Dateien werden als Backup gesichert. Der Fortschritt und das Ergebnis werden im Terminal angezeigt.
|
||||
6. **Service aktualisieren** — Die systemd Service-Datei und Watchdog-Dateien werden aktualisiert und `daemon-reload` ausgeführt
|
||||
7. **Watchdog aktivieren** — Der Watchdog-Timer wird automatisch aktiviert (falls noch nicht aktiv)
|
||||
8. **Service neustarten** — Der Service wird automatisch neu gestartet (falls er vorher lief)
|
||||
Du brauchst ein fertiges Linux-Binary. Das kann aus einem Release, aus CI oder aus einem lokalen Build kommen.
|
||||
|
||||
### 3. Neue Parameter prüfen (optional)
|
||||
|
||||
Nach dem Update empfiehlt es sich, eventuell neu hinzugefügte Konfigurationsparameter zu prüfen:
|
||||
Release-Binary für v1.0.0 herunterladen:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/adguard-shield/adguard-shield.conf
|
||||
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
|
||||
```
|
||||
|
||||
Falls etwas nicht stimmt, kann das Backup wiederhergestellt werden:
|
||||
Build mit lokal installiertem Go:
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o adguard-shield ./cmd/adguard-shieldd
|
||||
```
|
||||
|
||||
Build ohne lokale Go-Installation mit Docker:
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Konfigurationsmigration
|
||||
|
||||
Vorhandene Werte bleiben erhalten. Neue Parameter werden ergänzt.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
Nach dem Update solltest du 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.
|
||||
|
||||
## Update mit Service-Neustart
|
||||
|
||||
Wenn der Service nach dem Update direkt laufen soll, bestätige die Nachfrage am Ende mit `j`.
|
||||
|
||||
Wenn du vorher manuell prüfen möchtest:
|
||||
|
||||
```bash
|
||||
sudo ./adguard-shield update
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
## 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.
|
||||
|
||||
## Migration von der alten Shell-Version
|
||||
|
||||
Die Go-Version erkennt alte Shell-Artefakte und bricht ab, wenn sie noch vorhanden sind.
|
||||
|
||||
Typische Funde:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Warum Abbruch?
|
||||
|
||||
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.
|
||||
|
||||
Empfohlener Migrationsablauf:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
# neues Go-Binary installieren und alte Konfiguration als Quelle nutzen
|
||||
sudo ./adguard-shield install --config-source /root/adguard-shield.conf.backup
|
||||
|
||||
# prüfen
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
sudo /opt/adguard-shield/adguard-shield dry-run
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield install-status
|
||||
```
|
||||
|
||||
Service:
|
||||
|
||||
```bash
|
||||
sudo systemctl status adguard-shield
|
||||
sudo journalctl -u adguard-shield --no-pager -n 100
|
||||
```
|
||||
|
||||
API:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield test
|
||||
```
|
||||
|
||||
Runtime:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield status
|
||||
sudo /opt/adguard-shield/adguard-shield live --once
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo systemctl stop adguard-shield
|
||||
sudo cp ./adguard-shield-alte-version /opt/adguard-shield/adguard-shield
|
||||
sudo chmod +x /opt/adguard-shield/adguard-shield
|
||||
sudo systemctl start adguard-shield
|
||||
```
|
||||
|
||||
Wenn die Konfiguration zurückgesetzt werden soll:
|
||||
|
||||
```bash
|
||||
sudo cp /opt/adguard-shield/adguard-shield.conf.old /opt/adguard-shield/adguard-shield.conf
|
||||
sudo systemctl restart adguard-shield
|
||||
```
|
||||
|
||||
## Kurzfassung (Copy & Paste)
|
||||
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.
|
||||
|
||||
## Backup vor größeren Updates
|
||||
|
||||
```bash
|
||||
cd /pfad/zum/adguard-shield
|
||||
git pull
|
||||
sudo bash install.sh update
|
||||
sudo systemctl stop adguard-shield
|
||||
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)
|
||||
sudo systemctl start adguard-shield
|
||||
```
|
||||
|
||||
## Versionsprüfung
|
||||
Bei laufendem SQLite mit WAL können zusätzliche Dateien existieren:
|
||||
|
||||
Installierte Version anzeigen:
|
||||
|
||||
```bash
|
||||
sudo /opt/adguard-shield/adguard-shield.sh status
|
||||
```text
|
||||
adguard-shield.db-wal
|
||||
adguard-shield.db-shm
|
||||
```
|
||||
|
||||
Oder über den Installer:
|
||||
|
||||
```bash
|
||||
sudo bash install.sh status
|
||||
```
|
||||
Am saubersten ist ein kurzer Service-Stop während des Backups.
|
||||
|
||||
Reference in New Issue
Block a user