From e8f61a10148475ede83050b10d9a5e5186af497f Mon Sep 17 00:00:00 2001 From: thomasciesla Date: Tue, 9 Dec 2025 11:45:38 +0100 Subject: [PATCH] README.md aktualisiert --- README.md | 902 +++++++++++++++++------------------------------------- 1 file changed, 289 insertions(+), 613 deletions(-) diff --git a/README.md b/README.md index ab922f3..81e87ad 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,92 @@ -# GeoIP Shop Blocker Manager +# GeoIP Shop Blocker Manager v3.1.0 **Hybrid-System für temporäres GeoIP-Blocking auf Plesk-Servern mit mehreren Shops** -Dieses Tool ermöglicht es, einzelne oder alle Shops auf einem Plesk-Server temporär für alle Zugriffe außerhalb der gewählten Region zu sperren. Es kombiniert PHP-Level-Blocking mit optionaler CrowdSec Firewall-Integration für maximalen Schutz. +Dieses Tool ermöglicht es, einzelne oder alle Shops auf einem Plesk-Server temporär für alle Zugriffe außerhalb einer gewählten Geo-Region zu sperren. Es kombiniert PHP-Level-Blocking mit optionaler CrowdSec Firewall-Integration für maximalen Schutz. ## 🎯 Features -- ✅ **Zwei Geo-Regionen wählbar**: - - 🇩🇪🇦🇹🇨🇭 **DACH**: Deutschland, Österreich, Schweiz (3 Länder) - - 🇪🇺 **Eurozone+GB**: 22 Länder (DE, AT, CH, BE, CY, EE, ES, FI, FR, GB, GR, HR, IE, IT, LT, LU, LV, MT, NL, PT, SI, SK) +- ✅ **Zwei Geo-Regionen**: DACH (3 Länder) oder Eurozone+GB (22 Länder) - ✅ **Präzises Blocking**: PHP prüft gegen vollständige IP-Ranges (keine Fehlblockierungen) - ✅ **Flexibler Modus**: Wahl zwischen "PHP + CrowdSec" oder "Nur PHP" +- ✅ **Cache-Validierung**: Sofortige Prüfung bei Aktivierung +- ✅ **Fail-Open**: Bei Cache-Fehlern wird Traffic durchgelassen (nicht blockiert) +- ✅ **Selbstheilender Cache**: Korrupte Cache-Dateien werden automatisch regeneriert - ✅ **Doppelter Schutz**: PHP-Level + Firewall-Level (CrowdSec) - optional - ✅ **Automatische Synchronisation**: Blockierte IPs werden automatisch an CrowdSec weitergegeben - ✅ **Multi-Shop-Management**: Verwaltung mehrerer Shops auf einem Server - ✅ **Bulk-Operationen**: Alle Shops gleichzeitig aktivieren/deaktivieren - ✅ **Gesamtübersicht**: Logs und Statistiken über alle Shops hinweg (Top 100 IPs) +- ✅ **Bot-Erkennung**: Automatische Identifikation von bekannten Bots/Crawlern +- ✅ **Link11-Erkennung**: Farbige Anzeige ob Shop hinter Link11 CDN ist - ✅ **Auto-Deaktivierung**: Blocking läuft nach 72 Stunden automatisch ab - ✅ **Systemd-Service**: Automatischer Start beim Booten - ✅ **Sauberes Cleanup**: Vollständige Deinstallation bei Deaktivierung - ✅ **Plesk-kompatibel**: Funktioniert mit Plesk-verwalteten Shops - ✅ **CDN-kompatibel**: PHP-only Modus für Link11, Cloudflare & Co. -- ✅ **Link11-Erkennung**: Automatische Anzeige ob Shop hinter Link11 steht -## 🌍 Verfügbare Geo-Regionen +## 🌍 Geo-Regionen -### 🇩🇪🇦🇹🇨🇭 DACH (3 Länder) -| Code | Land | -|------|------| -| DE | Deutschland | -| AT | Österreich | -| CH | Schweiz | +| Region | Icon | Länder | Beschreibung | +|--------|------|--------|--------------| +| **DACH** | 🇩🇪🇦🇹🇨🇭 | 3 | Deutschland, Österreich, Schweiz | +| **Eurozone+GB** | 🇪🇺 | 22 | DE, AT, CH, BE, CY, EE, ES, FI, FR, GB, GR, HR, IE, IT, LT, LU, LV, MT, NL, PT, SI, SK | -### 🇪🇺 Eurozone + GB (22 Länder) -| Code | Land | Code | Land | -|------|------|------|------| -| DE | Deutschland | IT | Italien | -| AT | Österreich | LT | Litauen | -| CH | Schweiz | LU | Luxemburg | -| BE | Belgien | LV | Lettland | -| CY | Zypern | MT | Malta | -| EE | Estland | NL | Niederlande | -| ES | Spanien | PT | Portugal | -| FI | Finnland | SI | Slowenien | -| FR | Frankreich | SK | Slowakei | -| GB | Großbritannien | GR | Griechenland | -| HR | Kroatien | IE | Irland | +### Wann welche Region? + +| Situation | Empfohlene Region | +|-----------|-------------------| +| Nur deutschsprachige Kunden | 🇩🇪🇦🇹🇨🇭 DACH | +| EU-weiter Versand | 🇪🇺 Eurozone+GB | +| Schnellere Performance gewünscht | 🇩🇪🇦🇹🇨🇭 DACH (weniger IP-Ranges) | +| Maximale Abdeckung | 🇪🇺 Eurozone+GB | + +### Performance-Vergleich + +| Region | IP-Ranges | RAM-Verbrauch | Cache-Größe | +|--------|-----------|---------------|-------------| +| 🇩🇪🇦🇹🇨🇭 DACH | ~3.000-4.000 | ~5-10 MB | ~100-200 KB | +| 🇪🇺 Eurozone+GB | ~12.000-15.000 | ~15-25 MB | ~500-900 KB | + +## 🆕 Neu in v3.1.0: Cache-Validierung & Fail-Open + +### Problem gelöst +Korrupte Cache-Dateien führten dazu, dass **alle IPs blockiert** wurden (403 für jeden Besucher). + +### Lösung +1. **Cache-Validierung bei Aktivierung**: Cache wird sofort generiert und auf Mindestanzahl geprüft +2. **Fail-Open im PHP**: Bei Cache-Fehlern wird Traffic **durchgelassen** statt blockiert +3. **Selbstheilung**: Korrupter Cache wird automatisch gelöscht und neu generiert + +``` +DACH: min. 1.000 IP-Ranges erwartet +Eurozone: min. 5.000 IP-Ranges erwartet +``` + +### Wie funktioniert Fail-Open? + +```php +// Im PHP-Script: +if (!is_array($allowed_ranges) || count($allowed_ranges) < $min_ranges) { + // Cache korrupt oder unvollständig → löschen + @unlink($cache_file); + + // Neu laden versuchen... + $allowed_ranges = download_allowed_ranges($allowed_countries); +} + +// Wenn immer noch keine gültigen Ranges → Traffic durchlassen! +if (empty($allowed_ranges)) { + error_log("GeoIP FAIL-OPEN: Could not load valid IP ranges"); + return; // Allow traffic instead of blocking everything +} +``` + +**Vorteile:** +- Kein Total-Lockout bei Cache-Problemen +- Selbstheilend (regeneriert automatisch) +- Sicherer als Fail-Closed +- Validierung bereits bei Aktivierung ## 🏗️ Architektur @@ -53,10 +94,12 @@ Dieses Tool ermöglicht es, einzelne oder alle Shops auf einem Plesk-Server temp #### Komponente 1: PHP-Script - Wird in die `index.php` des Shops integriert -- Lädt IP-Ranges der gewählten Region von ipdeny.com +- Lädt IP-Ranges von ipdeny.com (je nach Region) - Prüft jede Anfrage gegen diese Ranges -- Blockt Nicht-Regions-IPs sofort mit HTTP 403 +- **Validiert Cache** auf Mindestanzahl +- Blockt Nicht-Region-IPs sofort mit HTTP 403 - Schreibt blockierte IPs in Queue-Datei für CrowdSec +- **Fail-Open** bei Cache-Problemen #### Komponente 2: Python Watcher (systemd service) - Läuft permanent im Hintergrund als root @@ -118,14 +161,14 @@ apt-get install crowdsec crowdsec-firewall-bouncer-iptables ```bash # Als root cd /root -wget https://git.jtl-hosting.de/thomasciesla/geoip_shop_manager/raw/branch/main/geoip_shop_manager.py -chmod +x geoip_shop_manager.py +wget https://git.jtl-hosting.de/thomasciesla/geoip_shop_manager/raw/branch/main/geoip_shop_blocker.py +chmod +x geoip_shop_blocker.py ``` ### 2. Script ausführen ```bash -python3 geoip_shop_manager.py +python3 geoip_shop_blocker.py ``` Das war's! Das Script ist vollständig selbstverwaltend. @@ -135,29 +178,29 @@ Das war's! Das Script ist vollständig selbstverwaltend. ### Hauptmenü ``` -══════════════════════════════════════════════════════════════ - GeoIP Shop Blocker Manager - Regionen: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB (22 Länder) - PHP + CrowdSec Watcher (systemd service) -══════════════════════════════════════════════════════════════ - ✅ CrowdSec: Aktiv - ✅ Watcher-Service: Läuft +════════════════════════════════════════════════════════════════ + GeoIP Shop Blocker Manager v3.1.0 + 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB (22 Länder) + 🛡️ Mit Cache-Validierung und Fail-Open +════════════════════════════════════════════════════════════════ + ✅ CrowdSec + ✅ Watcher-Service ──────────────────────────────────────── -[1] GeoIP-Blocking AKTIVIEREN (einzeln) -[2] GeoIP-Blocking DEAKTIVIEREN (einzeln) +[1] Aktivieren (einzeln) +[2] Deaktivieren (einzeln) [3] Logs anzeigen -[4] Status anzeigen +[4] Status ──────────────────────────────────────── -[5] 🚀 ALLE Shops aktivieren -[6] 🛑 ALLE Shops deaktivieren +[5] 🚀 ALLE aktivieren +[6] 🛑 ALLE deaktivieren ──────────────────────────────────────── [0] Beenden ``` ### Geo-Region wählen -Bei jeder Aktivierung (einzeln oder alle) wird zuerst nach der Region gefragt: +Bei jeder Aktivierung wird zuerst nach der Region gefragt: ``` 🌍 Wähle die Geo-Region: @@ -169,7 +212,7 @@ Region wählen [1/2]: ### Blocking-Modus wählen -Nach der Region wird der Modus abgefragt: +Danach wird nach dem Modus gefragt: ``` 🔧 Wähle den Blocking-Modus: @@ -179,22 +222,21 @@ Nach der Region wird der Modus abgefragt: Modus wählen [1/2]: ``` -**Wann welche Kombination wählen?** +**Wann welchen Modus wählen?** -| Situation | Region | Modus | -|-----------|--------|-------| -| DE/AT/CH Shop, Server direkt | DACH | PHP + CrowdSec 🛡️ | -| DE/AT/CH Shop, hinter CDN | DACH | Nur PHP 📝 | -| EU-weiter Shop, Server direkt | Eurozone+GB | PHP + CrowdSec 🛡️ | -| EU-weiter Shop, hinter CDN | Eurozone+GB | Nur PHP 📝 | -| Maximaler Schutz (nur DACH) | DACH | PHP + CrowdSec 🛡️ | -| Weniger restriktiv (EU-weit) | Eurozone+GB | Nur PHP 📝 | +| Situation | Empfohlener Modus | +|-----------|-------------------| +| Server direkt im Internet | PHP + CrowdSec 🛡️ | +| Server hinter CDN (Link11, Cloudflare) | Nur PHP 📝 | +| CrowdSec nicht installiert | Nur PHP 📝 | +| Minimaler Overhead gewünscht | Nur PHP 📝 | +| Maximaler Schutz (alle Ports) | PHP + CrowdSec 🛡️ | ### Blocking aktivieren (einzelner Shop) -1. Script starten: `python3 geoip_shop_manager.py` -2. Option `[1] GeoIP-Blocking AKTIVIEREN (einzeln)` wählen -3. Shop aus der Liste auswählen +1. Script starten: `python3 geoip_shop_blocker.py` +2. Option `[1] Aktivieren (einzeln)` wählen +3. Shop aus der Liste auswählen (farbig: 🟢 Link11, 🔴 Direkt) 4. **Geo-Region wählen** (DACH oder Eurozone+GB) 5. **Modus wählen** (PHP+CrowdSec oder Nur PHP) 6. Bestätigen mit `ja` @@ -206,248 +248,131 @@ Modus wählen [1/2]: Modus: PHP + CrowdSec ════════════════════════════════════════════════════════════════ -[1/3] Installiere CrowdSec-Watcher-Service... - ✅ Watcher-Script erstellt: /usr/local/bin/geoip_crowdsec_watcher.py - ✅ Systemd-Service erstellt: /etc/systemd/system/geoip-crowdsec-watcher.service - ✅ Service gestartet und läuft +[1/4] Installiere CrowdSec-Watcher-Service... + ✅ Service gestartet -[2/3] Aktiviere PHP-Blocking... - 📋 Backup erstellen... - ✏️ index.php modifiziert - 📝 geoip_blocking.php erstellt +[2/4] Aktiviere PHP-Blocking... + ✅ PHP-Blocking aktiviert -[3/3] Registriere Shop... +[3/4] Generiere IP-Range-Cache (22 Länder)... + ✅ Cache generiert: 12,345 IP-Ranges + +[4/4] Registriere Shop... ✅ Shop registriert ════════════════════════════════════════════════════════════════ -✅ 🇪🇺 Eurozone + GB GeoIP-Blocking aktiviert für: shop.example.com - Erlaubte Länder: 22 Länder: DE, AT, CH, BE, CY, EE, ES, FI, FR, GB, GR, HR, IE, IT, LT, LU, LV, MT, NL, PT, SI, SK - Modus: PHP + CrowdSec 🛡️ - Gültig bis: 2025-12-12 14:30:00 CET - PHP-Log: /var/www/vhosts/shop.example.com/httpdocs/geoip_blocked.log - CrowdSec-Queue: /var/www/vhosts/shop.example.com/httpdocs/geoip_crowdsec_queue.log - - 🔄 Der Watcher-Service synchronisiert blockierte IPs zu CrowdSec +✅ 🇪🇺 Eurozone + GB GeoIP-Blocking aktiviert + Shop: shop.example.com + IP-Ranges: 12,345 + Gültig bis: 2025-12-12 10:30:00 CET + 🛡️ Fail-Open: Bei Cache-Fehlern wird Traffic durchgelassen ════════════════════════════════════════════════════════════════ ``` ### Blocking für ALLE Shops aktivieren -1. Script starten: `python3 geoip_shop_manager.py` -2. Option `[5] 🚀 ALLE Shops aktivieren` wählen +1. Script starten: `python3 geoip_shop_blocker.py` +2. Option `[5] 🚀 ALLE aktivieren` wählen 3. Liste der zu aktivierenden Shops wird angezeigt 4. **Geo-Region wählen** (gilt für alle Shops) 5. **Modus wählen** (gilt für alle Shops) 6. Bestätigen mit `ja` -**Beispielausgabe:** -``` -══════════════════════════════════════════════════════════════ - GeoIP-Blocking für ALLE Shops aktivieren -══════════════════════════════════════════════════════════════ +### Status prüfen -📋 Folgende 5 Shop(s) werden aktiviert: - Grün = hinter Link11 | Rot = Direkt - - • shop1.example.com [Link11] - • shop2.example.com [Direkt] - • shop3.example.com [Link11] - ... - -🌍 Wähle die Geo-Region: - [1] 🇩🇪🇦🇹🇨🇭 DACH - Deutschland, Österreich, Schweiz - [2] 🇪🇺 Eurozone+GB - 22 Länder - -Region wählen [1/2]: 2 - -🔧 Wähle den Blocking-Modus: - [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet) - [2] Nur PHP (keine CrowdSec-Synchronisation) - -Modus wählen [1/2]: 2 - -⚠️ Dies aktiviert den Schutz für alle oben genannten Shops! - Region: 🇪🇺 Eurozone + GB - Modus: Nur PHP 📝 - -Fortfahren? (ja/nein): ja - -══════════════════════════════════════════════════════════════ - Starte Aktivierung (🇪🇺 Eurozone + GB, Nur PHP 📝)... -══════════════════════════════════════════════════════════════ - -[1/5] Aktiviere: shop1.example.com - ✅ Aktiviert (bis 2025-12-12 14:30) -... - -══════════════════════════════════════════════════════════════ - ZUSAMMENFASSUNG -══════════════════════════════════════════════════════════════ - - ✅ Erfolgreich aktiviert: 5 - ❌ Fehlgeschlagen: 0 - - 🇪🇺 Region: Eurozone + GB - 🔧 Modus: Nur PHP 📝 - ⏰ Gültig für 72 Stunden -══════════════════════════════════════════════════════════════ -``` - -### Blocking deaktivieren (einzelner Shop) - -1. Script starten: `python3 geoip_shop_manager.py` -2. Option `[2] GeoIP-Blocking DEAKTIVIEREN (einzeln)` wählen -3. Shop aus der Liste auswählen (zeigt Region und Modus an) -4. Bestätigen mit `ja` - -**Shop-Liste zeigt alle relevanten Infos:** -``` -📋 Aktive Shops: - Grün = hinter Link11 | Rot = Direkt - [1] shop1.example.com [Link11] 🇪🇺 🛡️ - [2] shop2.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 📝 - [3] shop3.example.com [Link11] 🇪🇺 📝 -``` - -**Was passiert:** -- Original `index.php` wird wiederhergestellt -- Alle PHP-Dateien werden gelöscht -- Bei PHP+CrowdSec Modus: Alle CrowdSec-Decisions werden entfernt -- Shop wird deregistriert -- Bei LETZTEM Shop mit CrowdSec: Systemd-Service wird deinstalliert - -### Blocking für ALLE Shops deaktivieren - -1. Script starten: `python3 geoip_shop_manager.py` -2. Option `[6] 🛑 ALLE Shops deaktivieren` wählen -3. Liste der aktiven Shops wird angezeigt (mit Region-Icons) -4. Bestätigen mit `ja` - -### Logs anzeigen - -1. Script starten: `python3 geoip_shop_manager.py` -2. Option `[3] Logs anzeigen` wählen -3. Auswahl treffen: +Option `[4] Status` zeigt: ``` -📋 Logs anzeigen für: - Grün = hinter Link11 | Rot = Direkt - [0] 📊 ALLE Shops (Zusammenfassung) - [1] shop1.example.com [Link11] 🇪🇺 🛡️ - [2] shop2.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 📝 - ... +📊 2/5 Shops aktiv + shop1.example.com [Link11] 🇩🇪🇦🇹🇨🇭 🛡️ + 1234 blocks, 2h 30m, Cache: ✅3,456 + shop2.example.com [Direkt] 🇪🇺 📝 + 567 blocks, 1h 15m, Cache: ✅12,345 ``` -Die Icons zeigen: +**Legende:** +- 🟢 `[Link11]` = Shop ist hinter Link11 CDN +- 🔴 `[Direkt]` = Shop ist direkt erreichbar - 🇩🇪🇦🇹🇨🇭 = DACH Region - 🇪🇺 = Eurozone+GB Region - 🛡️ = PHP + CrowdSec Modus - 📝 = Nur PHP Modus +- ✅ = Cache valide mit Anzahl Ranges +- ⚠️ = Cache-Problem -#### Option [0]: Gesamtübersicht aller Shops +### Logs anzeigen -Zeigt eine aggregierte Statistik über alle aktiven Shops: +Option `[3] Logs anzeigen` bietet: ``` -════════════════════════════════════════════════════════════════════════ - 📊 GESAMTÜBERSICHT ALLER SHOPS -════════════════════════════════════════════════════════════════════════ - Grün = hinter Link11 | Rot = Direkt - -📝 PHP-Blocks gesamt: 1.247 (⌀ 2.3 req/min, Laufzeit: 9h 12m) - ├─ shop1.example.com 🇪🇺: 523 (1.2 req/min, seit 9h 12m) ██████████ - │ └─➤ Top: 185.220.101.34 (GPTBot) - 127x, 0.2 req/min - ├─ shop2.example.com 🇩🇪🇦🇹🇨🇭: 412 (0.8 req/min, seit 8h 30m) ████████ - │ └─➤ Top: 45.95.169.22 (SemrushBot) - 89x, 0.2 req/min - └─ shop3.example.com 🇪🇺: 312 (0.6 req/min, seit 8h 45m) ██████ - └─➤ Top: 194.26.192.64 (Unbekannt) - 67x, 0.1 req/min - -🛡️ CrowdSec-Bans gesamt: 892 - ├─ shop1.example.com 🇪🇺: 401 ████████████████ - └─ shop2.example.com 🇩🇪🇦🇹🇨🇭: 298 ███████████ - -🔥 Top 100 blockierte IPs (alle Shops): - 185.220.101.34 (GPTBot): 127 (0.2 req/min) → shop1.example.com [127x] █████████████████████████ - 45.95.169.22 (SemrushBot): 89 (0.2 req/min) → shop2.example.com [89x] █████████████████ - 194.26.192.64 (Unbekannt): 67 (0.1 req/min) → shop3.example.com [45x] █████████████ - ... - -════════════════════════════════════════════════════════════════════════ +📋 Logs für: + [0] 📊 ALLE (Zusammenfassung) + [1] shop1.example.com [Link11] 🇩🇪🇦🇹🇨🇭 🛡️ + [2] shop2.example.com [Direkt] 🇪🇺 📝 ``` -**Enthält:** -- PHP-Blocks pro Shop mit Geo-Region-Icon, req/min und Top-IP -- CrowdSec-Bans pro Shop (nur für PHP+CrowdSec Shops) -- Top 100 der am häufigsten blockierten IPs über alle Shops hinweg -- Bot-Erkennung (GPTBot, SemrushBot, Googlebot, etc.) - -#### Option [1-n]: Einzelner Shop - -Zeigt detaillierte Logs für einen spezifischen Shop: +#### Gesamtübersicht (Option 0) ``` -════════════════════════════════════════════════════════════════════════ -📊 Logs für shop1.example.com - 🇪🇺 Eurozone + GB | PHP + CrowdSec 🛡️ -════════════════════════════════════════════════════════════════════════ +════════════════════════════════════════════════════════════════ + 📊 GESAMTÜBERSICHT +════════════════════════════════════════════════════════════════ -⏱️ Aktiviert: 2025-12-09 05:18:00 -⏱️ Laufzeit: 9h 12m -📈 Blocks: 523 (1.2 req/min) + shop1.example.com 🇩🇪🇦🇹🇨🇭: 1234 (5.2 req/min) + shop2.example.com 🇪🇺: 567 (2.1 req/min) -📝 Letzte 50 PHP-Blocks: -====================================================================== -[2025-12-09 14:24:57] IP: 202.8.43.232 | UA: Mozilla/5.0 ... | URI: /produkt-123 +📊 Gesamt: 1801 Blocks + +🔥 Top 20 IPs: + 185.220.101.34 (Bytespider): 127x + 45.95.169.22 (SemrushBot): 89x + 194.26.192.64 (Unbekannt): 67x +``` + +#### Einzelner Shop + +Zeigt detaillierte Logs mit Bot-Erkennung: + +``` +════════════════════════════════════════════════════════════════ +📊 shop.example.com | 🇪🇺 Eurozone + GB +════════════════════════════════════════════════════════════════ +⏱️ Laufzeit: 2h 30m +📈 Blocks: 1234 (8.2 req/min) +✅ Cache: 12,345 Ranges + +📝 Letzte 30 Blocks: +[2025-12-09 10:24:57] IP: 202.8.43.232 | UA: Bytespider | URI: /produkt-123 ... -====================================================================== -Gesamt: 523 -🔥 Top 20 blockierte IPs: - 185.220.101.34 (GPTBot): 127 (0.2 req/min) █████████████████████████ - 45.95.169.22 (SemrushBot): 89 (0.2 req/min) █████████████████ - ... - -🛡️ CrowdSec Decisions: -====================================================================== -Aktive Bans: 401 - -Letzte 20 Bans: - 🚫 202.8.43.232 (bis 2025-12-12 14:24:57) - 🚫 45.95.169.22 (bis 2025-12-12 13:30:12) - ... -====================================================================== -``` - -Bei PHP-only Shops wird stattdessen angezeigt: -``` -📝 CrowdSec-Synchronisation ist für diesen Shop deaktiviert (PHP-only Modus) -``` - -### Status prüfen - -Option `[4] Status anzeigen` zeigt: -- Anzahl verfügbarer Shops -- Anzahl aktiver Blockings -- Liste aller Shops mit aktivem Blocking, Region und Modus - -``` -📊 Status: - Shops gesamt: 15 - Aktive GeoIP-Blockings: 5 - Grün = hinter Link11 | Rot = Direkt - ✓ shop1.example.com [Link11] 🇪🇺 [PHP+CS] 🛡️ - 523 blocks (1.2 req/min, 9h 12m) - ✓ shop2.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 [PHP] 📝 - 412 blocks (0.8 req/min, 8h 30m) - ✓ shop3.example.com [Link11] 🇪🇺 [PHP] 📝 - 312 blocks (0.6 req/min, 8h 45m) - ✓ shop4.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 [PHP+CS] 🛡️ - 201 blocks (0.4 req/min, 8h 15m) - ✓ shop5.example.com [Link11] 🇪🇺 [PHP] 📝 - 156 blocks (0.3 req/min, 8h 0m) +🔥 Top 10 IPs: + 202.8.43.232 (Bytespider): 127x + 45.95.169.22 (SemrushBot): 89x ``` ## 🔧 Erweiterte Verwendung +### Cache manuell regenerieren + +```bash +# Cache für einen Shop löschen (wird automatisch neu generiert) +rm /var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache +``` + +### Cache-Status prüfen + +```bash +# Cache-Größe und Alter prüfen +ls -la /var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache + +# Anzahl der Ranges im Cache +php -r 'echo count(unserialize(file_get_contents("/var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache")));' +``` + ### Manuell CrowdSec Decisions prüfen ```bash -# Alle Decisions anzeigen (mit vollständiger Liste) +# Alle Decisions anzeigen cscli decisions list --limit 0 # Nur GeoIP-Blocks anzeigen @@ -457,23 +382,14 @@ cscli decisions list --limit 0 | grep "GeoIP" cscli decisions list --limit 0 | grep "shop.example.com" ``` -### Alle GeoIP-Decisions löschen (Einzeiler) +### Alle GeoIP-Decisions löschen ```bash -while cscli decisions list -o raw --limit 0 | grep -q "GeoIP"; do cscli decisions list -o raw --limit 0 | grep "GeoIP" | cut -d',' -f3 | cut -d':' -f2 | while read ip; do echo "🗑️ Lösche: $ip"; cscli decisions delete --ip "$ip" 2>/dev/null; done; done && echo "✅ Alle GeoIP-Decisions gelöscht" -``` - -### Firewall-Statistiken prüfen - -```bash -# Geblockte Pakete in iptables -iptables -L -n -v | grep crowdsec - -# IPs im CrowdSec ipset -ipset list crowdsec-blacklists-5 | head -50 - -# Prüfe ob eine bestimmte IP gebannt ist -ipset test crowdsec-blacklists-5 1.2.3.4 +while cscli decisions list -o raw --limit 0 | grep -q "GeoIP"; do \ + cscli decisions list -o raw --limit 0 | grep "GeoIP" | \ + cut -d',' -f3 | cut -d':' -f2 | \ + while read ip; do cscli decisions delete --ip "$ip" 2>/dev/null; done; \ +done && echo "✅ Alle GeoIP-Decisions gelöscht" ``` ### Systemd-Service verwalten @@ -489,82 +405,25 @@ journalctl -u geoip-crowdsec-watcher.service -f systemctl restart geoip-crowdsec-watcher.service ``` -### Manuelle IP-Tests - -```bash -# Eigene IP für 3 Minuten bannen (Test) -cscli decisions add --ip DEINE_IP --duration 3m --type ban --reason "Test" - -# Prüfen ob Ban aktiv ist -ipset test crowdsec-blacklists-5 DEINE_IP - -# Ban manuell entfernen -cscli decisions delete --ip DEINE_IP -``` - ## 📁 Dateistruktur ### Pro Shop (in `/var/www/vhosts/SHOP/httpdocs/`) -- `index.php.geoip_backup` - Backup der Original index.php -- `geoip_blocking.php` - PHP-Blocking-Script -- `geoip_ip_ranges.cache` - Gecachte IP-Ranges der gewählten Region (erneuert alle 24h) -- `geoip_blocked.log` - Log der PHP-Level Blocks -- `geoip_crowdsec_queue.log` - Queue für CrowdSec-Synchronisation (nur PHP+CrowdSec Modus) +| Datei | Beschreibung | +|-------|--------------| +| `index.php.geoip_backup` | Backup der Original index.php | +| `geoip_blocking.php` | PHP-Blocking-Script | +| `geoip_ip_ranges.cache` | Gecachte IP-Ranges (erneuert alle 24h) | +| `geoip_blocked.log` | Log der PHP-Level Blocks | +| `geoip_crowdsec_queue.log` | Queue für CrowdSec (nur PHP+CrowdSec) | ### System-weit -- `/usr/local/bin/geoip_crowdsec_watcher.py` - Watcher-Service Script -- `/etc/systemd/system/geoip-crowdsec-watcher.service` - Systemd Service -- `/var/lib/crowdsec/geoip_active_shops.json` - Tracking aktiver Shops (inkl. Modus und Region) - -## ⚙️ Konfiguration - -### Blocking-Dauer ändern - -Standardmäßig 72 Stunden. Zum Ändern editiere das Python-Script: - -```python -# Zeile ~400 und ~750 -expiry = datetime.now() + timedelta(hours=72) # Hier ändern -``` - -### Watcher-Intervall ändern - -Standard: 5 Sekunden. Zum Ändern im Watcher-Script: - -```python -CHECK_INTERVAL = 5 # In Sekunden -``` - -### IP-Range-Cache-Dauer ändern - -Standard: 24 Stunden. Im PHP-Script: - -```php -$cache_duration = 86400; // In Sekunden -``` - -### Weitere Länder hinzufügen - -Um weitere Länder zu einer Region hinzuzufügen, editiere im Python-Script das `GEO_REGIONS` Dictionary: - -```python -GEO_REGIONS = { - "dach": { - "name": "DACH", - "countries": ["de", "at", "ch"], # Hier Länder hinzufügen - ... - }, - "eurozone": { - "name": "Eurozone + GB", - "countries": ["de", "at", "ch", "be", ...], # Hier Länder hinzufügen - ... - } -} -``` - -Die verfügbaren Ländercodes findest du unter: https://www.ipdeny.com/ipblocks/data/aggregated/ +| Datei | Beschreibung | +|-------|--------------| +| `/usr/local/bin/geoip_crowdsec_watcher.py` | Watcher-Service Script | +| `/etc/systemd/system/geoip-crowdsec-watcher.service` | Systemd Service | +| `/var/lib/crowdsec/geoip_active_shops.json` | Tracking aktiver Shops | ## 🛡️ Sicherheit @@ -572,76 +431,63 @@ Die verfügbaren Ländercodes findest du unter: https://www.ipdeny.com/ipblocks/ - ✅ Alle IPs außerhalb der gewählten Region - ✅ Auf PHP-Ebene: Sofortiger 403 Response -- ✅ Auf Firewall-Ebene (nur PHP+CrowdSec): Alle Ports (HTTP, HTTPS, SSH, FTP, etc.) +- ✅ Auf Firewall-Ebene (nur PHP+CrowdSec): Alle Ports ### Was wird NICHT geblockt? -- ✅ Alle IPs aus der gewählten Region (basierend auf RIPE/ipdeny.com Daten) +- ✅ Alle IPs aus der gewählten Region - ✅ Private IPs (192.168.x.x, 10.x.x.x, etc.) - ✅ Localhost (127.0.0.1) +- ✅ Bei Cache-Fehlern: Alle IPs (Fail-Open) -### Fehlblockierungen vermeiden +### Fail-Open vs. Fail-Closed -Das System nutzt die **offiziellen IP-Zuweisungen** von ipdeny.com: -- Basiert auf RIPE-Daten -- Täglich aktualisiert -- Umfasst alle Provider der Region -- Präzise CIDR-Prüfung +| Strategie | Verhalten bei Cache-Fehler | Risiko | +|-----------|---------------------------|--------| +| **Fail-Open** ✅ | Traffic durchlassen | Kurzzeitig kein Schutz | +| Fail-Closed ❌ | Alles blockieren | Totaler Lockout möglich | -**Risiko für Fehlblockierungen: Minimal** - -## 🌐 CDN/Reverse-Proxy Hinweise - -### Problem bei CDN-Nutzung (Link11, Cloudflare, etc.) - -Wenn dein Server hinter einem CDN oder Reverse-Proxy steht: - -``` -Client (202.8.43.232) → CDN (85.131.143.x) → Dein Server - ↓ - iptables sieht nur CDN-IP! -``` - -**Folge:** CrowdSec Firewall-Bouncer kann die echte Client-IP nicht blocken, da er nur die CDN-IP sieht. - -### Lösung: PHP-only Modus - -Das PHP-Script liest die echte IP aus dem `X-Forwarded-For` Header: -- Funktioniert auch hinter CDN/Proxy -- Blockt zuverlässig auf Anwendungsebene -- Kein unnötiger CrowdSec-Overhead - -**Empfehlung für CDN-Nutzer:** Wähle bei der Aktivierung den Modus **[2] Nur PHP**. - -### Link11-Erkennung - -Das Script erkennt automatisch, ob ein Shop hinter Link11 steht: -- **Grün** = Shop löst auf Link11-IP auf (128.65.223.106) -- **Rot** = Shop ist direkt erreichbar - -``` -📋 Verfügbare Shops: - Grün = hinter Link11 | Rot = Direkt - [1] shop1.example.com [Link11] - [2] shop2.example.com [Direkt] -``` +**Wir nutzen Fail-Open** - lieber kurzzeitig keinen Schutz als alle Kunden aussperren! ## 🐛 Troubleshooting -### Shop zeigt 500 Error +### Shop zeigt 403 für ALLE Besucher -**Ursache**: PHP-Syntax-Fehler oder falsche Einbindung +**Mögliche Ursache**: Korrupter Cache ```bash -# Prüfe PHP-Fehler-Log +# Cache prüfen +php -r 'var_dump(unserialize(file_get_contents("/var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache")));' + +# Cache löschen (regeneriert automatisch) +rm /var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache + +# Oder: Blocking deaktivieren +python3 geoip_shop_blocker.py # Option 2 +``` + +### Cache-Generierung schlägt fehl + +**Mögliche Ursachen:** +1. Keine Internet-Verbindung zu ipdeny.com +2. Timeout bei vielen Ländern (Eurozone) +3. ipdeny.com temporär nicht erreichbar + +```bash +# Manuell testen +curl -v https://www.ipdeny.com/ipblocks/data/aggregated/de-aggregated.zone | head -20 +``` + +### Shop zeigt 500 Error + +```bash +# PHP-Fehler-Log prüfen tail -50 /var/www/vhosts/SHOP/logs/error_log -# Stelle Original-Index wieder her +# Original wiederherstellen cd /var/www/vhosts/SHOP/httpdocs mv index.php.geoip_backup index.php - -# Deaktiviere via Script -python3 geoip_shop_manager.py # Option 2 +rm geoip_blocking.php geoip_ip_ranges.cache ``` ### Watcher-Service läuft nicht @@ -657,168 +503,73 @@ journalctl -u geoip-crowdsec-watcher.service -n 100 systemctl restart geoip-crowdsec-watcher.service ``` -### CrowdSec Decisions werden nicht erstellt +## 🌐 CDN/Reverse-Proxy Hinweise -```bash -# Prüfe ob Queue-Datei beschrieben wird -tail -f /var/www/vhosts/SHOP/httpdocs/geoip_crowdsec_queue.log +### Problem bei CDN-Nutzung -# Prüfe Watcher-Logs -journalctl -u geoip-crowdsec-watcher.service -f - -# Prüfe CrowdSec API -cscli decisions add --ip 1.2.3.4 --duration 1m --type ban --reason "Test" -cscli decisions list | grep "1.2.3.4" -cscli decisions delete --ip 1.2.3.4 +``` +Client (202.8.43.232) → CDN (85.131.143.x) → Dein Server + ↓ + iptables sieht nur CDN-IP! ``` -### Firewall blockt nicht (trotz CrowdSec-Ban) +### Lösung: PHP-only Modus -**Mögliche Ursachen:** +Das PHP-Script liest die echte IP - funktioniert auch hinter CDN/Proxy. -1. **CDN/Reverse-Proxy aktiv** → Wechsle zu PHP-only Modus -2. **Bouncer läuft nicht:** - ```bash - systemctl status crowdsec-firewall-bouncer - ``` -3. **iptables-Regeln fehlen:** - ```bash - iptables -L -n -v | grep crowdsec - ``` +**Empfehlung für CDN-Nutzer:** Wähle **[2] Nur PHP** bei der Aktivierung. -### IPs aus erlaubter Region werden geblockt +### Link11 Erkennung -**Sehr unwahrscheinlich!** Aber falls doch: - -```bash -# Prüfe welche IP-Ranges als erlaubt erkannt werden -cat /var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache - -# Lösche Cache (wird neu geladen) -rm /var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache -``` - -### Migration von der alten DACH-Only Version - -Falls du von der alten Version (nur DACH) auf die neue Version mit Regionsauswahl wechselst: - -```bash -# 1. Alle aktiven Shops deaktivieren (alte Version) -python3 geoip_shop_manager_old.py # Option 2 für jeden Shop - -# 2. Alte Cache-Dateien löschen -rm /var/www/vhosts/*/httpdocs/dach_ip_ranges.cache - -# 3. Neue Version verwenden -python3 geoip_shop_manager.py # Shops wieder aktivieren mit gewünschter Region -``` +Das Script erkennt automatisch ob ein Shop hinter Link11 ist: +- 🟢 Grün = hinter Link11 (IP 128.65.223.106) +- 🔴 Rot = Direkt erreichbar ## 📊 Performance ### PHP-Level Blocking -- **Overhead pro Request**: ~2-8ms (bei gecachten IP-Ranges) -- **Erster Request DACH**: ~400-800ms (Download für 3 Länder) -- **Erster Request Eurozone+GB**: ~1-2s (Download für 22 Länder) -- **Cache-Dauer**: 24 Stunden -- **RAM-Verbrauch DACH**: ~5-10 MB pro Shop -- **RAM-Verbrauch Eurozone+GB**: ~15-25 MB pro Shop - -### CrowdSec Firewall Blocking (nur PHP+CrowdSec Modus) - -- **Overhead**: 0ms (blockt vor PHP) -- **RAM**: ~20-50 MB (Watcher-Service) -- **Geblockte Pakete**: Werden gar nicht erst an Apache weitergeleitet +| Region | Overhead pro Request | Erster Request | Cache-Dauer | +|--------|---------------------|----------------|-------------| +| DACH | ~2-5ms | ~200-400ms | 24h | +| Eurozone+GB | ~5-10ms | ~800-1200ms | 24h | ### Empfohlene Limits -- **Kleine Server** (2GB RAM): Bis zu 10 Shops gleichzeitig -- **Mittlere Server** (4-8GB RAM): Bis zu 50 Shops -- **Große Server** (16GB+ RAM): Unbegrenzt +| Server | RAM | Max. Shops | +|--------|-----|------------| +| Klein | 2 GB | 10 | +| Mittel | 4-8 GB | 50 | +| Groß | 16+ GB | Unbegrenzt | -## 🔄 Updates +## 📝 Changelog -### Script aktualisieren +### v3.1.0 (Dezember 2025) +- ✅ **Cache-Validierung** bei Aktivierung +- ✅ **Fail-Open** bei Cache-Fehlern +- ✅ **Selbstheilender Cache** (automatische Regeneration) +- ✅ Mindest-Range-Prüfung pro Region (DACH: 1000, Eurozone: 5000) -```bash -cd /root -wget -O geoip_shop_manager.py https://raw.githubusercontent.com/DEIN-REPO/geoip-shop-blocker/main/geoip_shop_manager.py -chmod +x geoip_shop_manager.py -``` +### v3.0.0 +- ✅ **Eurozone+GB Region** (22 Länder) +- ✅ Region-Icons in Status/Logs +- ✅ Dynamische PHP-Länder-Arrays +- ✅ Bot-Erkennung in Logs +- ✅ Link11-Erkennung (farbige Anzeige) +- ✅ req/min Statistiken -**WICHTIG**: Bereits aktive Shops bleiben unberührt. Der Watcher-Service muss manuell aktualisiert werden. +### v2.2.0 +- ✅ Modus-Auswahl (PHP+CrowdSec oder Nur PHP) +- ✅ Top 100 blockierte IPs in Gesamtübersicht -### IP-Ranges aktualisieren +### v2.1.0 +- ✅ Bulk-Operationen (alle aktivieren/deaktivieren) +- ✅ Gesamtübersicht in Logs -```bash -# Cache löschen (wird automatisch neu geladen) -rm /var/www/vhosts/*/httpdocs/geoip_ip_ranges.cache -``` - -Die Ranges werden automatisch alle 24h aktualisiert. - -## 📝 Logs und Monitoring - -### PHP-Level Logs - -```bash -# Blockierte IPs für einen Shop -tail -f /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log - -# Statistik -wc -l /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log -``` - -### CrowdSec Logs - -```bash -# Watcher-Service Logs (Echtzeit) -journalctl -u geoip-crowdsec-watcher.service -f - -# CrowdSec-Agent Logs -tail -f /var/log/crowdsec.log - -# Firewall-Bouncer Logs -journalctl -u crowdsec-firewall-bouncer.service -f -``` - -### Statistiken - -```bash -# Geblockte Pakete zählen -iptables -L -n -v | grep crowdsec-blacklists-5 - -# Anzahl aktiver Bans -cscli decisions list --limit 0 | grep "GeoIP" | wc -l - -# Top 10 blockierte IPs (PHP-Level) -cat /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log | \ - grep -oP 'IP: \K[0-9.]+' | sort | uniq -c | sort -rn | head -10 -``` - -## 🔐 Best Practices - -### Vor Aktivierung - -1. ✅ Backup erstellen (macht das Script automatisch) -2. ✅ Sicherstellen, dass Admin-Zugriff aus erlaubter Region kommt -3. ✅ **Region wählen** (DACH für DE/AT/CH Shops, Eurozone+GB für EU-weite Shops) -4. ✅ **Modus wählen** (PHP+CrowdSec für direkte Server, PHP-only für CDN) -5. ✅ Test mit kurzer Dauer (kann im Script angepasst werden) -6. ✅ Monitoring einrichten - -### Während aktivem Blocking - -1. ✅ Logs regelmäßig prüfen (Gesamtübersicht nutzen!) -2. ✅ Auf Fehlblockierungen achten (sehr selten) -3. ✅ CrowdSec-Statistiken beobachten (nur bei PHP+CrowdSec) -4. ✅ Server-Performance monitoren - -### Nach Deaktivierung - -1. ✅ Prüfen ob alle Decisions entfernt wurden (nur bei PHP+CrowdSec) -2. ✅ Backup-Dateien können gelöscht werden (optional) -3. ✅ Logs archivieren (falls benötigt) +### v2.0.0 +- ✅ DACH-Support (DE, AT, CH) +- ✅ CrowdSec-Integration +- ✅ Systemd-Service ## ⚠️ Wichtige Hinweise @@ -828,100 +579,25 @@ cat /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log | \ - **Geoblocking**: Kann gegen EU-Verordnungen verstoßen bei B2C-Geschäften - **Haftung**: Nur für technische Notfälle/DDoS-Abwehr empfohlen -### Technisches - -- **API-Calls**: Bei vielen aktiven Shops könnten viele IPs in CrowdSec landen -- **CrowdSec-Limits**: Kostenloser Tier hat API-Limits -- **Netzwerk**: Kein Blocking möglich, wenn Server selbst unter DDoS steht -- **CDN**: Bei CDN-Nutzung ist PHP-only Modus empfohlen - ### Empfehlungen - ✅ Nur temporär nutzen (Notfälle, Angriffe) - ✅ Nicht als permanente Lösung -- ✅ Kombinieren mit anderen Security-Maßnahmen -- ✅ Regelmäßig Logs prüfen (Gesamtübersicht für schnellen Überblick) - ✅ Bei CDN: PHP-only Modus verwenden -- ✅ Region passend zum Shop wählen - -## 🤝 Contributing - -Contributions sind willkommen! Bitte: - -1. Fork das Repository -2. Erstelle einen Feature-Branch -3. Committe deine Änderungen -4. Push zum Branch -5. Erstelle einen Pull Request +- ✅ Regelmäßig Status/Cache prüfen ## 📄 Lizenz -MIT License - siehe LICENSE Datei +MIT License ## 🙏 Credits - **IP-Ranges**: [ipdeny.com](https://www.ipdeny.com/) (RIPE-basiert) - **CrowdSec**: [crowdsec.net](https://www.crowdsec.net/) -- **Entwickelt für**: Plesk-basierte Multi-Shop-Server - -## 📞 Support - -Bei Problemen: - -1. Prüfe die Troubleshooting-Sektion -2. Prüfe die Logs (Gesamtübersicht oder einzeln) -3. Erstelle ein GitHub Issue mit: - - Fehlerbeschreibung - - Relevante Logs - - System-Infos (OS, PHP-Version, CrowdSec-Version) - - **Gewählte Region** (DACH oder Eurozone+GB) - - **Verwendeter Modus** (PHP+CrowdSec oder PHP-only) - -## 📚 Weitere Dokumentation - -- [CrowdSec Dokumentation](https://docs.crowdsec.net/) -- [Plesk Dokumentation](https://docs.plesk.com/) -- [iptables Tutorial](https://www.netfilter.org/documentation/) -- [ipdeny.com Ländercodes](https://www.ipdeny.com/ipblocks/data/aggregated/) --- -**Version**: 3.0.0 -**Letztes Update**: Dezember 2025 +**Version**: 3.1.0 **Status**: Production Ready ✅ -**Verfügbare Regionen**: 🇩🇪🇦🇹🇨🇭 DACH (3 Länder) | 🇪🇺 Eurozone+GB (22 Länder) - -### Changelog - -#### v3.0.0 -- **NEU**: Geo-Region-Auswahl bei Aktivierung (DACH oder Eurozone+GB) -- **NEU**: Eurozone+GB Region mit 22 Ländern (DE, AT, CH, BE, CY, EE, ES, FI, FR, GB, GR, HR, IE, IT, LT, LU, LV, MT, NL, PT, SI, SK) -- **NEU**: Geo-Region-Icon in Status, Logs und allen Menüs (🇩🇪🇦🇹🇨🇭 / 🇪🇺) -- **NEU**: Pro-Shop Geo-Region-Tracking (verschiedene Shops können verschiedene Regionen haben) -- Umbenannt von "DACH Version" zu "GeoIP Shop Blocker Manager" -- Cache-Datei umbenannt von `dach_ip_ranges.cache` zu `geoip_ip_ranges.cache` - -#### v2.2.0 -- **NEU**: Modus-Auswahl bei Aktivierung (PHP+CrowdSec 🛡️ oder Nur PHP 📝) -- **NEU**: PHP-only Modus für Server hinter CDN/Reverse-Proxy (Link11, Cloudflare) -- **NEU**: Modus-Anzeige in Status, Logs und Deaktivierungs-Menü -- **NEU**: Automatische Erkennung ob CrowdSec-Cleanup nötig ist -- **NEU**: Top 100 blockierte IPs (statt Top 10) in Gesamtübersicht -- **NEU**: Bot-Erkennung (GPTBot, SemrushBot, Googlebot, etc.) -- **NEU**: req/min Statistiken und Laufzeit-Anzeige -- **NEU**: Link11-Erkennung mit Farbcodierung -- **FIX**: CrowdSec Cleanup nutzt jetzt `--limit 0` für vollständige Löschung -- Verbesserte Dokumentation zu CDN/Proxy-Szenarien - -#### v2.1.0 -- **NEU**: Option [5] - Alle Shops gleichzeitig aktivieren -- **NEU**: Option [6] - Alle Shops gleichzeitig deaktivieren -- **NEU**: Gesamtübersicht in Logs (Option [0]) mit aggregierten Statistiken -- **NEU**: Visuelle Balken in der Statistik-Anzeige -- Verbessertes Menü-Layout mit Trennlinien - -#### v2.0.0 -- DACH-Support (DE, AT, CH statt nur DE) -- Systemd-Service für Watcher -- CrowdSec-Integration -- Multi-Shop-Management \ No newline at end of file +**Regionen**: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB (22 Länder) +**Features**: Cache-Validierung 🛡️ | Fail-Open 🔓 | Bot-Erkennung 🤖 \ No newline at end of file