Files
geoip_shop_manager/README.md
2025-12-04 17:08:42 +01:00

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

📋 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://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

  1. Script starten: python3 geoip_shop_manager.py
  2. Option [1] GeoIP-Blocking AKTIVIEREN wählen
  3. Shop aus der Liste auswählen
  4. Bestätigen mit ja

Was passiert:

  • 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

Blocking deaktivieren

  1. Script starten: python3 geoip_shop_manager.py
  2. Option [2] GeoIP-Blocking DEAKTIVIEREN wählen
  3. Shop aus der Liste auswählen
  4. Bestätigen mit ja

Was passiert:

  • Original index.php wird wiederhergestellt
  • Alle PHP-Dateien werden gelöscht
  • Alle CrowdSec-Decisions werden entfernt
  • Shop wird deregistriert
  • Bei LETZTEM Shop: Systemd-Service wird deinstalliert

Logs anzeigen

  1. Script starten: python3 geoip_shop_manager.py
  2. Option [3] Logs anzeigen wählen
  3. 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.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

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

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/

🛡️ Sicherheit

Was wird geblockt?

  • Alle IPs außerhalb der DACH IP-Ranges (DE, AT, CH)
  • 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 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)

🐛 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

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

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, etwas mehr als DE-only wegen mehr 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 (mehr Ranges als DE-only)

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/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 | 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. Test mit kurzer Dauer (kann im Script angepasst werden)
  4. Monitoring einrichten

Während aktivem Blocking

  1. Logs regelmäßig prüfen
  2. Auf Fehlblockierungen achten (sehr selten)
  3. CrowdSec-Statistiken beobachten
  4. Server-Performance monitoren

Nach Deaktivierung

  1. Prüfen ob alle Decisions entfernt wurden
  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

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:

  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
  3. Erstelle ein GitHub Issue mit:
    • Fehlerbeschreibung
    • Relevante Logs
    • System-Infos (OS, PHP-Version, CrowdSec-Version)

📚 Weitere Dokumentation


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