# 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 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**: 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 50 IPs) - ✅ **Bot-Erkennung**: Automatische Identifikation von bekannten Bots/Crawlern - ✅ **Link11-Erkennung**: Farbige Anzeige ob Shop hinter Link11 CDN ist - ✅ **Auto-Deaktivierung**: PHP-Blocking UND CrowdSec-Bans laufen 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. ## 🌍 Geo-Regionen | 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 | ### 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 ### Modus 1: PHP + CrowdSec 🛡️ #### Komponente 1: PHP-Script - Wird in die `index.php` des Shops integriert - Lädt IP-Ranges von ipdeny.com (je nach Region) - Prüft jede Anfrage gegen diese Ranges - **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 - **Auto-Deaktivierung** nach 72 Stunden #### Komponente 2: Python Watcher (systemd service) - Läuft permanent im Hintergrund als root - Überwacht Queue-Dateien aller aktiven Shops - Fügt blockierte IPs automatisch zu CrowdSec hinzu - Vermeidet Duplikate durch In-Memory-Cache - Prüft alle 5 Sekunden auf neue IPs #### Komponente 3: CrowdSec Firewall Bouncer - Blockiert IPs auf Firewall-Ebene (iptables/nftables) - Schützt ALLE Services (HTTP, HTTPS, SSH, FTP, etc.) - Übernimmt Bans für 72 Stunden - Deutlich performanter als PHP-Checks ### Modus 2: Nur PHP 📝 - Nur das PHP-Script wird aktiviert - Keine CrowdSec-Synchronisation - Kein Watcher-Service nötig - **Ideal für Server hinter CDN/Proxy** (Link11, Cloudflare, etc.) > **Hinweis**: Bei Servern hinter einem CDN/Reverse-Proxy (wie Link11, Cloudflare, Hetzner LB) sieht iptables nur die Proxy-IP, nicht die echte Client-IP. In diesem Fall ist der **PHP-only Modus** die bessere Wahl, da PHP die echte IP aus dem `X-Forwarded-For` Header liest. ## 📋 Voraussetzungen - **Betriebssystem**: Ubuntu Server (getestet auf 24.04) - **Webserver**: Apache mit mod_rewrite (oder nginx) - **PHP**: Version 8.0 oder höher - **Python**: Version 3.8 oder höher - **CrowdSec**: Installiert und aktiv (nur für PHP+CrowdSec Modus) - **CrowdSec Firewall Bouncer**: Installiert und konfiguriert (nur für PHP+CrowdSec Modus) - **Plesk**: Optional, aber empfohlen - **Root-Zugriff**: Erforderlich für Installation und Verwaltung ### CrowdSec Installation prüfen (nur für PHP+CrowdSec Modus) ```bash # Prüfe ob CrowdSec läuft systemctl status crowdsec # Prüfe ob Firewall Bouncer aktiv ist cscli bouncers list # Sollte zeigen: # cs-firewall-bouncer-... mit ✔️ Valid und Recent Last API pull ``` Falls CrowdSec noch nicht installiert ist: ```bash curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash apt-get update apt-get install crowdsec crowdsec-firewall-bouncer-iptables ``` ## 🚀 Installation ### 1. Script herunterladen ```bash # Als root cd /root 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_blocker.py ``` Das war's! Das Script ist vollständig selbstverwaltend. ## 📖 Verwendung ### Hauptmenü ``` ════════════════════════════════════════════════════════════════ GeoIP Shop Blocker Manager v3.1.0 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB (22 Länder) 🛡️ Mit Cache-Validierung und Fail-Open ════════════════════════════════════════════════════════════════ ✅ CrowdSec ✅ Watcher-Service ──────────────────────────────────────── [1] Aktivieren (einzeln) [2] Deaktivieren (einzeln) [3] Logs anzeigen [4] Status ──────────────────────────────────────── [5] 🚀 ALLE aktivieren [6] 🛑 ALLE deaktivieren ──────────────────────────────────────── [0] Beenden ``` ### Geo-Region wählen Bei jeder Aktivierung wird zuerst nach der Region gefragt: ``` 🌍 Wähle die Geo-Region: [1] 🇩🇪🇦🇹🇨🇭 DACH - Deutschland, Österreich, Schweiz [2] 🇪🇺 Eurozone+GB - 22 Länder Region wählen [1/2]: ``` ### Blocking-Modus wählen Danach wird nach dem Modus gefragt: ``` 🔧 Wähle den Blocking-Modus: [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet) [2] Nur PHP (keine CrowdSec-Synchronisation) Modus wählen [1/2]: ``` **Wann welchen Modus wählen?** | 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_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` **Was passiert (PHP + CrowdSec Modus):** - Bei ERSTEM Shop: Systemd-Service wird installiert und gestartet - Backup der `index.php` wird erstellt - `geoip_blocking.php` wird erstellt und eingebunden - **Cache wird generiert und validiert** - Shop wird für Tracking registriert - Blocking ist sofort aktiv - Erlaubt werden nur IPs aus gewählter Region **Was passiert (Nur PHP Modus):** - Backup der `index.php` wird erstellt - `geoip_blocking.php` wird erstellt (ohne CrowdSec-Queue) - **Cache wird generiert und validiert** - Shop wird für Tracking registriert - Blocking ist sofort aktiv - Kein Watcher-Service nötig **Beispielausgabe:** ``` 🔧 Aktiviere 🇪🇺 Eurozone + GB GeoIP-Blocking für: shop.example.com Erlaubt: 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 ════════════════════════════════════════════════════════════════ [1/4] Installiere CrowdSec-Watcher-Service... ✅ Service gestartet [2/4] Aktiviere PHP-Blocking... ✅ PHP-Blocking aktiviert [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 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_blocker.py` 2. Option `[5] 🚀 ALLE aktivieren` wählen 3. Liste der zu aktivierenden Shops wird angezeigt (farbig nach Link11-Status) 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 ══════════════════════════════════════════════════════════════ 📋 5 Shop(s): • shop1.example.com [Link11] ← grün • shop2.example.com [Direkt] ← rot • 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 ⚠️ Region: 🇪🇺 Eurozone + GB Modus: Nur PHP 📝 Fortfahren? (ja/nein): ja ══════════════════════════════════════════════════════════════ [1/5] shop1.example.com ⏳ Cache generieren... ✅ Aktiviert (12,345 Ranges) ... ══════════════════════════════════════════════════════════════ ✅ 5 Shop(s) aktiviert 🛡️ Fail-Open bei Cache-Fehlern aktiv ══════════════════════════════════════════════════════════════ ``` ### Blocking deaktivieren (einzelner Shop) 1. Script starten: `python3 geoip_shop_blocker.py` 2. Option `[2] Deaktivieren (einzeln)` wählen 3. Shop aus der Liste auswählen (zeigt Region und Modus an) 4. Bestätigen mit `ja` **Was passiert:** - Original `index.php` wird wiederhergestellt - Alle PHP-Dateien werden gelöscht (inkl. Cache) - 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_blocker.py` 2. Option `[6] 🛑 ALLE 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_blocker.py` 2. Option `[3] Logs anzeigen` wählen 3. Auswahl treffen: ``` 📋 Logs für: [0] 📊 ALLE (Zusammenfassung) [1] shop1.example.com [Link11] 🇪🇺 🛡️ [2] shop2.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 📝 ... ``` Die Icons zeigen: - 🛡️ = PHP + CrowdSec Modus - 📝 = Nur PHP Modus - 🇪🇺 = Eurozone+GB Region - 🇩🇪🇦🇹🇨🇭 = DACH Region - `[Link11]` grün = hinter Link11 CDN - `[Direkt]` rot = direkt erreichbar #### Option [0]: Gesamtübersicht aller Shops Zeigt eine aggregierte Statistik über alle aktiven Shops: ``` ══════════════════════════════════════════════════════════════════════ 📊 GESAMTÜBERSICHT ALLER SHOPS ══════════════════════════════════════════════════════════════════════ Grün = hinter Link11 | Rot = Direkt 📝 PHP-Blocks gesamt: 5037 (⌀ 125.3 req/min, Laufzeit: 40m) ├─ shop1.example.com 🇪🇺: 923 (23.0 req/min, seit 40m) ████████████████████ │ └─➤ Top: 216.244.66.196 (DotBot) - 30x, 0.7 req/min ├─ shop2.example.com 🇩🇪🇦🇹🇨🇭: 412 (10.3 req/min, seit 40m) ████████████ │ └─➤ Top: 40.77.167.48 (Bingbot) - 25x, 0.6 req/min └─ shop3.example.com 🇪🇺: 312 (7.8 req/min, seit 40m) ████████ └─➤ Top: 52.167.144.139 (Bingbot) - 18x, 0.4 req/min 🛡️ CrowdSec-Bans gesamt: 892 ├─ shop1.example.com 🇪🇺: 401 ████████████████ ├─ shop2.example.com 🇩🇪🇦🇹🇨🇭: 298 ███████████ └─ shop3.example.com 🇪🇺: 193 ███████ 🔥 Top 50 blockierte IPs (alle Shops): 40.113.19.56 (Bingbot): 146 (3.6 req/min) → shop1.example.com [89x] █████████████ 185.220.101.34 (Unbekannt): 127 (3.2 req/min) → shop2.example.com [65x] ██████████ 45.95.169.22 (SemrushBot): 89 (2.2 req/min) → shop1.example.com [52x] ███████ ... ══════════════════════════════════════════════════════════════════════ ``` **Enthält:** - Legende für Link11-Farben - PHP-Blocks pro Shop mit req/min, Laufzeit und visuellen Balken - **Top-IP pro Shop** mit Bot-Erkennung und req/min - CrowdSec-Bans pro Shop (nur für PHP+CrowdSec Shops, farbig nach Link11) - **Top 50** der am häufigsten blockierten IPs mit: - Bot-Erkennung - req/min - Top-Shop für diese IP (farbig nach Link11) - Visuelle Balken #### Option [1-n]: Einzelner Shop Zeigt detaillierte Logs für einen spezifischen Shop: ``` ══════════════════════════════════════════════════════════════════════ 📊 shop1.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 [2025-12-09 10:24:55] IP: 45.95.169.22 | UA: SemrushBot/7 | URI: /kategorie ... 🔥 Top 10 IPs: 202.8.43.232 (Bytespider): 127x 45.95.169.22 (SemrushBot): 89x 40.77.167.48 (Bingbot): 67x ... ``` Bei PHP-only Shops wird angezeigt: ``` 📝 CrowdSec-Synchronisation ist für diesen Shop deaktiviert (PHP-only Modus) ``` ### Status prüfen Option `[4] Status` zeigt: ``` 📊 2/5 Shops aktiv shop1.example.com [Link11] 🇪🇺 🛡️ 1234 blocks, 2h 30m, Cache: ✅12,345 shop2.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 📝 567 blocks, 1h 15m, Cache: ✅3,456 ``` **Zeigt pro Shop:** - Link11-Status (farbig) - Geo-Region Icon - Modus Icon (🛡️ oder 📝) - Anzahl Blocks - Laufzeit - Cache-Status (✅ mit Anzahl oder ⚠️ bei Problemen) ## 🔧 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) cscli decisions list --limit 0 # Nur GeoIP-Blocks anzeigen cscli decisions list --limit 0 | grep "GeoIP" # Decisions für einen bestimmten Shop cscli decisions list --limit 0 | grep "shop.example.com" ``` ### Alle GeoIP-Decisions löschen (Einzeiler) ```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 ``` ### Systemd-Service verwalten ```bash # Status des Watcher-Service systemctl status geoip-crowdsec-watcher.service # Logs des Watcher-Service journalctl -u geoip-crowdsec-watcher.service -f # Service neu starten 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/`) | 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-Synchronisation (nur PHP+CrowdSec) | ### System-weit | 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 (inkl. Modus und Region) | ## ⚙️ Konfiguration ### Blocking-Dauer ändern Standardmäßig 72 Stunden. Zum Ändern editiere das Python-Script: ```python # In activate_blocking() und activate_all_shops() expiry = datetime.now() + timedelta(hours=72) # Hier ändern ``` ### Watcher-Intervall ändern Standard: 5 Sekunden. 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 ``` ### Mindest-Ranges für Cache-Validierung ändern ```python MIN_RANGES = { "dach": 1000, # Minimum für DACH "eurozone": 5000 # Minimum für Eurozone+GB } ``` ## 🛡️ Sicherheit ### Was wird geblockt? - ✅ 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.) ### Was wird NICHT geblockt? - ✅ Alle IPs aus der gewählten Region (basierend auf RIPE/ipdeny.com Daten) - ✅ Private IPs (192.168.x.x, 10.x.x.x, etc.) - ✅ Localhost (127.0.0.1) - ✅ Bei Cache-Fehlern: Alle IPs (Fail-Open) ### Fail-Open vs. Fail-Closed | Strategie | Verhalten bei Cache-Fehler | Risiko | |-----------|---------------------------|--------| | **Fail-Open** ✅ | Traffic durchlassen | Kurzzeitig kein Schutz | | Fail-Closed ❌ | Alles blockieren | Totaler Lockout möglich | **Wir nutzen Fail-Open** - lieber kurzzeitig keinen Schutz als alle Kunden aussperren! ### Auto-Deaktivierung nach 72 Stunden Beide Blocking-Mechanismen laufen automatisch aus: 1. **PHP-Blocking**: Das Script prüft ein Ablaufdatum und macht `return` nach 72h 2. **CrowdSec-Bans**: Werden mit `--duration 72h` erstellt **Sicherheitsfeature**: Falls jemand vergisst zu deaktivieren, läuft der Schutz automatisch aus. ## 🌐 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 ist: - 🟢 Grün `[Link11]` = Shop resolves zu 128.65.223.106 - 🔴 Rot `[Direkt]` = Shop ist direkt erreichbar ### Prüfen ob CDN aktiv ist ```bash # Welche IPs verbinden sich zu nginx/Apache? ss -tn state established '( sport = :80 or sport = :443 )' | head -20 # Wenn nur interne/CDN-IPs erscheinen → PHP-only Modus verwenden ``` ## 🐛 Troubleshooting ### Shop zeigt 403 für ALLE Besucher **Mögliche Ursache**: Korrupter Cache (sollte mit v3.1.0 durch Fail-Open verhindert werden) ```bash # 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 ``` **Hinweis**: Bei Cache-Fehlern greift Fail-Open - Traffic wird durchgelassen! ### Shop zeigt 500 Error **Ursache**: PHP-Syntax-Fehler oder falsche Einbindung ```bash # Prüfe PHP-Fehler-Log tail -50 /var/www/vhosts/SHOP/logs/error_log # Stelle Original-Index wieder her cd /var/www/vhosts/SHOP/httpdocs mv index.php.geoip_backup index.php # Deaktiviere via Script python3 geoip_shop_blocker.py # Option 2 ``` ### Watcher-Service läuft nicht ```bash # Status prüfen systemctl status geoip-crowdsec-watcher.service # Logs prüfen journalctl -u geoip-crowdsec-watcher.service -n 100 # Service neu starten systemctl restart geoip-crowdsec-watcher.service ``` ### CrowdSec Decisions werden nicht erstellt ```bash # Prüfe ob Queue-Datei beschrieben wird tail -f /var/www/vhosts/SHOP/httpdocs/geoip_crowdsec_queue.log # 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 ``` ### Firewall blockt nicht (trotz CrowdSec-Ban) **Mögliche Ursachen:** 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 ``` ### Cleanup nach Deaktivierung unvollständig ```bash # Manuelle Bereinigung aller GeoIP-Decisions (Einzeiler mit Fortschritt) 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" # Prüfen cscli decisions list --limit 0 | grep "GeoIP" ``` ### Migration von älteren Versionen Falls du von einer älteren Version wechselst: ```bash # 1. Alle aktiven Shops deaktivieren (alte Version) python3 geoip_shop_manager_old.py # Option 6 (alle deaktivieren) # 2. Alte Cache-Dateien löschen rm /var/www/vhosts/*/httpdocs/dach_ip_ranges.cache # 3. Neue Version verwenden python3 geoip_shop_blocker.py # Shops wieder aktivieren ``` ## 📊 Performance ### PHP-Level Blocking | Region | Overhead pro Request | Erster Request | Cache-Dauer | |--------|---------------------|----------------|-------------| | 🇩🇪🇦🇹🇨🇭 DACH | ~2-5ms | ~200-400ms | 24h | | 🇪🇺 Eurozone+GB | ~5-10ms | ~800-1200ms | 24h | ### 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 ### Empfohlene Limits | Server | RAM | Max. Shops | |--------|-----|------------| | Klein | 2 GB | 10 | | Mittel | 4-8 GB | 50 | | Groß | 16+ GB | Unbegrenzt | ## 📝 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 gewählter Region kommt 3. ✅ **Region wählen** (DACH für DACH-only, Eurozone für EU-weit) 4. ✅ **Modus wählen** (PHP+CrowdSec für direkte Server, PHP-only für CDN) 5. ✅ 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 5. ✅ Cache-Status im Status-Menü prüfen ### 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) ## ⚠️ Wichtige Hinweise ### Rechtliches - **DSGVO**: IP-Adressen werden nur temporär geloggt (72h) - **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 ## 📄 Lizenz 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. Prüfe den Cache-Status im Status-Menü 4. Erstelle ein GitHub Issue mit: - Fehlerbeschreibung - Relevante Logs - System-Infos (OS, PHP-Version, CrowdSec-Version) - **Verwendete 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.1.0 **Letztes Update**: Dezember 2025 **Status**: Production Ready ✅ **Regionen**: 🇩🇪🇦🇹🇨🇭 DACH (3 Länder) | 🇪🇺 Eurozone+GB (22 Länder) **Features**: Cache-Validierung 🛡️ | Fail-Open 🔓 | Bot-Erkennung 🤖 | Link11-Erkennung 🌐 ### Changelog #### v3.1.0 - **NEU**: Cache-Validierung bei Aktivierung - **NEU**: Fail-Open bei Cache-Fehlern (kein Total-Lockout mehr) - **NEU**: Selbstheilender Cache (automatische Regeneration bei Korruption) - **NEU**: Mindest-Range-Prüfung pro Region (DACH: 1000, Eurozone: 5000) - **NEU**: Cache-Status in Status-Anzeige (✅ oder ⚠️) #### v3.0.0 - **NEU**: Eurozone+GB Region (22 Länder) - **NEU**: Region-Auswahl bei Aktivierung - **NEU**: Region-Icons in Status/Logs (🇩🇪🇦🇹🇨🇭 oder 🇪🇺) - **NEU**: Bot-Erkennung in Logs (GPTBot, Googlebot, Bingbot, etc.) - **NEU**: Link11-Erkennung (farbige Anzeige) - **NEU**: req/min Statistiken pro Shop und IP - **NEU**: Top-IP pro Shop in Gesamtübersicht - Cache-Datei umbenannt 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**: Top 100 blockierte IPs in Gesamtübersicht (jetzt Top 50) - **FIX**: CrowdSec Cleanup nutzt jetzt `--limit 0` für vollständige Löschung #### 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 #### v2.0.0 - DACH-Support (DE, AT, CH statt nur DE) - Systemd-Service für Watcher - CrowdSec-Integration - Multi-Shop-Management