38 KiB
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.phpdes 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-ForHeader 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)
# 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:
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
# 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
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)
- Script starten:
python3 geoip_shop_manager.py - Option
[1] Aktivieren (einzeln)wählen - Shop aus der Liste auswählen
- Modus wählen (GeoIP oder Bot-Only, mit/ohne CrowdSec)
- Bei Bot-Only: Rate-Limit konfigurieren
- Bestätigen mit
ja
Was passiert (Bot-Only Modus):
- Backup der
index.phpwird erstellt geoip_blocking.phpwird 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
- Script starten:
python3 geoip_shop_manager.py - Option
[5] 🚀 ALLE aktivierenwählen - Liste der zu aktivierenden Shops wird angezeigt
- Modus wählen (gilt für alle Shops)
- Bei Bot-Only: Rate-Limit konfigurieren (gilt für alle Shops)
- 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.
- Script starten:
python3 geoip_shop_manager.py - Option
[7] 🎯 Nur DIREKTE aktivieren (ohne Link11)wählen - Liste zeigt welche Shops aktiviert/übersprungen werden
- Modus wählen (gilt für alle direkten Shops)
- Bei Bot-Only: Rate-Limit konfigurieren
- 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)
- Script starten:
python3 geoip_shop_manager.py - Option
[2] Deaktivieren (einzeln)wählen - Shop aus der Liste auswählen (zeigt Modus an)
- Bestätigen mit
ja
Was passiert:
- Original
index.phpwird 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
- Script starten:
python3 geoip_shop_manager.py - Option
[6] 🛑 ALLE deaktivierenwählen - Liste der aktiven Shops wird angezeigt
- 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
- Script starten:
python3 geoip_shop_manager.py - Option
[3] Logs anzeigenwählen - 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
# 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)
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)
# 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
# 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
# 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
# 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
# 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.phpgeoip_blocking.php- PHP-Blocking-Scriptgeoip_ip_ranges.cache- Gecachte IP-Ranges (erneuert alle 24h, nur GeoIP-Modi)geoip_blocked.log- Log der PHP-Level Blocksgeoip_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:
# Zeile ~400 und ~750
expiry = datetime.now() + timedelta(hours=72) # Hier ändern
Rate-Limit Defaults ändern
# 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:
# Zeile ~140
CHECK_INTERVAL = 5 # In Sekunden
IP-Range-Cache-Dauer ändern
Standard: 24 Stunden. Im PHP-Script:
$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:
$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:
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:
# 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
# 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
# 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
# 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
# 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
# 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:
- CDN/Reverse-Proxy aktiv → Nutze Option [7] oder wechsle zu PHP-only Modus
- Bouncer läuft nicht:
systemctl status crowdsec-firewall-bouncer - iptables-Regeln fehlen:
iptables -L -n -v | grep crowdsec
Erlaubte IPs werden geblockt
Sehr unwahrscheinlich! Aber falls doch:
# 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
# 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
# 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
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:
# 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
# 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
# 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
# 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
# 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
- ✅ Backup erstellen (macht das Script automatisch)
- ✅ Sicherstellen, dass Admin-Zugriff aus erlaubter Region kommt (GeoIP-Modi)
- ✅ Link11-Status prüfen (farbcodiert im Script)
- ✅ Modus wählen (GeoIP vs. Bot-Only, mit/ohne CrowdSec)
- ✅ Rate-Limit konfigurieren (Bot-Only Modus)
- ✅ Bei gemischtem Setup: Option [7] für nur direkte Shops nutzen
- ✅ Test mit kurzer Dauer (kann im Script angepasst werden)
- ✅ Monitoring einrichten
Während aktivem Blocking
- ✅ Logs regelmäßig prüfen (Gesamtübersicht nutzen!)
- ✅ Auf Fehlblockierungen achten (sehr selten)
- ✅ CrowdSec-Statistiken beobachten (nur bei CrowdSec-Modi)
- ✅ Rate-Limit Bans prüfen (Bot-Only Modus)
- ✅ Server-Performance monitoren
Nach Deaktivierung
- ✅ Prüfen ob alle Decisions entfernt wurden (nur bei CrowdSec-Modi)
- ✅ Rate-Limit Verzeichnis wird automatisch gelöscht (Bot-Only Modus)
- ✅ Backup-Dateien können gelöscht werden (optional)
- ✅ 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:
- Fork das Repository
- Erstelle einen Feature-Branch
- Committe deine Änderungen
- Push zum Branch
- Erstelle einen Pull Request
📄 Lizenz
MIT License - siehe LICENSE Datei
🙏 Credits
- IP-Ranges: ipdeny.com (RIPE-basiert)
- CrowdSec: crowdsec.net
- Entwickelt für: Plesk-basierte Multi-Shop-Server
📞 Support
Bei Problemen:
- Prüfe die Troubleshooting-Sektion
- Prüfe die Logs (Gesamtübersicht oder einzeln)
- 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
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/undgeoip_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()undget_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 0fü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