Files
geoip_shop_manager/README.md
2025-12-09 18:45:21 +01:00

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.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)

# 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)

  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

# 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.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:

# 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:

  1. CDN/Reverse-Proxy aktiv → Nutze Option [7] oder wechsle zu PHP-only Modus
  2. Bouncer läuft nicht:
    systemctl status crowdsec-firewall-bouncer
    
  3. 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

  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 (RIPE-basiert)
  • CrowdSec: 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


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