14 KiB
GeoIP Shop Blocker Manager
Hybrid-System für temporäres GeoIP-Blocking auf Plesk-Servern mit mehreren Shops
Dieses Tool ermöglicht es, einzelne Shops auf einem Plesk-Server temporär für alle Zugriffe außerhalb Deutschlands zu sperren. Es kombiniert PHP-Level-Blocking mit CrowdSec Firewall-Integration für maximalen Schutz.
🎯 Features
- ✅ Präzises Blocking: PHP prüft gegen vollständige deutsche IP-Ranges (keine Fehlblockierungen)
- ✅ Doppelter Schutz: PHP-Level + Firewall-Level (CrowdSec)
- ✅ Automatische Synchronisation: Blockierte IPs werden automatisch an CrowdSec weitergegeben
- ✅ Multi-Shop-Management: Verwaltung mehrerer Shops auf einem Server
- ✅ 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
🏗️ Architektur
Komponente 1: PHP-Script
- Wird in die
index.phpdes Shops integriert - Lädt deutsche IP-Ranges von ipdeny.com
- Prüft jede Anfrage gegen diese Ranges
- Blockt Nicht-DE-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
📋 Voraussetzungen
- Betriebssystem: Ubuntu Server (getestet auf 24.04)
- Webserver: Apache mit mod_rewrite
- PHP: Version 8.0 oder höher
- Python: Version 3.8 oder höher
- CrowdSec: Installiert und aktiv
- CrowdSec Firewall Bouncer: Installiert und konfiguriert
- Plesk: Optional, aber empfohlen
- Root-Zugriff: Erforderlich für Installation und Verwaltung
CrowdSec Installation prüfen
# 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://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
Blocking aktivieren
- Script starten:
python3 geoip_shop_manager.py - Option
[1] GeoIP-Blocking AKTIVIERENwählen - Shop aus der Liste auswählen
- Bestätigen mit
ja
Was passiert:
- Bei ERSTEM Shop: Systemd-Service wird installiert und gestartet
- Backup der
index.phpwird erstellt geoip_blocking.phpwird erstellt und eingebunden- Shop wird für Tracking registriert
- Blocking ist sofort aktiv
Blocking deaktivieren
- Script starten:
python3 geoip_shop_manager.py - Option
[2] GeoIP-Blocking DEAKTIVIERENwählen - Shop aus der Liste auswählen
- Bestätigen mit
ja
Was passiert:
- Original
index.phpwird wiederhergestellt - Alle PHP-Dateien werden gelöscht
- Alle CrowdSec-Decisions werden entfernt
- Shop wird deregistriert
- Bei LETZTEM Shop: Systemd-Service wird deinstalliert
Logs anzeigen
- Script starten:
python3 geoip_shop_manager.py - Option
[3] Logs anzeigenwählen - Shop auswählen
Zeigt:
- PHP-Level Blocks (letzte 50 Einträge)
- CrowdSec Firewall Bans (letzte 20 mit Ablaufzeit)
- Gesamtstatistiken
Status prüfen
Option [4] Status anzeigen zeigt:
- Anzahl verfügbarer Shops
- Anzahl aktiver Blockings
- Liste aller Shops mit aktivem Blocking
🔧 Erweiterte Verwendung
Manuell CrowdSec Decisions prüfen
# Alle Decisions anzeigen
cscli decisions list
# Nur GeoIP-Blocks anzeigen
cscli decisions list | grep "GeoIP"
# Decisions für einen bestimmten Shop
cscli decisions list | grep "uhlig-kakteen.de"
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-Scriptde_ip_ranges.cache- Gecachte deutsche IP-Ranges (erneuert alle 24h)geoip_blocked.log- Log der PHP-Level Blocksgeoip_crowdsec_queue.log- Queue für CrowdSec-Synchronisation
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:
# 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
🛡️ Sicherheit
Was wird geblockt?
- ✅ Alle IPs außerhalb deutscher IP-Ranges
- ✅ Auf allen Ebenen: HTTP, HTTPS, SSH, FTP, SMTP, etc. (durch CrowdSec)
- ✅ Auch wenn sie den PHP-Check umgehen (Firewall blockt)
Was wird NICHT geblockt?
- ✅ Alle deutschen IPs (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 deutschen Provider (Telekom, Vodafone, O2, 1&1, etc.)
- Präzise CIDR-Prüfung
Risiko für Fehlblockierungen: Minimal
Deutsche IPs können nur geblockt werden, wenn:
- Der Provider die IP-Range außerhalb Deutschlands registriert hat (extrem selten)
- Die IP über einen ausländischen VPN/Proxy kommt
- Die ipdeny.com Daten veraltet sind (wird täglich aktualisiert)
🐛 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
# Prüfe ob Bouncer läuft
systemctl status crowdsec-firewall-bouncer
# Prüfe ob Bouncer registriert ist
cscli bouncers list
# Prüfe iptables-Regeln
iptables -L -n -v | grep crowdsec
# Prüfe ipset
ipset list crowdsec-blacklists-5 | head -20
Deutsche IPs werden geblockt
Sehr unwahrscheinlich! Aber falls doch:
# Prüfe welche IP-Ranges als deutsch erkannt werden
cat /var/www/vhosts/SHOP/httpdocs/de_ip_ranges.cache
# Lösche Cache (wird neu geladen)
rm /var/www/vhosts/SHOP/httpdocs/de_ip_ranges.cache
# Prüfe ob IP in deutschen Ranges ist
php -r '
$ip = "91.107.229.191";
$ranges = unserialize(file_get_contents("/var/www/vhosts/SHOP/httpdocs/de_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
cscli decisions list -o raw | grep "GeoIP" | cut -d',' -f3 | cut -d':' -f2 | while read ip; do
cscli decisions delete --ip "$ip" 2>/dev/null
done
# Prüfen
cscli decisions list | grep "GeoIP"
📊 Performance
PHP-Level Blocking
- Overhead pro Request: ~1-5ms (bei gecachten IP-Ranges)
- Erster Request: ~200-500ms (beim Download der IP-Ranges)
- Cache-Dauer: 24 Stunden
- RAM-Verbrauch: ~2-5 MB pro Shop
CrowdSec Firewall Blocking
- 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/de_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 | 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
- ✅ Backup erstellen (macht das Script automatisch)
- ✅ Sicherstellen, dass Admin-Zugriff aus Deutschland kommt
- ✅ Test mit kurzer Dauer (kann im Script angepasst werden)
- ✅ Monitoring einrichten
Während aktivem Blocking
- ✅ Logs regelmäßig prüfen
- ✅ Auf Fehlblockierungen achten (sehr selten)
- ✅ CrowdSec-Statistiken beobachten
- ✅ Server-Performance monitoren
Nach Deaktivierung
- ✅ Prüfen ob alle Decisions entfernt wurden
- ✅ 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
Empfehlungen
- ✅ Nur temporär nutzen (Notfälle, Angriffe)
- ✅ Nicht als permanente Lösung
- ✅ Kombinieren mit anderen Security-Maßnahmen
- ✅ Regelmäßig Logs prüfen
🤝 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
- Erstelle ein GitHub Issue mit:
- Fehlerbeschreibung
- Relevante Logs
- System-Infos (OS, PHP-Version, CrowdSec-Version)
📚 Weitere Dokumentation
Version: 1.0.0
Letztes Update: November 2025
Status: Production Ready ✅