From 5b3172faa2cdaa0461289ed50dc0832ca363b6fa Mon Sep 17 00:00:00 2001 From: scriptos Date: Thu, 5 Mar 2026 18:28:46 +0100 Subject: [PATCH] Email-Report ist jetzt implementiert. --- README.md | 10 + adguard-shield.conf | 28 ++ doc/befehle.md | 30 ++ doc/konfiguration.md | 18 + doc/report.md | 255 ++++++++++++ install.sh | 19 + report-generator.sh | 931 ++++++++++++++++++++++++++++++++++++++++++ templates/report.html | 316 ++++++++++++++ templates/report.txt | 59 +++ 9 files changed, 1666 insertions(+) create mode 100644 doc/report.md create mode 100644 report-generator.sh create mode 100644 templates/report.html create mode 100644 templates/report.txt diff --git a/README.md b/README.md index d994972..450ebac 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Wenn ein Client eine bestimmte Domain zu oft anfragt (z.B. >30x pro Minute), wir - Automatisches Entsperren nach konfigurierbarer Dauer - **Externe Blocklisten** — IP-Adressen von externen Textdateien (URLs) laden und automatisch sperren - **AbuseIPDB Reporting** — permanent gesperrte IPs automatisch an AbuseIPDB melden +- **E-Mail Reports** — periodische Statistik-Reports als HTML oder TXT (täglich, wöchentlich, zweiwöchentlich, monatlich) - **Ban-History** — lückenlose Protokollierung aller Sperren/Entsperrungen mit Zeitstempel - Whitelist für vertrauenswürdige IPs - Dry-Run Modus zum gefahrlosen Testen @@ -86,6 +87,9 @@ sudo /opt/adguard-shield/adguard-shield.sh reset-offenses # Offense-Zähler sudo /opt/adguard-shield/adguard-shield.sh test # API-Verbindung testen sudo /opt/adguard-shield/adguard-shield.sh blocklist-status # Externe Blocklisten Status sudo /opt/adguard-shield/adguard-shield.sh blocklist-sync # Blocklisten manuell synchronisieren +sudo /opt/adguard-shield/report-generator.sh send # Report jetzt senden +sudo /opt/adguard-shield/report-generator.sh status # Report-Status anzeigen +sudo /opt/adguard-shield/report-generator.sh install # Cron-Job einrichten sudo journalctl -u adguard-shield -f # Logs live verfolgen ``` @@ -98,13 +102,18 @@ sudo journalctl -u adguard-shield -f # Logs live ver ├── external-blocklist-worker.sh # Externer Blocklist-Worker ├── iptables-helper.sh # Manuelle iptables-Verwaltung ├── unban-expired.sh # Cron-basiertes Entsperren +├── report-generator.sh # E-Mail Report Generator ├── install.sh # Installer / Updater / Uninstaller +├── templates/ +│ ├── report.html # HTML-Report-Template +│ └── report.txt # TXT-Report-Template ├── README.md └── doc/ ├── architektur.md # Architektur & Funktionsweise ├── konfiguration.md # Alle Parameter erklärt + Konfig-Migration ├── befehle.md # Vollständige Befehlsreferenz inkl. Installer ├── benachrichtigungen.md # Webhook-Setup (Discord, Slack, Gotify, Ntfy) + ├── report.md # E-Mail Report Setup & Konfiguration └── tipps-und-troubleshooting.md ``` @@ -116,6 +125,7 @@ sudo journalctl -u adguard-shield -f # Logs live ver | [Konfiguration](doc/konfiguration.md) | Alle Parameter, Ports, Whitelist-Pflege, automatische Migration | | [Befehle](doc/befehle.md) | Vollständige Befehlsreferenz für Installer, Monitor, iptables-Helper und systemd | | [Benachrichtigungen](doc/benachrichtigungen.md) | Setup für Discord, Slack, Gotify, Ntfy | +| [E-Mail Report](doc/report.md) | Periodische Statistik-Reports per E-Mail (HTML/TXT) | | [Tipps & Troubleshooting](doc/tipps-und-troubleshooting.md) | Best Practices, häufige Probleme, Deinstallation | ## Lizenz diff --git a/adguard-shield.conf b/adguard-shield.conf index 90af6cd..bf13adc 100644 --- a/adguard-shield.conf +++ b/adguard-shield.conf @@ -95,6 +95,34 @@ NTFY_TOKEN="" # Priorität der Ntfy-Nachrichten (1=min, 3=default, 5=max) NTFY_PRIORITY="4" +# --- E-Mail Report (optional) --- +# Regelmäßiger Statistik-Report per E-Mail +# Voraussetzung: Ein funktionierender Mail-Transport (z.B. msmtp) +# Anleitung für msmtp: https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/ +REPORT_ENABLED=false + +# Report-Intervall: "daily", "weekly", "biweekly", "monthly" +# daily = täglich um die konfigurierte Uhrzeit +# weekly = wöchentlich am Montag +# biweekly = alle zwei Wochen am Montag +# monthly = monatlich am 1. des Monats +REPORT_INTERVAL="weekly" + +# Uhrzeit für den Report-Versand (Format: HH:MM, 24h) +REPORT_TIME="08:00" + +# E-Mail-Empfänger +REPORT_EMAIL_TO="admin@example.com" + +# E-Mail-Absender +REPORT_EMAIL_FROM="adguard-shield@example.com" + +# E-Mail-Format: "html" oder "txt" +REPORT_FORMAT="html" + +# Mail-Befehl (z.B. "msmtp", "sendmail", "mail") +REPORT_MAIL_CMD="msmtp" + # --- Externe Blocklist (optional) --- # Aktiviert den externen Blocklist-Worker EXTERNAL_BLOCKLIST_ENABLED=false diff --git a/doc/befehle.md b/doc/befehle.md index 9756577..0d85fe3 100644 --- a/doc/befehle.md +++ b/doc/befehle.md @@ -168,6 +168,36 @@ sudo /opt/adguard-shield/external-blocklist-worker.sh status sudo /opt/adguard-shield/external-blocklist-worker.sh flush ``` +## E-Mail Report + +```bash +# Report sofort generieren und per E-Mail versenden +sudo /opt/adguard-shield/report-generator.sh send + +# Test-E-Mail senden (prüft alle Voraussetzungen + Mailversand) +sudo /opt/adguard-shield/report-generator.sh test + +# Report als Datei generieren (Ausgabe auf stdout) +sudo /opt/adguard-shield/report-generator.sh generate + +# Report im HTML-Format in Datei speichern +sudo /opt/adguard-shield/report-generator.sh generate html > report.html + +# Report im TXT-Format in Datei speichern +sudo /opt/adguard-shield/report-generator.sh generate txt > report.txt + +# Cron-Job für automatischen Versand einrichten +sudo /opt/adguard-shield/report-generator.sh 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 +``` + +> Voraussetzung: Ein funktionierender Mail-Transport (z.B. msmtp). Anleitung: [Linux: Einfach E-Mails versenden mit msmtp](https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/) + ## Logs ```bash diff --git a/doc/konfiguration.md b/doc/konfiguration.md index e3cd4dd..557cb67 100644 --- a/doc/konfiguration.md +++ b/doc/konfiguration.md @@ -123,6 +123,24 @@ Wiederholungstäter werden wie bei fail2ban stufenweise länger gesperrt. Wird e | `NTFY_TOKEN` | *(leer)* | Optionaler Ntfy Access-Token | | `NTFY_PRIORITY` | `4` | Ntfy Priorität (1–5) | +### E-Mail Report + +Regelmäßige Statistik-Reports per E-Mail. Voraussetzung ist ein funktionierender Mail-Transport (z.B. msmtp). + +> **Anleitung für msmtp:** [Linux: Einfach E-Mails versenden mit msmtp](https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/) + +| Parameter | Standard | Beschreibung | +|-----------|----------|--------------| +| `REPORT_ENABLED` | `false` | Report-Funktion aktivieren | +| `REPORT_INTERVAL` | `weekly` | Intervall: `daily`, `weekly`, `biweekly`, `monthly` | +| `REPORT_TIME` | `08:00` | Versanduhrzeit (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`) | + +> Siehe [E-Mail Report Dokumentation](report.md) für Details zu Inhalten, Templates und Befehlen. + ### Erweitert | Parameter | Standard | Beschreibung | diff --git a/doc/report.md b/doc/report.md new file mode 100644 index 0000000..7494359 --- /dev/null +++ b/doc/report.md @@ -0,0 +1,255 @@ +# 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. + +## Voraussetzungen + +Der Server muss E-Mails versenden können. Empfohlen wird **msmtp** als leichtgewichtiger SMTP-Client. + +**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/) + +Alternativ funktioniert auch `sendmail`, `mail` oder ein anderer Befehl, der E-Mails über stdin entgegennimmt. + +## Aktivierung + +In der Konfiguration (`adguard-shield.conf`): + +```bash +REPORT_ENABLED=true +REPORT_INTERVAL="weekly" +REPORT_TIME="08:00" +REPORT_EMAIL_TO="admin@example.com" +REPORT_EMAIL_FROM="adguard-shield@example.com" +REPORT_FORMAT="html" +REPORT_MAIL_CMD="msmtp" +``` + +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`) | + +### 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: + +### Übersicht +- 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 im Berichtszeitraum + +### 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 + +# Test-E-Mail senden (prüft alle Voraussetzungen + Mailversand) +sudo /opt/adguard-shield/report-generator.sh test + +# Report als Datei generieren (auf stdout ausgeben) +sudo /opt/adguard-shield/report-generator.sh generate + +# 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 + +# Cron-Job für automatischen Versand einrichten +sudo /opt/adguard-shield/report-generator.sh 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 +``` + +## Report-Intervall ändern + +Um das Intervall, die Uhrzeit oder andere Einstellungen zu ändern: + +```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 +``` + +> **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: + +```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 | +| `{{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 +``` + +## Test-Mail + +Bevor du den automatischen Versand einrichtest, kannst du mit dem `test`-Befehl prüfen, ob alles funktioniert: + +```bash +sudo /opt/adguard-shield/report-generator.sh test +``` + +Der Test prüft Schritt für Schritt: + +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 + +Die Test-Mail enthält eine Übersicht der aktuellen Konfiguration und bestätigt, dass der Mailversand funktioniert. + +## Troubleshooting + +### E-Mail wird nicht versendet + +1. Prüfe ob der Mail-Befehl installiert ist: + ```bash + which msmtp + ``` + +2. Teste den Mailversand manuell: + ```bash + echo "Test" | msmtp -t deine@email.de + ``` + +3. Prüfe die msmtp-Konfiguration: + ```bash + cat ~/.msmtprc + # oder + cat /etc/msmtprc + ``` + +4. Prüfe die Report-Konfiguration: + ```bash + sudo /opt/adguard-shield/report-generator.sh status + ``` + +### Report enthält keine Daten + +Der Report basiert auf der Ban-History-Datei (`/var/log/adguard-shield-bans.log`). Wenn keine Sperren im Berichtszeitraum vorhanden sind, zeigt der Report „Keine Daten" an. + +### Cron-Job wird nicht ausgeführt + +1. Prüfe ob der Cron-Job angelegt wurde: + ```bash + cat /etc/cron.d/adguard-shield-report + ``` + +2. Prüfe die Cron-Logs: + ```bash + grep adguard-shield /var/log/syslog + # oder + journalctl -u cron + ``` diff --git a/install.sh b/install.sh index b58bf85..ec53a37 100644 --- a/install.sh +++ b/install.sh @@ -110,6 +110,13 @@ print_help() { echo -e " ${CYAN}sudo /opt/adguard-shield/iptables-helper.sh save${NC} # Regeln speichern" echo -e " ${CYAN}sudo /opt/adguard-shield/iptables-helper.sh restore${NC} # Regeln wiederherstellen" echo "" + echo -e "${BOLD}Report-Befehle:${NC}" + echo -e " ${CYAN}sudo /opt/adguard-shield/report-generator.sh status${NC} # Report-Konfiguration anzeigen" + echo -e " ${CYAN}sudo /opt/adguard-shield/report-generator.sh send${NC} # Report sofort senden" + echo -e " ${CYAN}sudo /opt/adguard-shield/report-generator.sh generate${NC} # Report als Datei generieren" + echo -e " ${CYAN}sudo /opt/adguard-shield/report-generator.sh install${NC} # Cron-Job einrichten" + echo -e " ${CYAN}sudo /opt/adguard-shield/report-generator.sh remove${NC} # Cron-Job entfernen" + echo "" echo -e "${BOLD}Voraussetzungen:${NC}" echo " - Linux Server (Debian/Ubuntu empfohlen)" echo " - Root-Zugriff (sudo)" @@ -231,12 +238,19 @@ install_files() { cp "$SCRIPT_DIR/iptables-helper.sh" "$INSTALL_DIR/" cp "$SCRIPT_DIR/unban-expired.sh" "$INSTALL_DIR/" cp "$SCRIPT_DIR/external-blocklist-worker.sh" "$INSTALL_DIR/" + cp "$SCRIPT_DIR/report-generator.sh" "$INSTALL_DIR/" + + # Templates kopieren + mkdir -p "$INSTALL_DIR/templates" + cp "$SCRIPT_DIR/templates/report.html" "$INSTALL_DIR/templates/" + cp "$SCRIPT_DIR/templates/report.txt" "$INSTALL_DIR/templates/" # Ausführbar machen chmod +x "$INSTALL_DIR/adguard-shield.sh" chmod +x "$INSTALL_DIR/iptables-helper.sh" chmod +x "$INSTALL_DIR/unban-expired.sh" chmod +x "$INSTALL_DIR/external-blocklist-worker.sh" + chmod +x "$INSTALL_DIR/report-generator.sh" echo -e " ✅ Dateien installiert" echo "" @@ -497,6 +511,11 @@ print_summary() { echo " sudo $INSTALL_DIR/adguard-shield.sh flush" echo " sudo $INSTALL_DIR/adguard-shield.sh unban " echo "" + echo " E-Mail Report:" + echo " sudo $INSTALL_DIR/report-generator.sh status" + echo " sudo $INSTALL_DIR/report-generator.sh install" + echo " sudo $INSTALL_DIR/report-generator.sh send" + echo "" echo " Hilfe anzeigen:" echo " sudo bash install.sh --help" echo "" diff --git a/report-generator.sh b/report-generator.sh new file mode 100644 index 0000000..32dfcec --- /dev/null +++ b/report-generator.sh @@ -0,0 +1,931 @@ +#!/bin/bash +############################################################################### +# AdGuard Shield - Report Generator +# Erstellt und versendet periodische Statistik-Reports per E-Mail. +# +# Nutzung: +# report-generator.sh send – Report sofort generieren und versenden +# report-generator.sh test – Test-E-Mail senden (Konfiguration prüfen) +# report-generator.sh generate – Report als Datei generieren (ohne Versand) +# report-generator.sh install – Cron-Job einrichten +# report-generator.sh remove – Cron-Job entfernen +# report-generator.sh status – Cron-Status anzeigen +# +# Crontab-Eintrag (wird automatisch verwaltet): +# Wird je nach REPORT_INTERVAL als Cron-Job unter /etc/cron.d/ angelegt. +# +# Autor: Patrick Asmus +# E-Mail: support@techniverse.net +# Lizenz: MIT +############################################################################### + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/adguard-shield.conf" +CRON_FILE="/etc/cron.d/adguard-shield-report" + +# ─── Konfiguration laden ─────────────────────────────────────────────────────── +if [[ ! -f "$CONFIG_FILE" ]]; then + echo "FEHLER: Konfigurationsdatei nicht gefunden: $CONFIG_FILE" >&2 + exit 1 +fi +# shellcheck source=adguard-shield.conf +source "$CONFIG_FILE" + +# ─── Standardwerte ──────────────────────────────────────────────────────────── +REPORT_ENABLED="${REPORT_ENABLED:-false}" +REPORT_INTERVAL="${REPORT_INTERVAL:-weekly}" +REPORT_TIME="${REPORT_TIME:-08:00}" +REPORT_EMAIL_TO="${REPORT_EMAIL_TO:-}" +REPORT_EMAIL_FROM="${REPORT_EMAIL_FROM:-adguard-shield@$(hostname -f 2>/dev/null || hostname)}" +REPORT_FORMAT="${REPORT_FORMAT:-html}" +REPORT_MAIL_CMD="${REPORT_MAIL_CMD:-msmtp}" +BAN_HISTORY_FILE="${BAN_HISTORY_FILE:-/var/log/adguard-shield-bans.log}" +STATE_DIR="${STATE_DIR:-/var/lib/adguard-shield}" +TEMPLATE_DIR="${SCRIPT_DIR}/templates" + +# Version aus dem Hauptscript auslesen +VERSION="unknown" +if [[ -f "${SCRIPT_DIR}/adguard-shield.sh" ]]; then + VERSION=$(grep -m1 '^VERSION=' "${SCRIPT_DIR}/adguard-shield.sh" 2>/dev/null | cut -d'"' -f2) + VERSION="${VERSION:-unknown}" +fi + +# ─── Logging ────────────────────────────────────────────────────────────────── +LOG_FILE="${LOG_FILE:-/var/log/adguard-shield.log}" + +log() { + local level="$1" + shift + local message="$*" + local timestamp + timestamp="$(date '+%Y-%m-%d %H:%M:%S')" + echo "[$timestamp] [$level] [REPORT] $message" | tee -a "$LOG_FILE" +} + +# ─── Berichtszeitraum berechnen ─────────────────────────────────────────────── +get_report_period() { + local now_epoch + now_epoch=$(date '+%s') + local start_epoch + local period_label + + case "$REPORT_INTERVAL" in + daily) + start_epoch=$((now_epoch - 86400)) + period_label="Tagesbericht" + ;; + weekly) + start_epoch=$((now_epoch - 604800)) + period_label="Wochenbericht" + ;; + biweekly) + start_epoch=$((now_epoch - 1209600)) + period_label="Zweiwochenbericht" + ;; + monthly) + start_epoch=$((now_epoch - 2592000)) + period_label="Monatsbericht" + ;; + *) + start_epoch=$((now_epoch - 604800)) + period_label="Bericht" + ;; + esac + + local start_date + start_date=$(date -d "@$start_epoch" '+%d.%m.%Y' 2>/dev/null || date -r "$start_epoch" '+%d.%m.%Y') + local end_date + end_date=$(date '+%d.%m.%Y') + + echo "${period_label}: ${start_date} – ${end_date}" +} + +get_period_start_epoch() { + local now_epoch + now_epoch=$(date '+%s') + + case "$REPORT_INTERVAL" in + daily) echo $((now_epoch - 86400)) ;; + weekly) echo $((now_epoch - 604800)) ;; + biweekly) echo $((now_epoch - 1209600)) ;; + monthly) echo $((now_epoch - 2592000)) ;; + *) echo $((now_epoch - 604800)) ;; + esac +} + +# ─── Ban-History filtern nach Zeitraum ──────────────────────────────────────── +# Gibt nur Zeilen zurück, deren Zeitstempel im Berichtszeitraum liegen +filter_history_by_period() { + local start_epoch="$1" + + if [[ ! -f "$BAN_HISTORY_FILE" ]]; then + return + fi + + while IFS= read -r line; do + # Kommentare und leere Zeilen überspringen + [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue + + # Zeitstempel extrahieren (erstes Feld, Format: YYYY-MM-DD HH:MM:SS) + local timestamp + timestamp=$(echo "$line" | awk -F'|' '{print $1}' | xargs) + + if [[ -z "$timestamp" ]]; then + continue + fi + + # Timestamp in Epoch umwandeln + local line_epoch + line_epoch=$(date -d "$timestamp" '+%s' 2>/dev/null || date -j -f '%Y-%m-%d %H:%M:%S' "$timestamp" '+%s' 2>/dev/null || echo "0") + + if [[ "$line_epoch" -ge "$start_epoch" ]]; then + echo "$line" + fi + done < "$BAN_HISTORY_FILE" +} + +# ─── Statistiken berechnen ──────────────────────────────────────────────────── +calculate_stats() { + local start_epoch + start_epoch=$(get_period_start_epoch) + + local filtered_data + filtered_data=$(filter_history_by_period "$start_epoch") + + # Wenn keine Daten vorhanden, Standardwerte + if [[ -z "$filtered_data" ]]; then + TOTAL_BANS=0 + TOTAL_UNBANS=0 + UNIQUE_IPS=0 + PERMANENT_BANS=0 + ACTIVE_BANS=0 + ABUSEIPDB_REPORTS=0 + RATELIMIT_BANS=0 + SUBDOMAIN_FLOOD_BANS=0 + EXTERNAL_BLOCKLIST_BANS=0 + BUSIEST_DAY="–" + TOP10_IPS="" + TOP10_DOMAINS="" + PROTOCOL_STATS="" + RECENT_BANS="" + return + fi + + # Gesamtzahl Sperren + TOTAL_BANS=$(echo "$filtered_data" | grep -c '| BAN ' || echo "0") + + # Gesamtzahl Entsperrungen + TOTAL_UNBANS=$(echo "$filtered_data" | grep -c '| UNBAN ' || echo "0") + + # Eindeutige IPs (nur BAN-Einträge) + UNIQUE_IPS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $3}' | xargs -I{} echo {} | sort -u | wc -l | xargs) + + # Permanente Sperren (Dauer enthält "PERMANENT" oder "permanent") + PERMANENT_BANS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $6}' | grep -ic 'permanent' || echo "0") + + # Aktuell aktive Sperren (aus State-Dateien) + ACTIVE_BANS=0 + if [[ -d "$STATE_DIR" ]]; then + for f in "${STATE_DIR}"/*.ban; do + [[ -f "$f" ]] && ACTIVE_BANS=$((ACTIVE_BANS + 1)) + done + fi + + # AbuseIPDB Reports (suche in Log-Datei) + ABUSEIPDB_REPORTS=0 + if [[ -f "$LOG_FILE" ]]; then + local abuseipdb_start_date + abuseipdb_start_date=$(date -d "@$start_epoch" '+%Y-%m-%d' 2>/dev/null || date -r "$start_epoch" '+%Y-%m-%d') + ABUSEIPDB_REPORTS=$(grep -c "AbuseIPDB: IP .* erfolgreich gemeldet" "$LOG_FILE" 2>/dev/null | head -1 || echo "0") + fi + + # Angriffsarten + RATELIMIT_BANS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $8}' | grep -ic 'rate-limit' || echo "0") + SUBDOMAIN_FLOOD_BANS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $8}' | grep -ic 'subdomain-flood' || echo "0") + EXTERNAL_BLOCKLIST_BANS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $8}' | grep -ic 'external-blocklist' || echo "0") + + # Aktivster Tag + BUSIEST_DAY=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $1}' | xargs -I{} echo {} | awk '{print $1}' | sort | uniq -c | sort -rn | head -1 | awk '{print $2}' || echo "–") + if [[ -z "$BUSIEST_DAY" ]]; then + BUSIEST_DAY="–" + else + # Datum in DE-Format umwandeln + local busiest_formatted + busiest_formatted=$(date -d "$BUSIEST_DAY" '+%d.%m.%Y' 2>/dev/null || echo "$BUSIEST_DAY") + BUSIEST_DAY="$busiest_formatted" + fi + + # Top 10 IPs (nach Häufigkeit der Sperren) + TOP10_IPS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $3}' | xargs -I{} echo {} | sort | uniq -c | sort -rn | head -10) + + # Top 10 Domains (nach Häufigkeit) + TOP10_DOMAINS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $4}' | xargs -I{} echo {} | sed 's/^-$//' | grep -v '^$' | sort | uniq -c | sort -rn | head -10) + + # Protokoll-Verteilung + PROTOCOL_STATS=$(echo "$filtered_data" | grep '| BAN ' | awk -F'|' '{print $7}' | xargs -I{} echo {} | sed 's/^-$/unbekannt/' | grep -v '^$' | sort | uniq -c | sort -rn) + + # Letzte 10 Sperren + RECENT_BANS=$(echo "$filtered_data" | grep '| BAN ' | tail -10) +} + +# ─── HTML-Tabellen generieren ───────────────────────────────────────────────── +generate_top10_ips_html() { + if [[ -z "$TOP10_IPS" ]]; then + echo '
Keine Daten im Berichtszeitraum
' + return + fi + + local max_count + max_count=$(echo "$TOP10_IPS" | head -1 | awk '{print $1}') + + local html='' + local rank=0 + + while read -r count ip; do + [[ -z "$count" || -z "$ip" ]] && continue + rank=$((rank + 1)) + local rank_class="" + [[ $rank -le 3 ]] && rank_class=" top3" + local bar_width=100 + if [[ "$max_count" -gt 0 ]]; then + bar_width=$((count * 100 / max_count)) + fi + html+="" + html+="" + html+="" + html+="" + done <<< "$TOP10_IPS" + + html+='
#IP-AdresseSperren
${rank}${ip}
${count}
' + echo "$html" +} + +generate_top10_domains_html() { + if [[ -z "$TOP10_DOMAINS" ]]; then + echo '
Keine Daten im Berichtszeitraum
' + return + fi + + local max_count + max_count=$(echo "$TOP10_DOMAINS" | head -1 | awk '{print $1}') + + local html='' + local rank=0 + + while read -r count domain; do + [[ -z "$count" || -z "$domain" ]] && continue + rank=$((rank + 1)) + local rank_class="" + [[ $rank -le 3 ]] && rank_class=" top3" + local bar_width=100 + if [[ "$max_count" -gt 0 ]]; then + bar_width=$((count * 100 / max_count)) + fi + html+="" + html+="" + html+="" + html+="" + done <<< "$TOP10_DOMAINS" + + html+='
#DomainSperren
${rank}${domain}
${count}
' + echo "$html" +} + +generate_protocol_html() { + if [[ -z "$PROTOCOL_STATS" ]]; then + echo '
Keine Daten im Berichtszeitraum
' + return + fi + + local html='' + + while read -r count proto; do + [[ -z "$count" || -z "$proto" ]] && continue + local badge_class="" + case "${proto,,}" in + dns*) badge_class="dns" ;; + doh*) badge_class="doh" ;; + dot*) badge_class="dot" ;; + doq*) badge_class="doq" ;; + esac + html+="" + html+="" + done <<< "$PROTOCOL_STATS" + + html+='
ProtokollAnzahl Sperren
${proto}${count}
' + echo "$html" +} + +generate_recent_bans_html() { + if [[ -z "$RECENT_BANS" ]]; then + echo '
Keine Sperren im Berichtszeitraum
' + return + fi + + local html='' + + while IFS='|' read -r timestamp action ip domain count duration protocol reason; do + timestamp=$(echo "$timestamp" | xargs) + ip=$(echo "$ip" | xargs) + domain=$(echo "$domain" | xargs) + reason=$(echo "$reason" | xargs) + [[ "$domain" == "-" ]] && domain="–" + [[ -z "$reason" ]] && reason="rate-limit" + + local reason_class="rate-limit" + [[ "$reason" == *"subdomain"* ]] && reason_class="subdomain-flood" + [[ "$reason" == *"external"* ]] && reason_class="external" + + # Datum kürzen für Anzeige + local short_time + short_time=$(echo "$timestamp" | awk '{print $1" "$2}' | cut -c6-) + + html+="" + html+="" + html+="" + html+="" + html+="" + done <<< "$RECENT_BANS" + + html+='
ZeitpunktIPDomainGrund
${short_time}${ip}${domain}${reason}
' + echo "$html" +} + +# ─── TXT-Tabellen generieren ────────────────────────────────────────────────── +generate_top10_ips_txt() { + if [[ -z "$TOP10_IPS" ]]; then + echo " Keine Daten im Berichtszeitraum" + return + fi + + local rank=0 + printf " %-4s %-42s %s\n" "#" "IP-Adresse" "Sperren" + printf " %-4s %-42s %s\n" "──" "──────────────────────────────────────────" "───────" + + while read -r count ip; do + [[ -z "$count" || -z "$ip" ]] && continue + rank=$((rank + 1)) + printf " %-4s %-42s %s\n" "${rank}." "$ip" "$count" + done <<< "$TOP10_IPS" +} + +generate_top10_domains_txt() { + if [[ -z "$TOP10_DOMAINS" ]]; then + echo " Keine Daten im Berichtszeitraum" + return + fi + + local rank=0 + printf " %-4s %-42s %s\n" "#" "Domain" "Sperren" + printf " %-4s %-42s %s\n" "──" "──────────────────────────────────────────" "───────" + + while read -r count domain; do + [[ -z "$count" || -z "$domain" ]] && continue + rank=$((rank + 1)) + printf " %-4s %-42s %s\n" "${rank}." "$domain" "$count" + done <<< "$TOP10_DOMAINS" +} + +generate_protocol_txt() { + if [[ -z "$PROTOCOL_STATS" ]]; then + echo " Keine Daten im Berichtszeitraum" + return + fi + + printf " %-20s %s\n" "Protokoll" "Anzahl" + printf " %-20s %s\n" "────────────────────" "──────" + + while read -r count proto; do + [[ -z "$count" || -z "$proto" ]] && continue + printf " %-20s %s\n" "$proto" "$count" + done <<< "$PROTOCOL_STATS" +} + +generate_recent_bans_txt() { + if [[ -z "$RECENT_BANS" ]]; then + echo " Keine Sperren im Berichtszeitraum" + return + fi + + printf " %-17s %-42s %-30s %s\n" "Zeitpunkt" "IP" "Domain" "Grund" + printf " %-17s %-42s %-30s %s\n" "─────────────────" "──────────────────────────────────────────" "──────────────────────────────" "──────────" + + while IFS='|' read -r timestamp action ip domain count duration protocol reason; do + timestamp=$(echo "$timestamp" | xargs) + ip=$(echo "$ip" | xargs) + domain=$(echo "$domain" | xargs) + reason=$(echo "$reason" | xargs) + [[ "$domain" == "-" ]] && domain="–" + [[ -z "$reason" ]] && reason="rate-limit" + + local short_time + short_time=$(echo "$timestamp" | awk '{print $1" "$2}' | cut -c6-) + + printf " %-17s %-42s %-30s %s\n" "$short_time" "$ip" "$domain" "$reason" + done <<< "$RECENT_BANS" +} + +# ─── Report generieren ──────────────────────────────────────────────────────── +generate_report() { + local format="${1:-$REPORT_FORMAT}" + + log "INFO" "Generiere ${format^^}-Report..." + + # Statistiken berechnen + calculate_stats + + local report_period + report_period=$(get_report_period) + local report_date + report_date=$(date '+%d.%m.%Y %H:%M:%S') + local hostname + hostname=$(hostname -f 2>/dev/null || hostname) + + if [[ "$format" == "html" ]]; then + local template_file="${TEMPLATE_DIR}/report.html" + if [[ ! -f "$template_file" ]]; then + log "ERROR" "HTML-Template nicht gefunden: $template_file" + return 1 + fi + + local report + report=$(cat "$template_file") + + # Tabellen generieren + local top10_ips_table + top10_ips_table=$(generate_top10_ips_html) + local top10_domains_table + top10_domains_table=$(generate_top10_domains_html) + local protocol_table + protocol_table=$(generate_protocol_html) + local recent_bans_table + recent_bans_table=$(generate_recent_bans_html) + + # Platzhalter ersetzen + report="${report//\{\{REPORT_PERIOD\}\}/$report_period}" + report="${report//\{\{REPORT_DATE\}\}/$report_date}" + report="${report//\{\{HOSTNAME\}\}/$hostname}" + report="${report//\{\{VERSION\}\}/$VERSION}" + report="${report//\{\{TOTAL_BANS\}\}/$TOTAL_BANS}" + report="${report//\{\{TOTAL_UNBANS\}\}/$TOTAL_UNBANS}" + report="${report//\{\{UNIQUE_IPS\}\}/$UNIQUE_IPS}" + report="${report//\{\{PERMANENT_BANS\}\}/$PERMANENT_BANS}" + report="${report//\{\{ACTIVE_BANS\}\}/$ACTIVE_BANS}" + report="${report//\{\{ABUSEIPDB_REPORTS\}\}/$ABUSEIPDB_REPORTS}" + report="${report//\{\{RATELIMIT_BANS\}\}/$RATELIMIT_BANS}" + report="${report//\{\{SUBDOMAIN_FLOOD_BANS\}\}/$SUBDOMAIN_FLOOD_BANS}" + report="${report//\{\{EXTERNAL_BLOCKLIST_BANS\}\}/$EXTERNAL_BLOCKLIST_BANS}" + report="${report//\{\{BUSIEST_DAY\}\}/$BUSIEST_DAY}" + report="${report//\{\{TOP10_IPS_TABLE\}\}/$top10_ips_table}" + report="${report//\{\{TOP10_DOMAINS_TABLE\}\}/$top10_domains_table}" + report="${report//\{\{PROTOCOL_TABLE\}\}/$protocol_table}" + report="${report//\{\{RECENT_BANS_TABLE\}\}/$recent_bans_table}" + + echo "$report" + + elif [[ "$format" == "txt" ]]; then + local template_file="${TEMPLATE_DIR}/report.txt" + if [[ ! -f "$template_file" ]]; then + log "ERROR" "TXT-Template nicht gefunden: $template_file" + return 1 + fi + + local report + report=$(cat "$template_file") + + # Text-Tabellen generieren + local top10_ips_txt + top10_ips_txt=$(generate_top10_ips_txt) + local top10_domains_txt + top10_domains_txt=$(generate_top10_domains_txt) + local protocol_txt + protocol_txt=$(generate_protocol_txt) + local recent_bans_txt + recent_bans_txt=$(generate_recent_bans_txt) + + # Platzhalter ersetzen + report="${report//\{\{REPORT_PERIOD\}\}/$report_period}" + report="${report//\{\{REPORT_DATE\}\}/$report_date}" + report="${report//\{\{HOSTNAME\}\}/$hostname}" + report="${report//\{\{VERSION\}\}/$VERSION}" + report="${report//\{\{TOTAL_BANS\}\}/$TOTAL_BANS}" + report="${report//\{\{TOTAL_UNBANS\}\}/$TOTAL_UNBANS}" + report="${report//\{\{UNIQUE_IPS\}\}/$UNIQUE_IPS}" + report="${report//\{\{PERMANENT_BANS\}\}/$PERMANENT_BANS}" + report="${report//\{\{ACTIVE_BANS\}\}/$ACTIVE_BANS}" + report="${report//\{\{ABUSEIPDB_REPORTS\}\}/$ABUSEIPDB_REPORTS}" + report="${report//\{\{RATELIMIT_BANS\}\}/$RATELIMIT_BANS}" + report="${report//\{\{SUBDOMAIN_FLOOD_BANS\}\}/$SUBDOMAIN_FLOOD_BANS}" + report="${report//\{\{EXTERNAL_BLOCKLIST_BANS\}\}/$EXTERNAL_BLOCKLIST_BANS}" + report="${report//\{\{BUSIEST_DAY\}\}/$BUSIEST_DAY}" + report="${report//\{\{TOP10_IPS_TEXT\}\}/$top10_ips_txt}" + report="${report//\{\{TOP10_DOMAINS_TEXT\}\}/$top10_domains_txt}" + report="${report//\{\{PROTOCOL_TEXT\}\}/$protocol_txt}" + report="${report//\{\{RECENT_BANS_TEXT\}\}/$recent_bans_txt}" + + echo "$report" + else + log "ERROR" "Unbekanntes Report-Format: $format" + return 1 + fi +} + +# ─── E-Mail senden ──────────────────────────────────────────────────────────── +send_report_email() { + if [[ -z "$REPORT_EMAIL_TO" ]]; then + log "ERROR" "Kein E-Mail-Empfänger konfiguriert (REPORT_EMAIL_TO)" + return 1 + fi + + # Prüfen ob Mail-Befehl verfügbar + if ! command -v "$REPORT_MAIL_CMD" &>/dev/null; then + log "ERROR" "Mail-Befehl nicht gefunden: $REPORT_MAIL_CMD" + log "ERROR" "Bitte installieren, z.B.: sudo apt install msmtp msmtp-mta" + log "ERROR" "Anleitung: https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/" + return 1 + fi + + local report_content + report_content=$(generate_report "$REPORT_FORMAT") + + if [[ -z "$report_content" ]]; then + log "ERROR" "Report-Generierung fehlgeschlagen – keine Daten" + return 1 + fi + + local subject="🛡️ AdGuard Shield $(get_report_period) – $(hostname)" + local content_type="text/plain" + [[ "$REPORT_FORMAT" == "html" ]] && content_type="text/html" + + log "INFO" "Sende Report an ${REPORT_EMAIL_TO} via ${REPORT_MAIL_CMD}..." + + # E-Mail zusammenbauen und senden + { + echo "From: ${REPORT_EMAIL_FROM}" + echo "To: ${REPORT_EMAIL_TO}" + echo "Subject: ${subject}" + echo "MIME-Version: 1.0" + echo "Content-Type: ${content_type}; charset=UTF-8" + echo "Content-Transfer-Encoding: 8bit" + echo "X-Mailer: AdGuard Shield Report Generator" + echo "" + echo "$report_content" + } | "$REPORT_MAIL_CMD" -t 2>&1 || { + log "ERROR" "E-Mail-Versand fehlgeschlagen (Exit-Code: $?)" + log "ERROR" "Prüfe die ${REPORT_MAIL_CMD}-Konfiguration" + return 1 + } + + log "INFO" "Report erfolgreich an ${REPORT_EMAIL_TO} gesendet" +} + +# ─── Cron-Job verwalten ─────────────────────────────────────────────────────── +install_cron() { + if [[ "$REPORT_ENABLED" != "true" ]]; then + log "WARN" "Report ist deaktiviert (REPORT_ENABLED=false)" + echo "Report ist deaktiviert. Bitte REPORT_ENABLED=true setzen." + return 1 + fi + + local hour minute + hour=$(echo "$REPORT_TIME" | cut -d: -f1 | sed 's/^0//') + minute=$(echo "$REPORT_TIME" | cut -d: -f2 | sed 's/^0//') + + local cron_schedule + + case "$REPORT_INTERVAL" in + daily) + cron_schedule="${minute} ${hour} * * *" + ;; + weekly) + # Montag + cron_schedule="${minute} ${hour} * * 1" + ;; + biweekly) + # Alle zwei Wochen am Montag (ungerade Kalenderwochen) + # Nutzt einen Test im Befehl selbst, da Cron keine 2-Wochen-Logik kann + cron_schedule="${minute} ${hour} * * 1" + ;; + monthly) + # 1. des Monats + cron_schedule="${minute} ${hour} 1 * *" + ;; + *) + log "ERROR" "Unbekanntes Intervall: $REPORT_INTERVAL" + return 1 + ;; + esac + + local cron_cmd="${SCRIPT_DIR}/report-generator.sh send" + + # Bei biweekly: Prüfung auf ungerade Kalenderwoche einbauen + if [[ "$REPORT_INTERVAL" == "biweekly" ]]; then + cron_cmd="[ \$(( \$(date +\\%V) \\% 2 )) -eq 1 ] && ${SCRIPT_DIR}/report-generator.sh send" + fi + + # Cron-Datei schreiben + cat > "$CRON_FILE" << EOF +# AdGuard Shield - Automatischer Report +# Generiert von: report-generator.sh install +# Intervall: ${REPORT_INTERVAL} +# Uhrzeit: ${REPORT_TIME} +SHELL=/bin/bash +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +${cron_schedule} root ${cron_cmd} >> /var/log/adguard-shield.log 2>&1 +EOF + + chmod 644 "$CRON_FILE" + + log "INFO" "Cron-Job installiert: $CRON_FILE" + echo "✅ Cron-Job installiert: $CRON_FILE" + echo " Intervall: $REPORT_INTERVAL" + echo " Uhrzeit: $REPORT_TIME" + echo " Schedule: $cron_schedule" + echo " Empfänger: $REPORT_EMAIL_TO" +} + +remove_cron() { + if [[ -f "$CRON_FILE" ]]; then + rm -f "$CRON_FILE" + log "INFO" "Cron-Job entfernt: $CRON_FILE" + echo "✅ Cron-Job entfernt" + else + echo "ℹ️ Kein Cron-Job vorhanden" + fi +} + +show_cron_status() { + echo "═══════════════════════════════════════════════════════════════" + echo " AdGuard Shield – Report Status" + echo "═══════════════════════════════════════════════════════════════" + echo "" + echo " Report aktiviert: ${REPORT_ENABLED}" + echo " Intervall: ${REPORT_INTERVAL}" + echo " Uhrzeit: ${REPORT_TIME}" + echo " Format: ${REPORT_FORMAT}" + echo " Empfänger: ${REPORT_EMAIL_TO:-nicht konfiguriert}" + echo " Absender: ${REPORT_EMAIL_FROM}" + echo " Mail-Befehl: ${REPORT_MAIL_CMD}" + echo "" + + if command -v "$REPORT_MAIL_CMD" &>/dev/null; then + echo " ✅ ${REPORT_MAIL_CMD} ist installiert" + else + echo " ❌ ${REPORT_MAIL_CMD} ist NICHT installiert" + echo " → Anleitung: https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/" + fi + + echo "" + + if [[ -f "$CRON_FILE" ]]; then + echo " ✅ Cron-Job aktiv:" + grep -v '^#' "$CRON_FILE" | grep -v '^$' | grep -v '^SHELL\|^PATH' | sed 's/^/ /' + else + echo " ❌ Kein Cron-Job installiert" + echo " → Einrichten mit: sudo $(basename "$0") install" + fi + + echo "" + echo "═══════════════════════════════════════════════════════════════" +} + +# ─── Test-E-Mail senden ─────────────────────────────────────────────────────── +send_test_email() { + echo "═══════════════════════════════════════════════════════════════" + echo " AdGuard Shield – E-Mail Test" + echo "═══════════════════════════════════════════════════════════════" + echo "" + + local errors=0 + + # 1. Empfänger prüfen + echo -n " 1) E-Mail-Empfänger ... " + if [[ -z "$REPORT_EMAIL_TO" ]]; then + echo "❌ nicht konfiguriert (REPORT_EMAIL_TO ist leer)" + errors=$((errors + 1)) + else + echo "✅ $REPORT_EMAIL_TO" + fi + + # 2. Absender prüfen + echo -n " 2) E-Mail-Absender ... " + echo "✅ $REPORT_EMAIL_FROM" + + # 3. Mail-Befehl prüfen + echo -n " 3) Mail-Befehl ($REPORT_MAIL_CMD) ... " + if command -v "$REPORT_MAIL_CMD" &>/dev/null; then + local mail_path + mail_path=$(command -v "$REPORT_MAIL_CMD") + echo "✅ gefunden ($mail_path)" + else + echo "❌ NICHT gefunden" + echo " → Installieren: sudo apt install msmtp msmtp-mta" + echo " → Anleitung: https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/" + errors=$((errors + 1)) + fi + + # 4. Templates prüfen + echo -n " 4) Report-Template ($REPORT_FORMAT) ... " + local tpl="${TEMPLATE_DIR}/report.${REPORT_FORMAT}" + if [[ -f "$tpl" ]]; then + echo "✅ vorhanden" + else + echo "❌ nicht gefunden: $tpl" + errors=$((errors + 1)) + fi + + # 5. Ban-History prüfen + echo -n " 5) Ban-History ... " + if [[ -f "$BAN_HISTORY_FILE" ]]; then + local lines + lines=$(grep -vc '^#' "$BAN_HISTORY_FILE" 2>/dev/null || echo "0") + echo "✅ vorhanden ($lines Einträge)" + else + echo "⚠️ nicht vorhanden (Report wird leer sein – das ist OK für einen Test)" + fi + + echo "" + + if [[ $errors -gt 0 ]]; then + echo " ❌ $errors Fehler gefunden – bitte zuerst beheben." + echo "" + echo "═══════════════════════════════════════════════════════════════" + return 1 + fi + + # 6. Test-Mail senden + echo " 6) Sende Test-E-Mail an ${REPORT_EMAIL_TO} ..." + echo "" + + local hostname + hostname=$(hostname -f 2>/dev/null || hostname) + local test_date + test_date=$(date '+%d.%m.%Y %H:%M:%S') + local subject="🧪 AdGuard Shield – Test-Mail von ${hostname}" + local content_type="text/plain" + [[ "$REPORT_FORMAT" == "html" ]] && content_type="text/html" + + local test_body + if [[ "$REPORT_FORMAT" == "html" ]]; then + test_body=$(cat < + + +
+
+

🧪 Test-Mail

+

AdGuard Shield Report

+
+
+

✅ E-Mail-Versand funktioniert!

+

Diese Test-Mail bestätigt, dass der E-Mail-Versand für AdGuard Shield korrekt konfiguriert ist.

+ + + + + + + + +
Hostname${hostname}
Zeitpunkt${test_date}
Empfänger${REPORT_EMAIL_TO}
Absender${REPORT_EMAIL_FROM}
Mail-Befehl${REPORT_MAIL_CMD}
Format${REPORT_FORMAT}
Intervall${REPORT_INTERVAL}
+

Ab jetzt kannst du den automatischen Versand aktivieren mit:
sudo $(basename "$0") install

+
+
+patrick-asmus.de +| +Git Repository +
AdGuard Shield v${VERSION} · ${hostname}
+
+
+ +TESTHTML +) + else + test_body=$(cat <&1 + ) + local exit_code=$? + + if [[ $exit_code -eq 0 ]]; then + echo " ✅ Test-E-Mail erfolgreich gesendet!" + echo "" + echo " Prüfe dein Postfach: ${REPORT_EMAIL_TO}" + echo " (Evtl. auch im Spam-Ordner nachschauen)" + log "INFO" "Test-E-Mail erfolgreich an ${REPORT_EMAIL_TO} gesendet" + else + echo " ❌ Versand fehlgeschlagen (Exit-Code: $exit_code)" + if [[ -n "$send_output" ]]; then + echo "" + echo " Fehlermeldung:" + echo "$send_output" | sed 's/^/ /' + fi + echo "" + echo " Troubleshooting:" + echo " 1) ${REPORT_MAIL_CMD}-Konfiguration prüfen" + echo " 2) Manuell testen: echo 'Test' | ${REPORT_MAIL_CMD} -t ${REPORT_EMAIL_TO}" + echo " 3) Anleitung: https://www.cleveradmin.de/blog/2024/12/linux-einfach-emails-versenden-mit-msmtp/" + log "ERROR" "Test-E-Mail fehlgeschlagen (Exit-Code: $exit_code): $send_output" + fi + + echo "" + echo "═══════════════════════════════════════════════════════════════" +} + +# ─── Hilfe ──────────────────────────────────────────────────────────────────── +print_help() { + echo "AdGuard Shield – Report Generator" + echo "" + echo "Nutzung: $(basename "$0") " + echo "" + echo "Befehle:" + echo " send Report generieren und per E-Mail versenden" + echo " test Test-E-Mail senden (prüft Konfiguration + Mailversand)" + echo " generate Report als Datei generieren (Ausgabe auf stdout)" + echo " install Cron-Job für automatischen Versand einrichten" + echo " remove Cron-Job entfernen" + echo " status Report-Konfiguration und Cron-Status anzeigen" + echo " --help Diese Hilfe anzeigen" + echo "" + echo "Beispiele:" + echo " sudo $(basename "$0") send # Report jetzt senden" + echo " sudo $(basename "$0") test # Test-Mail senden" + echo " sudo $(basename "$0") generate > r.html # Report in Datei speichern" + echo " sudo $(basename "$0") install # Automatischen Versand einrichten" + echo " sudo $(basename "$0") status # Status anzeigen" + echo "" +} + +# ─── Kommandozeilen-Argumente ───────────────────────────────────────────────── +case "${1:---help}" in + send) + send_report_email + ;; + test) + send_test_email + ;; + generate) + generate_report "${2:-$REPORT_FORMAT}" + ;; + install) + install_cron + ;; + remove) + remove_cron + ;; + status) + show_cron_status + ;; + --help|-h) + print_help + ;; + *) + echo "Unbekannter Befehl: $1" + print_help + exit 1 + ;; +esac diff --git a/templates/report.html b/templates/report.html new file mode 100644 index 0000000..221c404 --- /dev/null +++ b/templates/report.html @@ -0,0 +1,316 @@ + + + + + + AdGuard Shield – Report + + + +
+ +
+

🛡️ AdGuard Shield

+

Sicherheits-Report

+
{{REPORT_PERIOD}}
+
+ + +
+

📊 Übersicht

+
+
+
{{TOTAL_BANS}}
+
Sperren gesamt
+
+
+
{{TOTAL_UNBANS}}
+
Entsperrungen
+
+
+
{{UNIQUE_IPS}}
+
Eindeutige IPs
+
+
+
{{PERMANENT_BANS}}
+
Permanente Sperren
+
+
+
{{ACTIVE_BANS}}
+
Aktuell aktive Sperren
+
+
+
{{ABUSEIPDB_REPORTS}}
+
AbuseIPDB Reports
+
+
+ + +

⚔️ Angriffsarten

+
+
+
{{RATELIMIT_BANS}}
+
Rate-Limit Sperren
+
+
+
{{SUBDOMAIN_FLOOD_BANS}}
+
Subdomain-Flood Sperren
+
+
+
{{EXTERNAL_BLOCKLIST_BANS}}
+
Externe Blocklist
+
+
+
{{BUSIEST_DAY}}
+
Aktivster Tag
+
+
+ + +

🏴‍☠️ Top 10 – Auffälligste IPs

+ {{TOP10_IPS_TABLE}} + + +

🌐 Top 10 – Meistbetroffene Domains

+ {{TOP10_DOMAINS_TABLE}} + + +

📡 Protokoll-Verteilung

+ {{PROTOCOL_TABLE}} + + +

🕐 Letzte 10 Sperren

+ {{RECENT_BANS_TABLE}} +
+ + + +
+ + diff --git a/templates/report.txt b/templates/report.txt new file mode 100644 index 0000000..8ff5b60 --- /dev/null +++ b/templates/report.txt @@ -0,0 +1,59 @@ +═══════════════════════════════════════════════════════════════ + 🛡️ AdGuard Shield – Sicherheits-Report +═══════════════════════════════════════════════════════════════ + + Zeitraum: {{REPORT_PERIOD}} + Erstellt: {{REPORT_DATE}} + Host: {{HOSTNAME}} + +─────────────────────────────────────────────────────────────── + 📊 ÜBERSICHT +─────────────────────────────────────────────────────────────── + + Sperren gesamt: {{TOTAL_BANS}} + Entsperrungen: {{TOTAL_UNBANS}} + Eindeutige IPs: {{UNIQUE_IPS}} + Permanente Sperren: {{PERMANENT_BANS}} + Aktuell aktive Sperren: {{ACTIVE_BANS}} + AbuseIPDB Reports: {{ABUSEIPDB_REPORTS}} + +─────────────────────────────────────────────────────────────── + ⚔️ ANGRIFFSARTEN +─────────────────────────────────────────────────────────────── + + Rate-Limit Sperren: {{RATELIMIT_BANS}} + Subdomain-Flood Sperren: {{SUBDOMAIN_FLOOD_BANS}} + Externe Blocklist: {{EXTERNAL_BLOCKLIST_BANS}} + Aktivster Tag: {{BUSIEST_DAY}} + +─────────────────────────────────────────────────────────────── + 🏴‍☠️ TOP 10 – AUFFÄLLIGSTE IPs +─────────────────────────────────────────────────────────────── + +{{TOP10_IPS_TEXT}} + +─────────────────────────────────────────────────────────────── + 🌐 TOP 10 – MEISTBETROFFENE DOMAINS +─────────────────────────────────────────────────────────────── + +{{TOP10_DOMAINS_TEXT}} + +─────────────────────────────────────────────────────────────── + 📡 PROTOKOLL-VERTEILUNG +─────────────────────────────────────────────────────────────── + +{{PROTOCOL_TEXT}} + +─────────────────────────────────────────────────────────────── + 🕐 LETZTE 10 SPERREN +─────────────────────────────────────────────────────────────── + +{{RECENT_BANS_TEXT}} + +═══════════════════════════════════════════════════════════════ + Dieser Report wurde automatisch von AdGuard Shield generiert. + AdGuard Shield v{{VERSION}} + + Web: https://www.patrick-asmus.de + Repo: https://git.techniverse.net/scriptos/adguard-shield.git +═══════════════════════════════════════════════════════════════