Files
geoip_shop_manager/README.md
2025-12-09 07:35:52 +01:00

32 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"
  • Doppelter Schutz: PHP-Level + Firewall-Level (CrowdSec) - optional
  • Automatische Synchronisation: Blockierte IPs werden automatisch an CrowdSec weitergegeben
  • Multi-Shop-Management: Verwaltung mehrerer Shops auf einem Server
  • Bulk-Operationen: Alle Shops gleichzeitig aktivieren/deaktivieren
  • Gesamtübersicht: Logs und Statistiken über alle Shops hinweg (Top 100 IPs)
  • Bot-Erkennung: Automatische Identifikation von 80+ Bots/Crawlern (Googlebot, GPTBot, AhrefsBot, etc.)
  • Request-Statistiken: Requests pro Minute (req/min) und Laufzeit pro Shop
  • 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.

📋 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] GeoIP-Blocking AKTIVIEREN (einzeln)
[2] GeoIP-Blocking DEAKTIVIEREN (einzeln)
[3] Logs anzeigen
[4] Status anzeigen
────────────────────────────────────────
[5] 🚀 ALLE Shops aktivieren
[6] 🛑 ALLE Shops deaktivieren
────────────────────────────────────────
[0] Beenden

Blocking-Modus wählen

Bei jeder Aktivierung (einzeln oder alle) wird nach dem Modus gefragt:

🔧 Wähle den Blocking-Modus:
   [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet)
   [2] Nur PHP (keine CrowdSec-Synchronisation)

Modus wählen [1/2]: 

Wann welchen Modus wählen?

Situation Empfohlener Modus
Server direkt im Internet PHP + CrowdSec 🛡️
Server hinter CDN (Link11, Cloudflare) Nur PHP 📝
CrowdSec nicht installiert Nur PHP 📝
Minimaler Overhead gewünscht Nur PHP 📝
Maximaler Schutz (alle Ports) PHP + CrowdSec 🛡️

Blocking aktivieren (einzelner Shop)

  1. Script starten: python3 geoip_shop_manager.py
  2. Option [1] GeoIP-Blocking AKTIVIEREN (einzeln) wählen
  3. Shop aus der Liste auswählen
  4. Modus wählen (PHP+CrowdSec oder Nur PHP)
  5. Bestätigen mit ja

Was passiert (PHP + CrowdSec Modus):

  • Bei ERSTEM Shop: Systemd-Service wird installiert und gestartet
  • Backup der index.php wird erstellt
  • geoip_blocking.php wird erstellt und eingebunden
  • Shop wird für Tracking registriert
  • Blocking ist sofort aktiv
  • Erlaubt werden nur IPs aus: 🇩🇪 Deutschland, 🇦🇹 Österreich, 🇨🇭 Schweiz

Was passiert (Nur PHP Modus):

  • Backup der index.php wird erstellt
  • geoip_blocking.php wird erstellt (ohne CrowdSec-Queue)
  • Shop wird für Tracking registriert
  • Blocking ist sofort aktiv
  • Kein Watcher-Service nötig

Blocking für ALLE Shops aktivieren

  1. Script starten: python3 geoip_shop_manager.py
  2. Option [5] 🚀 ALLE Shops aktivieren wählen
  3. Liste der zu aktivierenden Shops wird angezeigt
  4. Modus wählen (gilt für alle Shops)
  5. Bestätigen mit ja

Beispielausgabe:

══════════════════════════════════════════════════════════════
  DACH GeoIP-Blocking für ALLE Shops aktivieren
══════════════════════════════════════════════════════════════

📋 Folgende 5 Shop(s) werden aktiviert:

   • shop1.example.com
   • shop2.example.com
   • shop3.example.com
   ...

🔧 Wähle den Blocking-Modus:
   [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet)
   [2] Nur PHP (keine CrowdSec-Synchronisation)

Modus wählen [1/2]: 2

⚠️  Dies aktiviert den Schutz für alle oben genannten Shops!
   Modus: Nur PHP 📝

Fortfahren? (ja/nein): ja

══════════════════════════════════════════════════════════════
  Starte Aktivierung (Nur PHP 📝)...
══════════════════════════════════════════════════════════════

[1/5] Aktiviere: shop1.example.com
   ✅ Aktiviert (bis 2025-12-11 14:30)
...

══════════════════════════════════════════════════════════════
  ZUSAMMENFASSUNG
══════════════════════════════════════════════════════════════

   ✅ Erfolgreich aktiviert: 5
   ❌ Fehlgeschlagen: 0

   🇩🇪 🇦🇹 🇨🇭 Nur DACH-Traffic erlaubt
   🔧 Modus: Nur PHP 📝
   ⏰ Gültig für 72 Stunden
══════════════════════════════════════════════════════════════

Blocking deaktivieren (einzelner Shop)

  1. Script starten: python3 geoip_shop_manager.py
  2. Option [2] GeoIP-Blocking 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
  • 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 Shops 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)
  • 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 🛡️
  [2] shop2.example.com 📝
  ...

Die Icons zeigen den Modus:

  • 🛡️ = PHP + CrowdSec
  • 📝 = Nur PHP

Option [0]: Gesamtübersicht aller Shops

Zeigt eine aggregierte Statistik über alle aktiven Shops mit Requests pro Minute und Bot-Erkennung:

══════════════════════════════════════════════════════════════════════
  📊 GESAMTÜBERSICHT ALLER SHOPS
══════════════════════════════════════════════════════════════════════

📝 PHP-Blocks gesamt: 173319 (⌀ 42.3 req/min, Laufzeit: 2d 20h 15m)
   ├─ air-suspension-parts.de: 19243 (8.2 req/min, seit 39h 12m) ████████████████
   ├─ gastro-shop-24.com: 20959 (12.1 req/min, seit 28h 45m) ████████████████████████
   ├─ horchakustik-shop.de: 29978 (15.3 req/min, seit 32h 38m) ██████████████████████████████
   ├─ leonessa.at: 12554 (5.8 req/min, seit 36h 05m) ███████████
   └─ verve-klima.de: 18412 (9.1 req/min, seit 33h 42m) ██████████████████

🛡️  CrowdSec-Bans gesamt: 892
   ├─ air-suspension-parts.de: 401 ████████████████
   ├─ gastro-shop-24.com: 298 ███████████
   └─ horchakustik-shop.de: 193 ███████

🔥 Top 100 blockierte IPs (alle Shops):
   66.249.66.10 (Googlebot): 7025 ████████████████████
   66.249.66.169 (Googlebot): 6179 ████████████████████
   40.77.167.27 (Bingbot): 571 ████████████████████
   173.0.81.65 (PayPal IPN): 466 ████████████████████
   216.244.66.196 (DotBot): 416 ████████████████████
   185.191.171.5 (SemrushBot): 312 ████████████████████
   35.187.50.162 (Unbekannt): 1035 ████████████████████
   ...

══════════════════════════════════════════════════════════════════════

Enthält:

  • PHP-Blocks gesamt mit durchschnittlicher Request-Rate und Gesamtlaufzeit
  • Pro Shop: Anzahl Blocks, req/min, Laufzeit seit Aktivierung, visueller Balken
  • CrowdSec-Bans pro Shop (nur für PHP+CrowdSec Shops)
  • Top 100 blockierte IPs mit automatischer Bot-Erkennung

Option [1-n]: Einzelner Shop

Zeigt detaillierte Logs für einen spezifischen Shop:

══════════════════════════════════════════════════════════════════════
📊 Logs für shop1.example.com [PHP + CrowdSec 🛡️]
══════════════════════════════════════════════════════════════════════

⏱️  Aktiviert: 2025-12-08 14:30:00
⏱️  Laufzeit: 1d 18h 45m
📈 Blocks: 19243 (8.2 req/min)

📝 Letzte 50 PHP-Blocks:
======================================================================
[2025-12-10 09:15:23] IP: 66.249.66.10 | UA: Mozilla/5.0 (compatible; Googlebot/2.1) | URI: /produkt-123
[2025-12-10 09:15:21] IP: 40.77.167.27 | UA: Mozilla/5.0 (compatible; bingbot/2.0) | URI: /kategorie
...
======================================================================
Gesamt: 19243

🔥 Top 20 blockierte IPs:
   66.249.66.10 (Googlebot): 2341 ████████████████████
   40.77.167.27 (Bingbot): 892 ████████████████████
   216.244.66.196 (DotBot): 234 ████████████████████
   185.191.171.5 (SemrushBot): 189 ████████████████████
   52.167.144.225 (Unbekannt): 156 ████████████████████
   ...

🛡️  CrowdSec Decisions:
======================================================================
Aktive Bans: 401

Letzte 20 Bans:
  🚫 202.8.43.232 (bis 2025-12-11 17:24:57)
  🚫 45.95.169.22 (bis 2025-12-11 16:30:12)
  ...
======================================================================

Bei PHP-only Shops wird stattdessen angezeigt:

📝 CrowdSec-Synchronisation ist für diesen Shop deaktiviert (PHP-only Modus)

Status prüfen

Option [4] Status anzeigen zeigt:

  • Anzahl verfügbarer Shops
  • Anzahl aktiver Blockings
  • Liste aller Shops mit aktivem Blocking, Modus, Blocks, req/min und Laufzeit
📊 Status:
  Shops gesamt: 15
  Aktive DACH-Blockings: 5
    ✓ shop1.example.com [PHP+CS] 🛡️ - 19243 blocks (8.2 req/min, 1d 18h 45m)
    ✓ shop2.example.com [PHP] 📝 - 12554 blocks (5.8 req/min, 2d 3h 12m)
    ✓ shop3.example.com [PHP] 📝 - 8921 blocks (4.1 req/min, 1d 12h 30m)
    ✓ shop4.example.com [PHP+CS] 🛡️ - 29978 blocks (15.3 req/min, 1d 8h 22m)
    ✓ shop5.example.com [PHP] 📝 - 3456 blocks (2.3 req/min, 1d 1h 05m)

🤖 Bot-Erkennung

Das Script erkennt automatisch über 80 verschiedene Bots und Crawler anhand des User-Agent-Strings. Die erkannten Bots werden in den Logs hinter der IP-Adresse angezeigt.

Erkannte Bot-Kategorien

Kategorie Bots
AI/LLM Crawler GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, Gemini-Deep-Research, cohere-ai, MistralAI-User, AI2Bot, CCBot
Suchmaschinen Googlebot, Bingbot, YandexBot, Baiduspider, DuckDuckBot, Applebot, PetalBot, Sogou, Qwantify
SEO-Tools AhrefsBot, SemrushBot, MJ12bot, DotBot, BLEXBot, DataForSeoBot, SEOkicks, Screaming Frog, Sistrix
Social Media FacebookBot, LinkedInBot, Twitterbot, Pinterest, Slackbot, TelegramBot, WhatsApp, Discordbot
Monitoring UptimeRobot, Pingdom, StatusCake, GTmetrix, Site24x7
E-Commerce PayPal IPN, Stripe, Shopify, Amazonbot
Andere Bytespider (TikTok), Diffbot, Wget, curl, python-requests, HeadlessChrome, Scrapy

Beispiel-Ausgabe mit Bot-Erkennung

🔥 Top 100 blockierte IPs (alle Shops):
   66.249.66.10 (Googlebot): 7025 ████████████████████
   40.77.167.27 (Bingbot): 571 ████████████████████
   173.0.81.65 (PayPal IPN): 466 ████████████████████
   216.244.66.196 (DotBot): 416 ████████████████████
   185.191.171.5 (SemrushBot): 312 ████████████████████
   54.36.148.0 (AhrefsBot): 289 ████████████████████
   35.187.50.162 (Unbekannt): 1035 ████████████████████

Wenn kein Bot erkannt wird, wird Unbekannt angezeigt.

🔧 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"

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
  • dach_ip_ranges.cache - Gecachte DACH IP-Ranges (erneuert alle 24h)
  • geoip_blocked.log - Log der PHP-Level Blocks
  • geoip_crowdsec_queue.log - Queue für CrowdSec-Synchronisation (nur PHP+CrowdSec Modus)

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 und Aktivierungszeit)

⚙️ 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

Und im PHP-Script Template:

# Zeile ~30-50
GEOIP_SCRIPT = '''<?php
// Auto-disable after 72 hours
$expiry_date = strtotime('{expiry_timestamp}');
'''

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-Erkennung erweitern

Um weitere Bots zur Erkennung hinzuzufügen, editiere das BOT_PATTERNS Dictionary im Python-Script:

BOT_PATTERNS = {
    # Existierende Patterns...
    'MeinNeuerBot': r'MeinNeuerBot',  # Regex-Pattern für User-Agent
}

🛡️ Sicherheit

Was wird geblockt?

  • Alle IPs außerhalb der DACH IP-Ranges (DE, AT, CH)
  • Auf PHP-Ebene: Sofortiger 403 Response
  • Auf Firewall-Ebene (nur PHP+CrowdSec): Alle Ports (HTTP, HTTPS, SSH, FTP, etc.)

Was wird NICHT geblockt?

  • Alle IPs aus Deutschland, Österreich und der Schweiz (basierend auf RIPE/ipdeny.com Daten)
  • Private IPs (192.168.x.x, 10.x.x.x, etc.)
  • Localhost (127.0.0.1)

Fehlblockierungen vermeiden

Das System nutzt die offiziellen IP-Zuweisungen von ipdeny.com:

  • Basiert auf RIPE-Daten
  • Täglich aktualisiert
  • Umfasst alle DACH-Provider (Telekom, Vodafone, A1, Swisscom, etc.)
  • Präzise CIDR-Prüfung

Risiko für Fehlblockierungen: Minimal

DACH-IPs können nur geblockt werden, wenn:

  1. Der Provider die IP-Range außerhalb der DACH-Region registriert hat (extrem selten)
  2. Die IP über einen ausländischen VPN/Proxy kommt
  3. Die ipdeny.com Daten veraltet sind (wird täglich aktualisiert)

🌐 CDN/Reverse-Proxy Hinweise

Problem bei CDN-Nutzung (Link11, Cloudflare, etc.)

Wenn dein Server hinter einem CDN oder Reverse-Proxy steht:

Client (202.8.43.232) → CDN (85.131.143.x) → Dein Server
                              ↓
                 iptables sieht nur CDN-IP!

Folge: CrowdSec Firewall-Bouncer kann die echte Client-IP nicht blocken, da er nur die CDN-IP sieht.

Lösung: PHP-only Modus

Das PHP-Script liest die echte IP aus dem X-Forwarded-For Header:

  • Funktioniert auch hinter CDN/Proxy
  • Blockt zuverlässig auf Anwendungsebene
  • Kein unnötiger CrowdSec-Overhead

Empfehlung für CDN-Nutzer: Wähle bei der Aktivierung den Modus [2] Nur PHP.

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

🐛 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

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 → 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
    

DACH-IPs werden geblockt

Sehr unwahrscheinlich! Aber falls doch:

# Prüfe welche IP-Ranges als DACH erkannt werden
cat /var/www/vhosts/SHOP/httpdocs/dach_ip_ranges.cache

# Lösche Cache (wird neu geladen)
rm /var/www/vhosts/SHOP/httpdocs/dach_ip_ranges.cache

# Prüfe ob IP in DACH-Ranges ist
php -r '
$ip = "91.107.229.191";
$ranges = unserialize(file_get_contents("/var/www/vhosts/SHOP/httpdocs/dach_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"

Migration von der alten DE-Only Version

Falls du von der alten Version (nur Deutschland) auf die DACH-Version wechselst:

# 1. Alle aktiven Shops deaktivieren (alte Version)
python3 geoip_shop_manager_old.py  # Option 2 für jeden Shop

# 2. Alte Cache-Dateien löschen
rm /var/www/vhosts/*/httpdocs/de_ip_ranges.cache

# 3. Neue Version verwenden
python3 geoip_shop_manager.py  # Shops wieder aktivieren

📊 Performance

PHP-Level Blocking

  • Overhead pro Request: ~2-8ms (bei gecachten IP-Ranges)
  • Erster Request: ~400-800ms (beim Download der IP-Ranges für 3 Länder)
  • Cache-Dauer: 24 Stunden
  • RAM-Verbrauch: ~5-10 MB pro Shop

CrowdSec Firewall Blocking (nur PHP+CrowdSec Modus)

  • Overhead: 0ms (blockt vor PHP)
  • RAM: ~20-50 MB (Watcher-Service)
  • Geblockte Pakete: Werden gar nicht erst an Apache weitergeleitet

Empfohlene Limits

  • 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://raw.githubusercontent.com/DEIN-REPO/geoip-shop-blocker/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/dach_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

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

🔐 Best Practices

Vor Aktivierung

  1. Backup erstellen (macht das Script automatisch)
  2. Sicherstellen, dass Admin-Zugriff aus DACH-Region kommt
  3. Modus wählen (PHP+CrowdSec für direkte Server, PHP-only für CDN)
  4. Test mit kurzer Dauer (kann im Script angepasst werden)
  5. Monitoring einrichten

Während aktivem Blocking

  1. Logs regelmäßig prüfen (Gesamtübersicht nutzen!)
  2. req/min beobachten - hohe Werte können auf Angriffe hindeuten
  3. Bot-Traffic analysieren - welche Crawler werden geblockt?
  4. Auf Fehlblockierungen achten (sehr selten)
  5. CrowdSec-Statistiken beobachten (nur bei PHP+CrowdSec)
  6. Server-Performance monitoren

Nach Deaktivierung

  1. Prüfen ob alle Decisions entfernt wurden (nur bei PHP+CrowdSec)
  2. Backup-Dateien können gelöscht werden (optional)
  3. Logs archivieren (falls benötigt)

⚠️ Wichtige Hinweise

Rechtliches

  • DSGVO: IP-Adressen werden nur temporär geloggt (72h)
  • Geoblocking: Kann gegen EU-Verordnungen verstoßen bei B2C-Geschäften
  • Haftung: Nur für technische Notfälle/DDoS-Abwehr empfohlen

Technisches

  • API-Calls: Bei vielen aktiven Shops könnten viele IPs in CrowdSec landen
  • CrowdSec-Limits: Kostenloser Tier hat API-Limits
  • Netzwerk: Kein Blocking möglich, wenn Server selbst unter DDoS steht
  • CDN: Bei CDN-Nutzung ist PHP-only Modus empfohlen

Empfehlungen

  • Nur temporär nutzen (Notfälle, Angriffe)
  • Nicht als permanente Lösung
  • Kombinieren mit anderen Security-Maßnahmen
  • Regelmäßig Logs prüfen (Gesamtübersicht für schnellen Überblick)
  • req/min im Auge behalten für Anomalie-Erkennung
  • Bei CDN: PHP-only Modus verwenden

🤝 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

📞 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 (PHP+CrowdSec oder PHP-only)

📚 Weitere Dokumentation


Version: 2.3.0 (DACH)
Letztes Update: Dezember 2025
Status: Production Ready
Erlaubte Länder: 🇩🇪 Deutschland | 🇦🇹 Österreich | 🇨🇭 Schweiz

Changelog

v2.3.0

  • NEU: Bot-Erkennung mit 80+ bekannten Bots/Crawlern (Googlebot, GPTBot, ClaudeBot, AhrefsBot, SemrushBot, etc.)
  • NEU: Requests pro Minute (req/min) Berechnung pro Shop
  • NEU: Laufzeit-Anzeige seit Aktivierung (z.B. "1d 18h 45m")
  • NEU: Erweiterte Status-Ansicht mit Blocks, req/min und Laufzeit
  • NEU: Top 20 IPs mit Bot-Erkennung in Einzelshop-Logs
  • Bot-Kategorien: AI/LLM, Suchmaschinen, SEO-Tools, Social Media, Monitoring, E-Commerce
  • Verbesserte Gesamtübersicht mit durchschnittlicher Request-Rate

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