GeoIP Shop Blocker Manager - DACH & Eurozone Version

Hybrid-System für temporäres GeoIP-Blocking auf Plesk-Servern mit mehreren Shops

Dieses Tool ermöglicht es, einzelne oder alle Shops auf einem Plesk-Server temporär für alle Zugriffe außerhalb der konfigurierten Region zu sperren. Es kombiniert PHP-Level-Blocking mit optionaler CrowdSec Firewall-Integration für maximalen Schutz.

🎯 Features

  • Flexible Regionen: DACH (DE, AT, CH) oder Eurozone+GB (22 Länder)
  • Bot-Rate-Limiting: Bots unter Limit durchlassen, bei Überschreitung temporär bannen
  • Präzises Blocking: PHP prüft gegen vollständige IP-Ranges (keine Fehlblockierungen)
  • Flexibler Modus: 4 Modi - GeoIP+CrowdSec, GeoIP-only, Bot+CrowdSec, Bot-only
  • Doppelter Schutz: PHP-Level + Firewall-Level (CrowdSec) - optional
  • Automatische Synchronisation: Blockierte IPs werden automatisch an CrowdSec weitergegeben
  • Multi-Shop-Management: Verwaltung mehrerer Shops auf einem Server
  • Bulk-Operationen: Alle Shops gleichzeitig aktivieren/deaktivieren
  • Link11-Erkennung: Automatische Erkennung ob Shop hinter Link11 CDN steht
  • Nur direkte Shops: Option um nur Shops ohne CDN-Schutz zu aktivieren
  • Gesamtübersicht: Logs und Statistiken über alle Shops hinweg (Top 50 IPs)
  • Auto-Deaktivierung: Blocking läuft nach 72 Stunden automatisch ab
  • Systemd-Service: Automatischer Start beim Booten
  • Sauberes Cleanup: Vollständige Deinstallation bei Deaktivierung
  • Plesk-kompatibel: Funktioniert mit Plesk-verwalteten Shops
  • CDN-kompatibel: PHP-only Modus für Link11, Cloudflare & Co.
  • Fail-Open: Bei Cache-Fehlern wird Traffic durchgelassen (keine Ausfälle)

🏗️ Architektur

Modus 1: GeoIP + CrowdSec 🛡️

Komponente 1: PHP-Script

  • Wird in die index.php des Shops integriert
  • Lädt IP-Ranges von ipdeny.com (konfigurierte Länder)
  • Prüft jede Anfrage gegen diese Ranges
  • Blockt Nicht-erlaubte IPs sofort mit HTTP 403
  • Schreibt blockierte IPs in Queue-Datei für CrowdSec

Komponente 2: Python Watcher (systemd service)

  • Läuft permanent im Hintergrund als root
  • Überwacht Queue-Dateien aller aktiven Shops
  • Fügt blockierte IPs automatisch zu CrowdSec hinzu
  • Vermeidet Duplikate durch In-Memory-Cache
  • Prüft alle 5 Sekunden auf neue IPs

Komponente 3: CrowdSec Firewall Bouncer

  • Blockiert IPs auf Firewall-Ebene (iptables/nftables)
  • Schützt ALLE Services (HTTP, HTTPS, SSH, FTP, etc.)
  • Übernimmt Bans für 72 Stunden
  • Deutlich performanter als PHP-Checks

Modus 2: Nur GeoIP 📝

  • Nur das PHP-Script wird aktiviert
  • Keine CrowdSec-Synchronisation
  • Kein Watcher-Service nötig
  • Ideal für Server hinter CDN/Proxy (Link11, Cloudflare, etc.)

Modus 3: Bot-Rate-Limiting + CrowdSec 🤖🛡️

  • Shop bleibt weltweit erreichbar
  • Nur bekannte Bots werden rate-limited
  • Bots unter dem Limit werden durchgelassen
  • Bei Überschreitung: temporärer Ban + CrowdSec-Meldung

Modus 4: Nur Bot-Rate-Limiting 🤖

  • Shop bleibt weltweit erreichbar
  • Nur bekannte Bots werden rate-limited
  • Bots unter dem Limit werden durchgelassen
  • Keine CrowdSec-Synchronisation

Hinweis: Bei Servern hinter einem CDN/Reverse-Proxy (wie Link11, Cloudflare, Hetzner LB) sieht iptables nur die Proxy-IP, nicht die echte Client-IP. In diesem Fall ist der PHP-only Modus oder Bot-only Modus die bessere Wahl.

🚦 Rate-Limiting (Bot-Only Modus)

Funktionsweise

Das Rate-Limiting im Bot-Only Modus funktioniert wie folgt:

Bot-Request kommt rein
        │
        ▼
┌───────────────────┐
│ Ist IP+UA gebannt?│──── Ja ───▶ 403 + Exit (sofort)
└───────────────────┘
        │ Nein
        ▼
┌───────────────────┐
│ Bot erkannt?      │──── Nein ──▶ Weiter (normaler Traffic)
└───────────────────┘
        │ Ja
        ▼
┌───────────────────┐
│ Counter erhöhen   │
│ Limit erreicht?   │──── Ja ───▶ Ban erstellen + 403
└───────────────────┘
        │ Nein
        ▼
    Log + Weiter ✅
    (Bot darf durch!)

Wichtig: Bots werden nicht sofort geblockt! Sie dürfen crawlen, solange sie unter dem konfigurierten Limit bleiben. Erst bei Überschreitung werden sie temporär gebannt.

Konfiguration bei Aktivierung

Bei Aktivierung des Bot-Only Modus werden zwei Werte abgefragt:

🚦 Rate-Limit Konfiguration:
   Requests pro Minute bevor Ban [30]: 
   Ban-Dauer in Minuten [5]: 

   ✅ Rate-Limit: 30 req/min
   ✅ Ban-Dauer: 5 Minuten
  • Requests pro Minute: Wie viele Requests ein Bot pro Minute machen darf (Default: 30)
  • Ban-Dauer: Wie lange ein Bot nach Überschreitung gebannt wird (Default: 5 Minuten)

Technische Details

  • Identifier: MD5-Hash aus IP + User-Agent (ermöglicht granulare Tracking pro Bot-Typ)
  • Speicherung: File-basiert in geoip_ratelimit/ Verzeichnis
  • Cleanup: Probabilistisch (1% der Requests) um Overhead zu minimieren
  • Atomare Operationen: File-Locking verhindert Race Conditions

Verzeichnisstruktur

httpdocs/
├── geoip_ratelimit/
│   ├── bans/
│   │   └── {hash}.ban      # Unix-Timestamp wann Ban abläuft
│   └── counts/
│       └── {hash}.count    # Format: window_start|count

🤖 Erkannte Bot-Patterns

Das System erkennt über 30 verschiedene Bots:

Kategorie Bots
AI-Crawler GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, anthropic-ai, PerplexityBot
Suchmaschinen Googlebot, Google-Extended, AdsBot-Google, Bingbot, BingPreview, msnbot, DuckDuckBot, YandexBot, Baiduspider
SEO-Tools AhrefsBot, SemrushBot, MJ12bot, DotBot, DataForSeoBot
Social Media FacebookBot, LinkedInBot, Twitterbot, Slackbot
Andere Applebot, Amazonbot, Bytespider, PetalBot, UptimeRobot, Pingdom
CLI-Tools curl, python-requests, Wget, Scrapy

📋 Voraussetzungen

  • Betriebssystem: Ubuntu Server (getestet auf 24.04)
  • Webserver: Apache mit mod_rewrite (oder nginx)
  • PHP: Version 8.0 oder höher
  • Python: Version 3.8 oder höher
  • CrowdSec: Installiert und aktiv (nur für +CrowdSec Modi)
  • CrowdSec Firewall Bouncer: Installiert und konfiguriert (nur für +CrowdSec Modi)
  • Plesk: Optional, aber empfohlen
  • Root-Zugriff: Erforderlich für Installation und Verwaltung

CrowdSec Installation prüfen (nur für +CrowdSec Modi)

# Prüfe ob CrowdSec läuft
systemctl status crowdsec

# Prüfe ob Firewall Bouncer aktiv ist
cscli bouncers list

Falls CrowdSec noch nicht installiert ist:

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ü

============================================================
  GeoIP Shop Blocker Manager v3.4.3
  🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Rate-Limiting
  🛡️  Mit Cache-Validierung und Fail-Open
  🚦 Bots unter Rate-Limit werden durchgelassen
============================================================

[1] Aktivieren (einzeln)
[2] Deaktivieren (einzeln)
[3] Logs anzeigen
[4] Status
────────────────────────────────────────
[5] 🚀 ALLE aktivieren
[6] 🛑 ALLE deaktivieren
[7] 🎯 Nur DIREKTE aktivieren (ohne Link11)
────────────────────────────────────────
[0] Beenden

Modus-Auswahl

Bei jeder Aktivierung wird nach dem Modus gefragt:

🔧 Wähle den Blocking-Modus:
   [1] 🌍 GeoIP + CrowdSec (IPs werden an CrowdSec gemeldet)
   [2] 🌍 Nur GeoIP (keine CrowdSec-Synchronisation)
   [3] 🤖 Bot-Rate-Limiting (weltweit erreichbar, mit CrowdSec)
   [4] 🤖 Bot-Rate-Limiting (weltweit erreichbar, ohne CrowdSec)

Modus wählen [1/2/3/4]: 

Wann welchen Modus wählen?

Situation Empfohlener Modus
Server direkt im Internet, Geo-Blocking gewünscht GeoIP + CrowdSec 🛡️
Server hinter CDN, Geo-Blocking gewünscht Nur GeoIP 📝
Weltweit erreichbar bleiben, nur Bots bremsen Bot-Rate-Limiting 🤖
CrowdSec nicht installiert Nur GeoIP 📝 oder Bot-only 🤖

Geo-Region wählen (nur GeoIP-Modi)

🌍 Wähle die Geo-Region:
   [1] 🇩🇪🇦🇹🇨🇭 DACH - Deutschland, Österreich, Schweiz
   [2] 🇪🇺 Eurozone+GB - 22 Länder

Region wählen [1/2]: 

Beispielausgabe: Bot-Only Aktivierung

🔧 Aktiviere 🤖 Bot-Only für: shop.example.com
   Modus: Bot-Rate-Limiting (weltweit erreichbar)
   Rate-Limit: 30 req/min, Ban: 5 min
   CrowdSec: Nein
============================================================

[1/4] CrowdSec-Synchronisation deaktiviert

[2/4] Aktiviere PHP-Blocking...
  ✅ PHP-Blocking aktiviert

[3/4] Cache-Generierung nicht erforderlich (Bot-Only)

[4/4] Registriere Shop...

============================================================
✅ 🤖 Bot-Only aktiviert
   Shop: shop.example.com
   Modus: Nur Bot-Rate-Limit 🤖
   🤖 32 Bot-Patterns aktiv
   🚦 Rate-Limit: 30 req/min, Ban: 5 min
     Bots unter dem Limit werden durchgelassen
   Gültig bis: 2025-12-12 19:30:00 CET
============================================================

Logs anzeigen

Die Logs zeigen bei Bot-Only Modus auch die Rate-Limit Statistiken:

══════════════════════════════════════════════════════════════════════
📊 shop.example.com | 🤖 Bot-Only 🤖
══════════════════════════════════════════════════════════════════════
⏱️  Laufzeit: 2h 15m
📈 Log-Einträge: 1,234 (9.1 req/min)
🤖 Bot-Patterns: 32 aktiv
🚦 Rate-Limit: 30 req/min, Ban: 5 min
🚫 Bans: 23 ausgelöst, 3 aktiv

🤖 Bot-Statistik:
   Googlebot: 456x ███████████████████████████████████████
   Bingbot: 234x ███████████████████
   GPTBot: 189x ███████████████
   AhrefsBot: 123x ██████████
   ...

📝 Letzte 30 Log-Einträge:
[2025-12-09 19:45:23] BOT: Googlebot | IP: 66.249.66.1 | Count: 12/30 | URI: /produkt-123
[2025-12-09 19:45:24] BOT: Googlebot | IP: 66.249.66.1 | Count: 13/30 | URI: /kategorie-abc
[2025-12-09 19:45:25] BANNED: GPTBot | IP: 20.15.240.64 | Exceeded 30 req/min | Ban: 5m | UA: ...
...

Status anzeigen

📊 5/15 Shops aktiv
   shop1.example.com [Link11] 🇩🇪🇦🇹🇨🇭 🛡️
      523 blocks, 1h 41m, Cache: ✅8,234
   shop2.example.com [Direkt] 🤖 🤖
      1,234 log entries, 2h 15m, 32 Bot-Patterns, 30 req/min, 3 aktive Bans
   shop3.example.com [Direkt] 🇪🇺 📝
      312 blocks, 1h 39m, Cache: ✅12,456

🔧 Erweiterte Verwendung

Manuell CrowdSec Decisions prüfen

# Alle Decisions anzeigen
cscli decisions list --limit 0

# Nur GeoIP-Blocks anzeigen
cscli decisions list --limit 0 | grep "GeoIP"

Rate-Limit Dateien prüfen

# Aktive Bans anzeigen
find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/ -name "*.ban" -exec cat {} \;

# Request-Counter anzeigen
find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/counts/ -name "*.count" -exec cat {} \;

# Anzahl aktiver Bans
find /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/bans/ -name "*.ban" | wc -l

Systemd-Service verwalten

# Status des Watcher-Service
systemctl status geoip-crowdsec-watcher.service

# Logs des Watcher-Service
journalctl -u geoip-crowdsec-watcher.service -f

# Service neu starten
systemctl restart geoip-crowdsec-watcher.service

📁 Dateistruktur

Pro Shop (in /var/www/vhosts/SHOP/httpdocs/)

GeoIP-Modi:

  • index.php.geoip_backup - Backup der Original index.php
  • geoip_blocking.php - PHP-Blocking-Script
  • geoip_ip_ranges.cache - Gecachte IP-Ranges (erneuert alle 24h)
  • geoip_blocked.log - Log der Blocks
  • geoip_crowdsec_queue.log - Queue für CrowdSec (nur +CrowdSec Modi)

Bot-Only Modi (zusätzlich):

  • geoip_ratelimit/ - Rate-Limit Verzeichnis
    • bans/ - Aktive Bans (.ban Dateien)
    • counts/ - Request-Counter (.count Dateien)

System-weit

  • /usr/local/bin/geoip_crowdsec_watcher.py - Watcher-Service Script
  • /etc/systemd/system/geoip-crowdsec-watcher.service - Systemd Service
  • /var/lib/crowdsec/geoip_active_shops.json - Tracking aktiver Shops

⚙️ Konfiguration

Blocking-Dauer ändern

Standardmäßig 72 Stunden. Zum Ändern editiere das Python-Script:

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

Weitere Länder hinzufügen

Editiere GEO_REGIONS im Python-Script:

GEO_REGIONS = {
    "dach": {
        "countries": ["de", "at", "ch"],  # Hier Länder hinzufügen
        ...
    },
    ...
}

Link11-IP ändern

# Am Anfang des Scripts
LINK11_IP = "128.65.223.106"  # Hier ändern

🛡️ Sicherheit

Was wird geblockt?

GeoIP-Modi:

  • Alle IPs außerhalb der konfigurierten Region
  • Auf PHP-Ebene: Sofortiger 403 Response
  • Auf Firewall-Ebene (+CrowdSec): Alle Ports

Bot-Only Modi:

  • Erkannte Bots die das Rate-Limit überschreiten
  • Temporärer Ban (konfigurierbare Dauer)
  • Bots unter dem Limit werden durchgelassen (gewollt!)

Was wird NICHT geblockt?

  • Alle IPs aus den erlaubten Ländern (GeoIP-Modi)
  • Normaler User-Traffic (Bot-Only Modi)
  • Bots unter dem Rate-Limit (Bot-Only Modi)
  • Private IPs (192.168.x.x, 10.x.x.x, etc.)
  • Localhost (127.0.0.1)

🐛 Troubleshooting

Shop zeigt 500 Error

# Prüfe PHP-Fehler-Log
tail -50 /var/www/vhosts/SHOP/logs/error_log

# Stelle Original-Index wieder her
cd /var/www/vhosts/SHOP/httpdocs
mv index.php.geoip_backup index.php

Rate-Limit funktioniert nicht

# Prüfe Verzeichnis-Berechtigungen
ls -la /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/

# Sollte 777 sein (PHP läuft als anderer User)
# Falls nicht:
chmod -R 777 /var/www/vhosts/SHOP/httpdocs/geoip_ratelimit/

Bots werden sofort geblockt (nicht rate-limited)

Prüfe ob du die aktuelle Version (v3.4.3+) verwendest!

In älteren Versionen wurden Bots sofort geblockt. Ab v3.4.3 werden Bots unter dem Limit durchgelassen.

# Version prüfen
grep "v3.4" geoip_shop_manager.py

# Update durchführen
wget -O geoip_shop_manager.py https://git.jtl-hosting.de/...

# Shops neu aktivieren (deaktivieren + aktivieren)
# damit das neue PHP-Template angewendet wird

Watcher-Service läuft nicht

# Status prüfen
systemctl status geoip-crowdsec-watcher.service

# Logs prüfen
journalctl -u geoip-crowdsec-watcher.service -n 100

# Service neu starten
systemctl restart geoip-crowdsec-watcher.service

Rate-Limit Verzeichnisse sind leer trotz Bot-Traffic

Berechtigungsproblem! Das Python-Script läuft als root, aber PHP läuft als Domain-User.

# Quick-Fix für alle Shops:
for dir in /var/www/vhosts/*/httpdocs/geoip_ratelimit; do
    [ -d "$dir" ] && chmod -R 777 "$dir" && echo "Fixed: $dir"
done

Ab v3.4.2 werden die Verzeichnisse automatisch mit 777 erstellt.

📊 Performance

PHP-Level Blocking (GeoIP)

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

Bot-Rate-Limiting

  • Overhead pro Request: ~1-3ms (File-I/O)
  • Ban-Check: ~0.5ms (schneller Pfad)
  • Cleanup: Probabilistisch (1% der Requests)

CrowdSec Firewall Blocking

  • Overhead: 0ms (blockt vor PHP)
  • RAM: ~20-50 MB (Watcher-Service)

📝 Logs und Monitoring

PHP-Level Logs

# Blockierte IPs/Bots für einen Shop
tail -f /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log

# Nur BANNED Einträge (Rate-Limit überschritten)
grep "BANNED:" /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log

# Nur BOT Einträge (unter Limit, durchgelassen)
grep "BOT:" /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log

Bot-Statistik erstellen

# Top 10 Bots (aus Log)
grep -oP '(BOT|BANNED): \K[^|]+' /var/www/vhosts/SHOP/httpdocs/geoip_blocked.log | \
    sed 's/ //g' | sort | uniq -c | sort -rn | head -10

📚 Changelog

v3.4.3

  • FIX: Rate-Limit Logik korrigiert - Bots unter dem Limit werden jetzt durchgelassen
  • Vorher: Alle erkannten Bots wurden sofort mit 403 geblockt
  • Nachher: Bots dürfen crawlen bis sie das Limit überschreiten, dann temporärer Ban
  • PHP-Templates aktualisiert mit korrektem Flowchart

v3.4.2

  • FIX: Verzeichnis-Berechtigungen für Rate-Limit (0o777 statt 0o755)
  • PHP läuft als Domain-User, nicht als root
  • Explizite os.chmod() Aufrufe nach os.makedirs()

v3.4.1

  • FIX: Bot-Namen werden jetzt korrekt in Statistiken angezeigt
  • Bot-Name wird direkt aus Log extrahiert (BOT: / BANNED: Prefix)
  • Fallback auf User-Agent Detection wenn nötig

v3.4.0

  • NEU: File-basiertes Rate-Limiting für Bot-Only Modus
  • NEU: Konfigurierbare Rate-Limits (Requests/Minute, Ban-Dauer)
  • NEU: Sliding Window Counter Algorithmus
  • NEU: Probabilistisches Cleanup (1% der Requests)
  • NEU: Ban-Check als schneller Pfad (vor Bot-Detection)

v3.3.0

  • NEU: Option [7] - Nur direkte Shops aktivieren (ohne Link11)
  • NEU: Automatische Link11-Erkennung per DNS-Lookup
  • NEU: Farbcodierung im Menü (Grün = Link11, Rot = Direkt)

v3.2.0

  • NEU: Bot-Only Blocking Modus (weltweit erreichbar, nur Bots blocken)
  • NEU: 4 Blocking-Modi: GeoIP+CrowdSec, GeoIP-only, Bot+CrowdSec, Bot-only
  • NEU: 30+ Bot-Patterns (GPTBot, ClaudeBot, Googlebot, etc.)

v3.1.0

  • NEU: Eurozone+GB Region (22 Länder)
  • NEU: Cache-Validierung mit Mindest-Range-Prüfung
  • NEU: Fail-Open Mechanismus bei Cache-Fehlern

v3.0.0

  • NEU: DACH-Support (DE, AT, CH)
  • Systemd-Service für Watcher
  • CrowdSec-Integration
  • Multi-Shop-Management

Version: 3.4.3
Letztes Update: Dezember 2025
Status: Production Ready
Erlaubte Regionen: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Only (weltweit)

Description
Sperrt temporär alle Länder aus. Außer Deutschland, um Botangriffe etc temporär zu verhindern bis Shop hinter Link11 ist.
Readme 603 KiB
Languages
Python 100%