# GeoIP Shop Blocker Manager - DACH Version **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 DACH-Region (Deutschland, Österreich, Schweiz) zu sperren. Es kombiniert PHP-Level-Blocking mit optionaler CrowdSec Firewall-Integration für maximalen Schutz. ## 🎯 Features - ✅ **DACH-Region erlaubt**: Deutschland (DE), Österreich (AT), Schweiz (CH) - ✅ **Präzises Blocking**: PHP prüft gegen vollständige DACH IP-Ranges (keine Fehlblockierungen) - ✅ **Flexibler Modus**: Wahl zwischen "PHP + CrowdSec" oder "Nur PHP" - ✅ **Bot-Only Modus**: Nur Bots blocken, Shop bleibt weltweit erreichbar - ✅ **Rate-Limiting**: Konfigurierbares Rate-Limit für Bot-Blocking mit temporären Bans - ✅ **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 - ✅ **Link11-Erkennung**: Automatische Erkennung ob Shop hinter Link11 CDN steht - ✅ **Nur direkte Shops**: Option um nur Shops ohne CDN-Schutz zu aktivieren - ✅ **Gesamtübersicht**: Logs und Statistiken über alle Shops hinweg (Top 50 IPs) - ✅ **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. ## 🏗️ Architektur ### Modus 1: PHP + CrowdSec 🛡️ #### Komponente 1: PHP-Script - Wird in die `index.php` des Shops integriert - Lädt DACH IP-Ranges von ipdeny.com (DE, AT, CH) - Prüft jede Anfrage gegen diese Ranges - Blockt Nicht-DACH-IPs sofort mit HTTP 403 - Schreibt blockierte IPs in Queue-Datei für CrowdSec #### 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. ### Modus 3: Bot-Only 🤖 - Blockt nur bekannte Bots/Crawler (30+ Patterns) - Shop bleibt weltweit für normale Besucher erreichbar - **Mit Rate-Limiting**: Bots werden nach X Requests/Minute temporär gebannt - Ideal um AI-Crawler (GPTBot, ClaudeBot, etc.) fernzuhalten - Verfügbar mit oder ohne CrowdSec-Integration ## 🚦 Rate-Limiting (Bot-Only Modus) Im Bot-Only Modus wird ein konfigurierbares Rate-Limiting angewendet: ### Funktionsweise ``` Bot-Request kommt rein │ ▼ ┌───────────────────┐ │ Ist IP+UA gebannt?│──── Ja ───▶ 403 + Exit (sofort) └───────────────────┘ │ Nein ▼ ┌───────────────────┐ │ Bot erkannt? │──── Nein ──▶ Weiter (normaler Traffic) └───────────────────┘ │ Ja ▼ ┌───────────────────┐ │ Counter erhöhen │ │ Limit erreicht? │──── Ja ───▶ Ban erstellen + 403 └───────────────────┘ │ Nein ▼ 403 (normal) ``` ### Konfiguration bei Aktivierung ``` 🚦 Rate-Limit Konfiguration: Requests pro Minute bevor Ban [30]: _ Ban-Dauer in Minuten [5]: _ ``` ### Technische Details - **Speicherung**: File-basiert (kein Redis/Memcached nötig) - **Identifier**: MD5-Hash aus IP + User-Agent - **Algorithmus**: Sliding Window Counter (1 Minute Fenster) - **Cleanup**: Probabilistisch (1% der Requests) - **Retry-After**: Gebannte Clients erhalten Header mit verbleibender Ban-Zeit ### Verzeichnisstruktur ``` httpdocs/ └── geoip_ratelimit/ ├── bans/ │ └── {hash}.ban # Inhalt: Unix-Timestamp (ban bis) └── counts/ └── {hash}.count # Inhalt: window_start|count ``` ## 📋 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_manager.py chmod +x geoip_shop_manager.py ``` ### 2. Script ausführen ```bash python3 geoip_shop_manager.py ``` Das war's! Das Script ist vollständig selbstverwaltend. ## 📖 Verwendung ### Hauptmenü ``` [1] Aktivieren (einzeln) [2] Deaktivieren (einzeln) [3] Logs anzeigen [4] Status ──────────────────────────────────────── [5] 🚀 ALLE aktivieren [6] 🛑 ALLE deaktivieren [7] 🎯 Nur DIREKTE aktivieren (ohne Link11) ──────────────────────────────────────── [0] Beenden ``` ### Blocking-Modus wählen Bei jeder Aktivierung (einzeln oder alle) wird nach dem Modus gefragt: ``` 🔧 Wähle den Blocking-Modus: [1] 🌍 GeoIP + CrowdSec (IPs werden an CrowdSec gemeldet) [2] 🌍 Nur GeoIP (keine CrowdSec-Synchronisation) [3] 🤖 Nur Bot-Blocking (weltweit erreichbar, mit CrowdSec) [4] 🤖 Nur Bot-Blocking (weltweit erreichbar, ohne CrowdSec) Modus wählen [1/2/3/4]: ``` **Wann welchen Modus wählen?** | Situation | Empfohlener Modus | |-----------|-------------------| | Server direkt im Internet | GeoIP + CrowdSec 🛡️ | | Server hinter CDN (Link11, Cloudflare) | Nur GeoIP 📝 | | Nur Bots blocken, Shop weltweit erreichbar | Bot-Only 🤖 | | CrowdSec nicht installiert | Nur GeoIP 📝 oder Bot-Only 🤖 | | Minimaler Overhead gewünscht | Nur GeoIP 📝 | | Maximaler Schutz (alle Ports) | GeoIP + CrowdSec 🛡️ | ### Bot-Only Modus mit Rate-Limiting Wenn du Modus [3] oder [4] wählst, wirst du zusätzlich nach dem Rate-Limit gefragt: ``` 🚦 Rate-Limit Konfiguration: Requests pro Minute bevor Ban [30]: 20 Ban-Dauer in Minuten [5]: 10 ✅ Rate-Limit: 20 req/min ✅ Ban-Dauer: 10 Minuten ``` **Empfohlene Werte:** | Szenario | Rate-Limit | Ban-Dauer | |----------|------------|-----------| | Normale Abwehr | 30 req/min | 5 min | | Aggressive Bots | 10 req/min | 15 min | | Sehr strikt | 5 req/min | 30 min | ### Blocking aktivieren (einzelner Shop) 1. Script starten: `python3 geoip_shop_manager.py` 2. Option `[1] Aktivieren (einzeln)` wählen 3. Shop aus der Liste auswählen 4. **Modus wählen** (GeoIP oder Bot-Only, mit/ohne CrowdSec) 5. Bei Bot-Only: **Rate-Limit konfigurieren** 6. Bestätigen mit `ja` **Was passiert (Bot-Only Modus):** - Backup der `index.php` wird erstellt - `geoip_blocking.php` wird erstellt mit Bot-Patterns und Rate-Limiting - Rate-Limit Verzeichnisse werden erstellt (`geoip_ratelimit/bans/`, `geoip_ratelimit/counts/`) - Shop wird für Tracking registriert - Blocking ist sofort aktiv - 30+ Bot-Patterns werden erkannt und geblockt ### Blocking für ALLE Shops aktivieren 1. Script starten: `python3 geoip_shop_manager.py` 2. Option `[5] 🚀 ALLE aktivieren` wählen 3. Liste der zu aktivierenden Shops wird angezeigt 4. **Modus wählen** (gilt für alle Shops) 5. Bei Bot-Only: **Rate-Limit konfigurieren** (gilt für alle Shops) 6. Bestätigen mit `ja` **Beispielausgabe (Bot-Only):** ``` ══════════════════════════════════════════════════════════════ Blocking für ALLE Shops aktivieren ══════════════════════════════════════════════════════════════ 📋 5 Shop(s): • shop1.example.com [Link11] • shop2.example.com [Direkt] ... 🔧 Wähle den Blocking-Modus: [1] 🌍 GeoIP + CrowdSec (IPs werden an CrowdSec gemeldet) [2] 🌍 Nur GeoIP (keine CrowdSec-Synchronisation) [3] 🤖 Nur Bot-Blocking (weltweit erreichbar, mit CrowdSec) [4] 🤖 Nur Bot-Blocking (weltweit erreichbar, ohne CrowdSec) Modus wählen [1/2/3/4]: 4 🚦 Rate-Limit Konfiguration: Requests pro Minute bevor Ban [30]: 30 Ban-Dauer in Minuten [5]: 5 ✅ Rate-Limit: 30 req/min ✅ Ban-Dauer: 5 Minuten ⚠️ Modus: Nur Bot-Block 🤖 Rate-Limit: 30 req/min, Ban: 5 min Fortfahren? (ja/nein): ja ══════════════════════════════════════════════════════════════ [1/5] shop1.example.com ✅ Aktiviert (32 Bot-Patterns, 30 req/min) [2/5] shop2.example.com ✅ Aktiviert (32 Bot-Patterns, 30 req/min) ... ══════════════════════════════════════════════════════════════ ✅ 5 Shop(s) aktiviert 🚦 Rate-Limit: 30 req/min, Ban: 5 min ══════════════════════════════════════════════════════════════ ``` ### Blocking nur für DIREKTE Shops aktivieren (ohne Link11) Diese Option ist besonders nützlich, wenn du einen Mix aus Shops hast - einige hinter Link11 CDN, andere direkt exponiert. Mit Option `[7]` werden **nur die direkt exponierten Shops** aktiviert. 1. Script starten: `python3 geoip_shop_manager.py` 2. Option `[7] 🎯 Nur DIREKTE aktivieren (ohne Link11)` wählen 3. Liste zeigt welche Shops aktiviert/übersprungen werden 4. **Modus wählen** (gilt für alle direkten Shops) 5. Bei Bot-Only: **Rate-Limit konfigurieren** 6. Bestätigen mit `ja` **Beispielausgabe:** ``` ══════════════════════════════════════════════════════════════ Blocking für DIREKTE Shops aktivieren (ohne Link11) ══════════════════════════════════════════════════════════════ Grün = hinter Link11 (übersprungen) Rot = Direkt (wird aktiviert) 📋 3 direkte Shop(s) werden aktiviert: • shop2.example.com [Direkt] • shop4.example.com [Direkt] • shop5.example.com [Direkt] ⏭️ 2 Shop(s) hinter Link11 werden übersprungen: • shop1.example.com [Link11] • shop3.example.com [Link11] ``` **Warum diese Option?** - **CrowdSec-Effektivität**: Bei Shops hinter Link11 sieht iptables nur die Link11-IP, nicht die echte Client-IP. CrowdSec-Bans sind dort wirkungslos. - **Gezielter Schutz**: Schützt nur die Shops, die tatsächlich direkt exponiert sind und von CrowdSec profitieren. - **Zeitersparnis**: Keine unnötige Konfiguration für CDN-geschützte Shops. ### Blocking deaktivieren (einzelner Shop) 1. Script starten: `python3 geoip_shop_manager.py` 2. Option `[2] Deaktivieren (einzeln)` wählen 3. Shop aus der Liste auswählen (zeigt Modus an) 4. Bestätigen mit `ja` **Was passiert:** - Original `index.php` wird wiederhergestellt - Alle PHP-Dateien werden gelöscht - Rate-Limit Verzeichnis wird gelöscht (Bot-Only Modus) - 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 deaktivieren` wählen 3. Liste der aktiven Shops wird angezeigt 4. Bestätigen mit `ja` **Was passiert:** - Zeigt alle Shops mit aktivem Blocking - Deaktiviert das Blocking für jeden Shop nacheinander - Entfernt alle zugehörigen CrowdSec-Decisions (nur bei PHP+CrowdSec Shops) - Löscht alle Rate-Limit Daten (Bot-Only Shops) - Deinstalliert den Watcher-Service am Ende (falls aktiv) - Zusammenfassung mit Erfolgs-/Fehlerzählung ### Logs anzeigen 1. Script starten: `python3 geoip_shop_manager.py` 2. Option `[3] Logs anzeigen` wählen 3. Auswahl treffen: ``` 📋 Logs anzeigen für: [0] 📊 ALLE Shops (Zusammenfassung) [1] shop1.example.com 🛡️ [Link11] [2] shop2.example.com 🤖 [Direkt] ... ``` Die Icons zeigen den Modus: - 🛡️ = GeoIP + CrowdSec - 📝 = Nur GeoIP - 🤖🛡️ = Bot-Only + CrowdSec - 🤖 = Nur Bot-Only Die Farbcodierung zeigt den CDN-Status: - **Grün** = hinter Link11 - **Rot** = Direkt exponiert #### Option [0]: Gesamtübersicht aller Shops Zeigt eine aggregierte Statistik über alle aktiven Shops: ``` ════════════════════════════════════════════════════════════════ 📊 GESAMTÜBERSICHT ALLER SHOPS ════════════════════════════════════════════════════════════════ Grün = hinter Link11 | Rot = Direkt 📝 Blocks gesamt: 1.247 (⌀ 12.3 req/min, Laufzeit: 1h 41m) ├─ shop1.example.com 🤖 🤖: 523 (5.2 req/min, seit 1h 41m) █████████████████████ │ └─➤ Top: 185.220.101.34 (GPTBot) - 127x, 1.3 req/min ├─ shop2.example.com 🤖 🤖: 412 (4.1 req/min, seit 1h 40m) ████████████████ │ └─➤ Top: 45.95.169.22 (Bytespider) - 89x, 0.9 req/min └─ shop3.example.com 🤖 🤖: 312 (3.1 req/min, seit 1h 39m) ████████████ 🚫 Rate-Limit Bans: 45 ausgelöst, 12 aktiv ├─ shop1.example.com 🤖 🤖: 20 bans (5 aktiv) ██████████ ├─ shop2.example.com 🤖 🤖: 15 bans (4 aktiv) ███████ └─ shop3.example.com 🤖 🤖: 10 bans (3 aktiv) █████ 🤖 Bot-Statistik (alle Shops): Bingbot: 234x ███████████████████████████████████████████████ GPTBot: 189x █████████████████████████████████████ Googlebot: 156x ███████████████████████████████ Bytespider: 98x ███████████████████ ... 🔥 Top 50 blockierte IPs (alle Shops): 185.220.101.34 (GPTBot): 127 (1.3 req/min) → shop1.example.com [127x] █████████████████████████ 45.95.169.22 (Bytespider): 89 (0.9 req/min) → shop2.example.com [89x] █████████████████ ... ════════════════════════════════════════════════════════════════ ``` **Enthält:** - PHP-Blocks pro Shop mit visuellen Balken und req/min - Top-IP pro Shop mit Bot-Erkennung - **Rate-Limit Bans**: Anzahl ausgelöster und aktiver Bans (Bot-Only Modus) - **Bot-Statistik**: Welche Bots wie oft geblockt wurden - CrowdSec-Bans pro Shop (nur für CrowdSec-Modi) - Top 50 der am häufigsten blockierten IPs über alle Shops hinweg #### Option [1-n]: Einzelner Shop Zeigt detaillierte Logs für einen spezifischen Shop: ``` ══════════════════════════════════════════════════════════════════════ 📊 shop1.example.com | 🤖 Bot-Only 🤖 ══════════════════════════════════════════════════════════════════════ ⏱️ Laufzeit: 1h 41m 📈 Blocks: 523 (5.2 req/min) 🤖 Bot-Patterns: 32 aktiv 🚦 Rate-Limit: 30 req/min, Ban: 5 min 🚫 Bans: 20 ausgelöst, 5 aktiv 🤖 Bot-Statistik: Bingbot: 234x ███████████████████████████████████████████████ GPTBot: 189x █████████████████████████████████████ Googlebot: 100x ████████████████████ 📝 Letzte 30 Blocks: [2025-12-09 18:45:23] BOT: Bingbot | IP: 40.77.167.75 | Count: 15/30 | URI: / [2025-12-09 18:45:24] BOT: Bingbot | IP: 40.77.167.75 | Count: 16/30 | URI: /produkt [2025-12-09 18:45:25] BANNED: Bingbot | IP: 40.77.167.75 | Exceeded 30 req/min | Ban: 5m ... 🔥 Top 10 IPs: 40.77.167.75 (Bingbot): 234x 52.167.144.140 (Bingbot): 89x ... ``` ### Status prüfen Option `[4] Status anzeigen` zeigt: - Anzahl verfügbarer Shops - Anzahl aktiver Blockings - Liste aller Shops mit aktivem Blocking **und deren Modus** - Rate-Limit Konfiguration (Bot-Only Modus) - Aktive Bans (Bot-Only Modus) - Link11-Status (farbcodiert) ``` 📊 Status: 5/15 Shops aktiv shop1.example.com [Link11] 🤖 🤖 523 blocks, 1h 41m, 32 Bot-Patterns, 30 req/min, 5 aktive Bans shop2.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 🛡️ 412 blocks, 1h 40m, Cache: ✅8,234 shop3.example.com [Direkt] 🇩🇪🇦🇹🇨🇭 📝 312 blocks, 1h 39m, Cache: ✅8,234 ``` ## 🔧 Erweiterte Verwendung ### 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" ``` ### Rate-Limit Bans manuell prüfen (Bot-Only Modus) ```bash # Aktive Bans für einen Shop anzeigen ls -la /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/ # Anzahl aktiver Bans find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/ -name "*.ban" | wc -l # Ban-Inhalt prüfen (Unix-Timestamp bis wann gebannt) cat /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/*.ban # Request-Counter prüfen cat /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/counts/*.count ``` ### Rate-Limit Bans manuell löschen ```bash # Alle Bans für einen Shop löschen rm /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/*.ban # Alle Counter zurücksetzen rm /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/counts/*.count ``` ### 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/`) - `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, nur GeoIP-Modi) - `geoip_blocked.log` - Log der PHP-Level Blocks - `geoip_crowdsec_queue.log` - Queue für CrowdSec-Synchronisation (nur CrowdSec-Modi) - `geoip_ratelimit/` - Rate-Limit Daten (nur Bot-Only Modus) - `bans/` - Aktive Bans (Hash → Unix-Timestamp) - `counts/` - Request-Counter (Hash → window_start|count) ### 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, Rate-Limit Config) ## ⚙️ 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 ``` ### Rate-Limit Defaults ändern ```python # Am Anfang des Scripts DEFAULT_RATE_LIMIT = 30 # Requests pro Minute DEFAULT_BAN_DURATION = 5 # Minuten ``` ### Watcher-Intervall ändern Standard: 5 Sekunden. Zum Ändern im Watcher-Script: ```python # Zeile ~140 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 zur Whitelist hinzuzufügen, editiere im Python-Script das PHP-Template. Suche nach: ```php $countries = ['de', 'at', 'ch']; // Germany, Austria, Switzerland ``` Füge weitere Ländercodes hinzu (z.B. `'nl'` für Niederlande, `'be'` für Belgien). Die verfügbaren Ländercodes findest du unter: https://www.ipdeny.com/ipblocks/data/aggregated/ ### Bot-Patterns erweitern Im Python-Script findest du das Dictionary `BOT_PATTERNS`: ```python BOT_PATTERNS = { 'GPTBot': r'GPTBot', 'ClaudeBot': r'ClaudeBot', # Weitere Patterns hinzufügen... } ``` ### Link11-IP ändern Falls Link11 eine andere IP verwendet, kann diese im Script angepasst werden: ```python # Am Anfang des Scripts LINK11_IP = "128.65.223.106" # Hier ändern ``` ## 🛡️ Sicherheit ### Was wird geblockt? **GeoIP-Modi:** - ✅ Alle IPs außerhalb der konfigurierten Region (DACH oder Eurozone) - ✅ Auf PHP-Ebene: Sofortiger 403 Response - ✅ Auf Firewall-Ebene (nur PHP+CrowdSec): Alle Ports (HTTP, HTTPS, SSH, FTP, etc.) **Bot-Only Modus:** - ✅ 30+ bekannte Bot-Patterns (GPTBot, ClaudeBot, Bingbot, etc.) - ✅ Bots die das Rate-Limit überschreiten werden temporär gebannt - ✅ Normale Besucher weltweit erlaubt ### Was wird NICHT geblockt? - ✅ Alle IPs aus den erlaubten Ländern (GeoIP-Modi) - ✅ Normale Besucher ohne Bot-User-Agent (Bot-Only Modus) - ✅ Private IPs (192.168.x.x, 10.x.x.x, etc.) - ✅ Localhost (127.0.0.1) ### Erkannte Bot-Patterns | Kategorie | Bots | |-----------|------| | AI-Crawler | GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, anthropic-ai, PerplexityBot | | Suchmaschinen | Googlebot, Google-Extended, AdsBot-Google, Bingbot, BingPreview, msnbot, DuckDuckBot, YandexBot, Baiduspider | | Social Media | FacebookBot, LinkedInBot, Twitterbot, Slackbot | | SEO-Tools | AhrefsBot, SemrushBot, MJ12bot, DotBot, DataForSeoBot | | Andere | Applebot, Amazonbot, Bytespider, PetalBot, UptimeRobot, Pingdom, curl, python-requests, Wget, Scrapy | ## 🌐 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 1: 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 GeoIP** oder **[4] Nur Bot-Block**. ### Lösung 2: Option [7] - Nur direkte Shops Wenn du einen Mix aus Shops hast (einige hinter Link11, andere direkt): - Nutze Option `[7] 🎯 Nur DIREKTE aktivieren (ohne Link11)` - Das Script erkennt automatisch welche Shops hinter Link11 stehen - Nur direkt exponierte Shops werden mit CrowdSec-Integration aktiviert - Link11-geschützte Shops werden übersprungen ### 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 # DNS-Check für einen Shop dig +short shop.example.com # Wenn 128.65.223.106 → hinter Link11 ``` ## 🐛 Troubleshooting ### 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_manager.py # Option 2 ``` ### Rate-Limit funktioniert nicht (Bot-Only Modus) **Ursache**: Berechtigungsprobleme bei den Rate-Limit Verzeichnissen ```bash # Prüfe Berechtigungen ls -la /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/ # Fix: Berechtigungen korrigieren chmod -R 777 /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/ # Oder für alle Shops: for dir in /var/www/vhosts/*/httpdocs/geoip_ratelimit; do [ -d "$dir" ] && chmod -R 777 "$dir" && echo "Fixed: $dir" done ``` ### 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** → Nutze Option [7] oder 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 ``` ### Erlaubte IPs werden geblockt **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 # Prüfe ob IP in erlaubten Ranges ist php -r ' $ip = "91.107.229.191"; $ranges = unserialize(file_get_contents("/var/www/vhosts/SHOP/httpdocs/geoip_ip_ranges.cache")); foreach($ranges as $range) { list($subnet, $mask) = explode("/", $range); $ip_long = ip2long($ip); $subnet_long = ip2long($subnet); $mask_long = -1 << (32 - (int)$mask); if(($ip_long & $mask_long) == ($subnet_long & $mask_long)) { echo "IP $ip ist in Range $range\n"; } } ' ``` ### 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" ``` ### Link11-Erkennung funktioniert nicht ```bash # Manuelle DNS-Prüfung dig +short shop.example.com # Sollte 128.65.223.106 zeigen wenn hinter Link11 # Falls andere IP → Shop ist direkt exponiert ``` ## 📊 Performance ### PHP-Level Blocking (GeoIP) - **Overhead pro Request**: ~2-8ms (bei gecachten IP-Ranges) - **Erster Request**: ~400-800ms (beim Download der IP-Ranges) - **Cache-Dauer**: 24 Stunden - **RAM-Verbrauch**: ~5-10 MB pro Shop ### PHP-Level Blocking (Bot-Only mit Rate-Limiting) - **Overhead pro Request**: ~1-3ms (File-basierte Checks) - **Ban-Check**: ~0.5ms (einzelner File-Read) - **Counter-Update**: ~1-2ms (File-Lock + Write) - **Speicherplatz**: ~1 KB pro aktiver Bot (Hash-Dateien) ### CrowdSec Firewall Blocking (nur CrowdSec-Modi) - **Overhead**: 0ms (blockt vor PHP) - **RAM**: ~20-50 MB (Watcher-Service) - **Geblockte Pakete**: Werden gar nicht erst an Apache weitergeleitet ### 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 ## 🔄 Updates ### Script aktualisieren ```bash cd /root wget -O geoip_shop_manager.py https://git.jtl-hosting.de/thomasciesla/geoip_shop_manager/raw/branch/main/geoip_shop_manager.py chmod +x geoip_shop_manager.py ``` **WICHTIG**: Bereits aktive Shops bleiben unberührt. Der Watcher-Service muss manuell aktualisiert werden: ```bash # Für aktive Shops: Watcher-Service neu installieren # (Automatisch beim nächsten Aktivieren/Deaktivieren) # ODER manuell: systemctl stop geoip-crowdsec-watcher.service # Script ausführen und einen Shop kurz de-/reaktivieren ``` ### IP-Ranges aktualisieren ```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 # Nur BANNED Einträge (Rate-Limit überschritten) grep "BANNED:" /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 # Top 10 gebannte Bots (Bot-Only Modus) grep "BOT:" /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log | \ grep -oP 'BOT: \K[^ |]+' | 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 (GeoIP-Modi) 3. ✅ **Link11-Status prüfen** (farbcodiert im Script) 4. ✅ **Modus wählen** (GeoIP vs. Bot-Only, mit/ohne CrowdSec) 5. ✅ **Rate-Limit konfigurieren** (Bot-Only Modus) 6. ✅ Bei gemischtem Setup: **Option [7]** für nur direkte Shops nutzen 7. ✅ Test mit kurzer Dauer (kann im Script angepasst werden) 8. ✅ 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 CrowdSec-Modi) 4. ✅ Rate-Limit Bans prüfen (Bot-Only Modus) 5. ✅ Server-Performance monitoren ### Nach Deaktivierung 1. ✅ Prüfen ob alle Decisions entfernt wurden (nur bei CrowdSec-Modi) 2. ✅ Rate-Limit Verzeichnis wird automatisch gelöscht (Bot-Only Modus) 3. ✅ Backup-Dateien können gelöscht werden (optional) 4. ✅ 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 oder Option [7] empfohlen - **Rate-Limiting**: File-basiert, funktioniert ohne Redis/Memcached ### 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 oder Option [7] verwenden - ✅ Bot-Only Modus für gezielte Bot-Abwehr ohne GeoBlocking ## 🤝 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 ## 📄 Lizenz MIT License - siehe LICENSE Datei ## 🙏 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) - **Verwendeter Modus** (GeoIP/Bot-Only, mit/ohne CrowdSec) - **Rate-Limit Konfiguration** (Bot-Only Modus) - **Link11-Status** der betroffenen Shops ## 📚 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.4.2 **Letztes Update**: Dezember 2025 **Status**: Production Ready ✅ **Erlaubte Regionen**: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Only (weltweit) ### Changelog #### v3.4.2 - **FIX**: Verzeichnis-Berechtigungen für Rate-Limit (777 statt 755) - PHP läuft als anderer User als root - Verzeichnisse müssen für alle schreibbar sein #### v3.4.1 - **FIX**: Bot-Namen werden jetzt korrekt in Statistiken angezeigt - Bot-Name wird direkt aus dem Log extrahiert (`BOT:` / `BANNED:`) statt aus UA geparst #### v3.4.0 - **NEU**: File-basiertes Rate-Limiting für Bot-Only Modus - **NEU**: Konfigurierbare Rate-Limits (Requests/Minute) bei Aktivierung - **NEU**: Konfigurierbare Ban-Dauer bei Überschreitung - **NEU**: Sliding Window Counter Algorithmus - **NEU**: Automatisches Cleanup abgelaufener Bans (probabilistisch) - **NEU**: Retry-After Header bei gebannten Requests - **NEU**: Rate-Limit Statistiken in Logs und Gesamtübersicht - **NEU**: Verzeichnisstruktur `geoip_ratelimit/bans/` und `geoip_ratelimit/counts/` #### v3.3.0 - **NEU**: Option [7] - Nur direkte Shops aktivieren (ohne Link11) - **NEU**: Automatische Link11-Erkennung per DNS-Lookup - **NEU**: Farbcodierung im Menü (Grün = Link11, Rot = Direkt) - **NEU**: Hilfsfunktionen `get_direct_shops()` und `get_link11_shops()` - Verbesserte Dokumentation zu CDN-Szenarien und Option [7] #### v3.2.0 - **NEU**: Bot-Only Blocking Modus (weltweit erreichbar, nur Bots blocken) - **NEU**: 4 Blocking-Modi: GeoIP+CrowdSec, GeoIP-only, Bot+CrowdSec, Bot-only - **NEU**: Bot-Statistiken in Logs und Gesamtübersicht - **NEU**: 30+ Bot-Patterns (GPTBot, ClaudeBot, Googlebot, etc.) #### v3.1.0 - **NEU**: Eurozone+GB Region (22 Länder) - **NEU**: Cache-Validierung mit Mindest-Range-Prüfung - **NEU**: Fail-Open Mechanismus bei Cache-Fehlern - Verbesserte Fehlerbehandlung #### v3.0.0 - **NEU**: DACH-Support (DE, AT, CH statt nur DE) - Systemd-Service für Watcher - CrowdSec-Integration - Multi-Shop-Management #### 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 - **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