# GeoIP Shop Blocker Manager - DACH & Eurozone 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 konfigurierten Region zu sperren. Es kombiniert PHP-Level-Blocking mit optionaler CrowdSec Firewall-Integration für maximalen Schutz. ## 🎯 Features - ✅ **Flexible Regionen**: DACH (DE, AT, CH) oder Eurozone+GB (22 Länder) - ✅ **Bot-Rate-Limiting**: Bots unter Limit durchlassen, bei Überschreitung temporär bannen - ✅ **Präzises Blocking**: PHP prüft gegen vollständige IP-Ranges (keine Fehlblockierungen) - ✅ **Flexibler Modus**: 4 Modi - GeoIP+CrowdSec, GeoIP-only, Bot+CrowdSec, Bot-only - ✅ **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. - ✅ **Fail-Open**: Bei Cache-Fehlern wird Traffic durchgelassen (keine Ausfälle) ## 🏗️ Architektur ### Modus 1: GeoIP + CrowdSec 🛡️ #### Komponente 1: PHP-Script - Wird in die `index.php` des Shops integriert - Lädt IP-Ranges von ipdeny.com (konfigurierte Länder) - Prüft jede Anfrage gegen diese Ranges - Blockt Nicht-erlaubte 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 GeoIP 📝 - Nur das PHP-Script wird aktiviert - Keine CrowdSec-Synchronisation - Kein Watcher-Service nötig - **Ideal für Server hinter CDN/Proxy** (Link11, Cloudflare, etc.) ### Modus 3: Bot-Rate-Limiting + CrowdSec 🤖🛡️ - Shop bleibt weltweit erreichbar - Nur bekannte Bots werden rate-limited - **Bots unter dem Limit werden durchgelassen** - Bei Überschreitung: temporärer Ban + CrowdSec-Meldung ### Modus 4: Nur Bot-Rate-Limiting 🤖 - Shop bleibt weltweit erreichbar - Nur bekannte Bots werden rate-limited - **Bots unter dem Limit werden durchgelassen** - Keine CrowdSec-Synchronisation > **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** oder **Bot-only Modus** die bessere Wahl. ## 🚦 Rate-Limiting (Bot-Only Modus) ### Funktionsweise Das Rate-Limiting im Bot-Only Modus funktioniert wie folgt: ``` 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 ▼ Log + Weiter ✅ (Bot darf durch!) ``` **Wichtig**: Bots werden **nicht** sofort geblockt! Sie dürfen crawlen, solange sie unter dem konfigurierten Limit bleiben. Erst bei Überschreitung werden sie temporär gebannt. ### Konfiguration bei Aktivierung Bei Aktivierung des Bot-Only Modus werden zwei Werte abgefragt: ``` 🚦 Rate-Limit Konfiguration: Requests pro Minute bevor Ban [30]: Ban-Dauer in Minuten [5]: ✅ Rate-Limit: 30 req/min ✅ Ban-Dauer: 5 Minuten ``` - **Requests pro Minute**: Wie viele Requests ein Bot pro Minute machen darf (Default: 30) - **Ban-Dauer**: Wie lange ein Bot nach Überschreitung gebannt wird (Default: 5 Minuten) ### Technische Details - **Identifier**: MD5-Hash aus IP + User-Agent (ermöglicht granulare Tracking pro Bot-Typ) - **Speicherung**: File-basiert in `geoip_ratelimit/` Verzeichnis - **Cleanup**: Probabilistisch (1% der Requests) um Overhead zu minimieren - **Atomare Operationen**: File-Locking verhindert Race Conditions ### Verzeichnisstruktur ``` httpdocs/ ├── geoip_ratelimit/ │ ├── bans/ │ │ └── {hash}.ban # Unix-Timestamp wann Ban abläuft │ └── counts/ │ └── {hash}.count # Format: window_start|count ``` ## 🤖 Erkannte Bot-Patterns Das System erkennt über 30 verschiedene Bots: | 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 | | **SEO-Tools** | AhrefsBot, SemrushBot, MJ12bot, DotBot, DataForSeoBot | | **Social Media** | FacebookBot, LinkedInBot, Twitterbot, Slackbot | | **Andere** | Applebot, Amazonbot, Bytespider, PetalBot, UptimeRobot, Pingdom | | **CLI-Tools** | curl, python-requests, Wget, Scrapy | ## 📋 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 +CrowdSec Modi) - **CrowdSec Firewall Bouncer**: Installiert und konfiguriert (nur für +CrowdSec Modi) - **Plesk**: Optional, aber empfohlen - **Root-Zugriff**: Erforderlich für Installation und Verwaltung ### CrowdSec Installation prüfen (nur für +CrowdSec Modi) ```bash # Prüfe ob CrowdSec läuft systemctl status crowdsec # Prüfe ob Firewall Bouncer aktiv ist cscli bouncers list ``` 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ü ``` ============================================================ GeoIP Shop Blocker Manager v3.4.3 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Rate-Limiting 🛡️ Mit Cache-Validierung und Fail-Open 🚦 Bots unter Rate-Limit werden durchgelassen ============================================================ [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 ``` ### Modus-Auswahl Bei jeder Aktivierung 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] 🤖 Bot-Rate-Limiting (weltweit erreichbar, mit CrowdSec) [4] 🤖 Bot-Rate-Limiting (weltweit erreichbar, ohne CrowdSec) Modus wählen [1/2/3/4]: ``` **Wann welchen Modus wählen?** | Situation | Empfohlener Modus | |-----------|-------------------| | Server direkt im Internet, Geo-Blocking gewünscht | GeoIP + CrowdSec 🛡️ | | Server hinter CDN, Geo-Blocking gewünscht | Nur GeoIP 📝 | | Weltweit erreichbar bleiben, nur Bots bremsen | Bot-Rate-Limiting 🤖 | | CrowdSec nicht installiert | Nur GeoIP 📝 oder Bot-only 🤖 | ### Geo-Region wählen (nur GeoIP-Modi) ``` 🌍 Wähle die Geo-Region: [1] 🇩🇪🇦🇹🇨🇭 DACH - Deutschland, Österreich, Schweiz [2] 🇪🇺 Eurozone+GB - 22 Länder Region wählen [1/2]: ``` ### Beispielausgabe: Bot-Only Aktivierung ``` 🔧 Aktiviere 🤖 Bot-Only für: shop.example.com Modus: Bot-Rate-Limiting (weltweit erreichbar) Rate-Limit: 30 req/min, Ban: 5 min CrowdSec: Nein ============================================================ [1/4] CrowdSec-Synchronisation deaktiviert [2/4] Aktiviere PHP-Blocking... ✅ PHP-Blocking aktiviert [3/4] Cache-Generierung nicht erforderlich (Bot-Only) [4/4] Registriere Shop... ============================================================ ✅ 🤖 Bot-Only aktiviert Shop: shop.example.com Modus: Nur Bot-Rate-Limit 🤖 🤖 32 Bot-Patterns aktiv 🚦 Rate-Limit: 30 req/min, Ban: 5 min ℹ️ Bots unter dem Limit werden durchgelassen Gültig bis: 2025-12-12 19:30:00 CET ============================================================ ``` ### Logs anzeigen Die Logs zeigen bei Bot-Only Modus auch die Rate-Limit Statistiken: ``` ══════════════════════════════════════════════════════════════════════ 📊 shop.example.com | 🤖 Bot-Only 🤖 ══════════════════════════════════════════════════════════════════════ ⏱️ Laufzeit: 2h 15m 📈 Log-Einträge: 1,234 (9.1 req/min) 🤖 Bot-Patterns: 32 aktiv 🚦 Rate-Limit: 30 req/min, Ban: 5 min 🚫 Bans: 23 ausgelöst, 3 aktiv 🤖 Bot-Statistik: Googlebot: 456x ███████████████████████████████████████ Bingbot: 234x ███████████████████ GPTBot: 189x ███████████████ AhrefsBot: 123x ██████████ ... 📝 Letzte 30 Log-Einträge: [2025-12-09 19:45:23] BOT: Googlebot | IP: 66.249.66.1 | Count: 12/30 | URI: /produkt-123 [2025-12-09 19:45:24] BOT: Googlebot | IP: 66.249.66.1 | Count: 13/30 | URI: /kategorie-abc [2025-12-09 19:45:25] BANNED: GPTBot | IP: 20.15.240.64 | Exceeded 30 req/min | Ban: 5m | UA: ... ... ``` ### Status anzeigen ``` 📊 5/15 Shops aktiv shop1.example.com [Link11] 🇩🇪🇦🇹🇨🇭 🛡️ 523 blocks, 1h 41m, Cache: ✅8,234 shop2.example.com [Direkt] 🤖 🤖 1,234 log entries, 2h 15m, 32 Bot-Patterns, 30 req/min, 3 aktive Bans shop3.example.com [Direkt] 🇪🇺 📝 312 blocks, 1h 39m, Cache: ✅12,456 ``` ## 🔧 Erweiterte Verwendung ### Manuell CrowdSec Decisions prüfen ```bash # Alle Decisions anzeigen cscli decisions list --limit 0 # Nur GeoIP-Blocks anzeigen cscli decisions list --limit 0 | grep "GeoIP" ``` ### Rate-Limit Dateien prüfen ```bash # Aktive Bans anzeigen find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/ -name "*.ban" -exec cat {} \; # Request-Counter anzeigen find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/counts/ -name "*.count" -exec cat {} \; # Anzahl aktiver Bans find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/ -name "*.ban" | wc -l ``` ### 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 ``` ## 📁 Dateistruktur ### Pro Shop (in `/var/www/vhosts/SHOP/httpdocs/`) **GeoIP-Modi:** - `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 Blocks - `geoip_crowdsec_queue.log` - Queue für CrowdSec (nur +CrowdSec Modi) **Bot-Only Modi (zusätzlich):** - `geoip_ratelimit/` - Rate-Limit Verzeichnis - `bans/` - Aktive Bans (`.ban` Dateien) - `counts/` - Request-Counter (`.count` Dateien) ### 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 ## ⚙️ Konfiguration ### Blocking-Dauer ändern Standardmäßig 72 Stunden. Zum Ändern editiere das Python-Script: ```python 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 ``` ### Weitere Länder hinzufügen Editiere `GEO_REGIONS` im Python-Script: ```python GEO_REGIONS = { "dach": { "countries": ["de", "at", "ch"], # Hier Länder hinzufügen ... }, ... } ``` ### Link11-IP ändern ```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 - ✅ Auf PHP-Ebene: Sofortiger 403 Response - ✅ Auf Firewall-Ebene (+CrowdSec): Alle Ports **Bot-Only Modi:** - ✅ Erkannte Bots die das Rate-Limit überschreiten - ✅ Temporärer Ban (konfigurierbare Dauer) - ❌ Bots unter dem Limit werden durchgelassen (gewollt!) ### Was wird NICHT geblockt? - ✅ Alle IPs aus den erlaubten Ländern (GeoIP-Modi) - ✅ Normaler User-Traffic (Bot-Only Modi) - ✅ Bots unter dem Rate-Limit (Bot-Only Modi) - ✅ Private IPs (192.168.x.x, 10.x.x.x, etc.) - ✅ Localhost (127.0.0.1) ## 🐛 Troubleshooting ### Shop zeigt 500 Error ```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 ``` ### Rate-Limit funktioniert nicht ```bash # Prüfe Verzeichnis-Berechtigungen ls -la /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/ # Sollte 777 sein (PHP läuft als anderer User) # Falls nicht: chmod -R 777 /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/ ``` ### Bots werden sofort geblockt (nicht rate-limited) **Prüfe ob du die aktuelle Version (v3.4.3+) verwendest!** In älteren Versionen wurden Bots sofort geblockt. Ab v3.4.3 werden Bots unter dem Limit durchgelassen. ```bash # Version prüfen grep "v3.4" geoip_shop_manager.py # Update durchführen wget -O geoip_shop_manager.py https://git.jtl-hosting.de/... # Shops neu aktivieren (deaktivieren + aktivieren) # damit das neue PHP-Template angewendet wird ``` ### 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 ``` ### Rate-Limit Verzeichnisse sind leer trotz Bot-Traffic **Berechtigungsproblem!** Das Python-Script läuft als root, aber PHP läuft als Domain-User. ```bash # Quick-Fix für alle Shops: for dir in /var/www/vhosts/*/httpdocs/geoip_ratelimit; do [ -d "$dir" ] && chmod -R 777 "$dir" && echo "Fixed: $dir" done ``` Ab v3.4.2 werden die Verzeichnisse automatisch mit 777 erstellt. ## 📊 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 ### Bot-Rate-Limiting - **Overhead pro Request**: ~1-3ms (File-I/O) - **Ban-Check**: ~0.5ms (schneller Pfad) - **Cleanup**: Probabilistisch (1% der Requests) ### CrowdSec Firewall Blocking - **Overhead**: 0ms (blockt vor PHP) - **RAM**: ~20-50 MB (Watcher-Service) ## 📝 Logs und Monitoring ### PHP-Level Logs ```bash # Blockierte IPs/Bots für einen Shop tail -f /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 # Nur BOT Einträge (unter Limit, durchgelassen) grep "BOT:" /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log ``` ### Bot-Statistik erstellen ```bash # Top 10 Bots (aus Log) grep -oP '(BOT|BANNED): \K[^|]+' /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log | \ sed 's/ //g' | sort | uniq -c | sort -rn | head -10 ``` ## 📚 Changelog ### v3.4.3 - **FIX**: Rate-Limit Logik korrigiert - Bots unter dem Limit werden jetzt durchgelassen - Vorher: Alle erkannten Bots wurden sofort mit 403 geblockt - Nachher: Bots dürfen crawlen bis sie das Limit überschreiten, dann temporärer Ban - PHP-Templates aktualisiert mit korrektem Flowchart ### v3.4.2 - **FIX**: Verzeichnis-Berechtigungen für Rate-Limit (0o777 statt 0o755) - PHP läuft als Domain-User, nicht als root - Explizite `os.chmod()` Aufrufe nach `os.makedirs()` ### v3.4.1 - **FIX**: Bot-Namen werden jetzt korrekt in Statistiken angezeigt - Bot-Name wird direkt aus Log extrahiert (BOT: / BANNED: Prefix) - Fallback auf User-Agent Detection wenn nötig ### v3.4.0 - **NEU**: File-basiertes Rate-Limiting für Bot-Only Modus - **NEU**: Konfigurierbare Rate-Limits (Requests/Minute, Ban-Dauer) - **NEU**: Sliding Window Counter Algorithmus - **NEU**: Probabilistisches Cleanup (1% der Requests) - **NEU**: Ban-Check als schneller Pfad (vor Bot-Detection) ### 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) ### 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**: 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 ### v3.0.0 - **NEU**: DACH-Support (DE, AT, CH) - Systemd-Service für Watcher - CrowdSec-Integration - Multi-Shop-Management --- **Version**: 3.4.3 **Letztes Update**: Dezember 2025 **Status**: Production Ready ✅ **Erlaubte Regionen**: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Only (weltweit)