diff --git a/geoip_shop_manager.py b/geoip_shop_manager.py index 8372456..79c50fc 100644 --- a/geoip_shop_manager.py +++ b/geoip_shop_manager.py @@ -450,40 +450,47 @@ def get_active_shops(): return active -def activate_blocking(shop): - """Activate GeoIP blocking""" +def activate_blocking(shop, silent=False): + """Activate GeoIP blocking for a single shop""" httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs') index_php = os.path.join(httpdocs, 'index.php') backup_php = os.path.join(httpdocs, f'index.php{BACKUP_SUFFIX}') blocking_file = os.path.join(httpdocs, BLOCKING_FILE) if os.path.isfile(backup_php): - print(f"⚠️ GeoIP-Blocking bereits aktiv für {shop}") + if not silent: + print(f"⚠️ GeoIP-Blocking bereits aktiv für {shop}") return False if not os.path.isfile(index_php): - print(f"❌ index.php nicht gefunden") + if not silent: + print(f"❌ index.php nicht gefunden") return False - print(f"\n🔧 Aktiviere DACH GeoIP-Blocking für: {shop}") - print(" (Erlaubt: Deutschland, Österreich, Schweiz)") - print("=" * 60) + if not silent: + print(f"\n🔧 Aktiviere DACH GeoIP-Blocking für: {shop}") + print(" (Erlaubt: Deutschland, Österreich, Schweiz)") + print("=" * 60) # Step 1: Install watcher service if not exists active_shops = get_active_shops() if not active_shops: # First shop - print("\n[1/3] Installiere CrowdSec-Watcher-Service...") + if not silent: + print("\n[1/3] Installiere CrowdSec-Watcher-Service...") if check_crowdsec(): install_watcher_service() else: - print(" ⚠️ CrowdSec nicht verfügbar - nur PHP-Blocking") + if not silent: + print(" ⚠️ CrowdSec nicht verfügbar - nur PHP-Blocking") else: - print("\n[1/3] CrowdSec-Watcher-Service bereits aktiv") + if not silent: + print("\n[1/3] CrowdSec-Watcher-Service bereits aktiv") # Step 2: PHP blocking - print("\n[2/3] Aktiviere PHP-Blocking...") + if not silent: + print("\n[2/3] Aktiviere PHP-Blocking...") + print(" 📋 Backup erstellen...") - print(" 📋 Backup erstellen...") shutil.copy2(index_php, backup_php) with open(index_php, 'r', encoding='utf-8') as f: @@ -505,7 +512,8 @@ def activate_blocking(shop): lines.insert(insert_line, require_statement) with open(index_php, 'w', encoding='utf-8') as f: f.write('\n'.join(lines)) - print(" ✏️ index.php modifiziert") + if not silent: + print(" ✏️ index.php modifiziert") expiry = datetime.now() + timedelta(hours=72) geoip_content = GEOIP_SCRIPT.format( @@ -519,27 +527,31 @@ def activate_blocking(shop): with open(blocking_file, 'w', encoding='utf-8') as f: f.write(geoip_content) - print(" 📝 geoip_blocking.php erstellt") + if not silent: + print(" 📝 geoip_blocking.php erstellt") # Step 3: Register shop - print("\n[3/3] Registriere Shop...") + if not silent: + print("\n[3/3] Registriere Shop...") add_shop_to_active(shop) - print(" ✅ Shop registriert") + if not silent: + print(" ✅ Shop registriert") - print("\n" + "=" * 60) - print(f"✅ DACH GeoIP-Blocking aktiviert für: {shop}") - print(f" Erlaubte Länder: 🇩🇪 DE | 🇦🇹 AT | 🇨🇭 CH") - print(f" Gültig bis: {expiry.strftime('%Y-%m-%d %H:%M:%S CET')}") - print(f" PHP-Log: {os.path.join(httpdocs, LOG_FILE)}") - print(f" CrowdSec-Queue: {os.path.join(httpdocs, CROWDSEC_QUEUE_FILE)}") - print(f"\n 🔄 Der Watcher-Service synchronisiert blockierte IPs zu CrowdSec") - print("=" * 60) + if not silent: + print("\n" + "=" * 60) + print(f"✅ DACH GeoIP-Blocking aktiviert für: {shop}") + print(f" Erlaubte Länder: 🇩🇪 DE | 🇦🇹 AT | 🇨🇭 CH") + print(f" Gültig bis: {expiry.strftime('%Y-%m-%d %H:%M:%S CET')}") + print(f" PHP-Log: {os.path.join(httpdocs, LOG_FILE)}") + print(f" CrowdSec-Queue: {os.path.join(httpdocs, CROWDSEC_QUEUE_FILE)}") + print(f"\n 🔄 Der Watcher-Service synchronisiert blockierte IPs zu CrowdSec") + print("=" * 60) return True -def deactivate_blocking(shop): - """Deactivate GeoIP blocking""" +def deactivate_blocking(shop, silent=False): + """Deactivate GeoIP blocking for a single shop""" httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs') index_php = os.path.join(httpdocs, 'index.php') backup_php = os.path.join(httpdocs, f'index.php{BACKUP_SUFFIX}') @@ -548,15 +560,18 @@ def deactivate_blocking(shop): log_file = os.path.join(httpdocs, LOG_FILE) queue_file = os.path.join(httpdocs, CROWDSEC_QUEUE_FILE) - print(f"\n🔧 Deaktiviere DACH GeoIP-Blocking für: {shop}") - print("=" * 60) + if not silent: + print(f"\n🔧 Deaktiviere DACH GeoIP-Blocking für: {shop}") + print("=" * 60) # Step 1: Remove PHP blocking - print("\n[1/4] PHP-Blocking entfernen...") + if not silent: + print("\n[1/4] PHP-Blocking entfernen...") if os.path.isfile(backup_php): shutil.move(backup_php, index_php) - print(" 📋 index.php wiederhergestellt") + if not silent: + print(" 📋 index.php wiederhergestellt") else: if os.path.isfile(index_php): with open(index_php, 'r') as f: @@ -568,36 +583,371 @@ def deactivate_blocking(shop): for f in [blocking_file, cache_file, log_file, queue_file]: if os.path.isfile(f): os.remove(f) - print(" 🗑️ PHP-Dateien gelöscht") + if not silent: + print(" 🗑️ PHP-Dateien gelöscht") # Step 2: Remove from tracking - print("\n[2/4] Deregistriere Shop...") + if not silent: + print("\n[2/4] Deregistriere Shop...") remove_shop_from_active(shop) - print(" ✅ Shop deregistriert") + if not silent: + print(" ✅ Shop deregistriert") # Step 3: Clean CrowdSec decisions - print("\n[3/4] CrowdSec-Decisions entfernen...") + if not silent: + print("\n[3/4] CrowdSec-Decisions entfernen...") if check_crowdsec(): cleanup_crowdsec_decisions(shop) # Step 4: Uninstall service if last shop - print("\n[4/4] Prüfe Watcher-Service...") + if not silent: + print("\n[4/4] Prüfe Watcher-Service...") remaining_shops = [s for s in get_active_shops() if s != shop] if not remaining_shops: - print(" ℹ️ Keine aktiven Shops mehr - deinstalliere Service") + if not silent: + print(" ℹ️ Keine aktiven Shops mehr - deinstalliere Service") uninstall_watcher_service() else: - print(f" ℹ️ Service bleibt aktiv ({len(remaining_shops)} Shop(s) noch aktiv)") + if not silent: + print(f" ℹ️ Service bleibt aktiv ({len(remaining_shops)} Shop(s) noch aktiv)") - print("\n" + "=" * 60) - print(f"✅ DACH GeoIP-Blocking deaktiviert für: {shop}") - print("=" * 60) + if not silent: + print("\n" + "=" * 60) + print(f"✅ DACH GeoIP-Blocking deaktiviert für: {shop}") + print("=" * 60) return True +def activate_all_shops(): + """Activate GeoIP blocking for all available shops""" + shops = get_available_shops() + active_shops = get_active_shops() + available_shops = [s for s in shops if s not in active_shops] + + if not available_shops: + print("\n⚠️ Keine Shops zum Aktivieren verfügbar") + print(" Alle Shops haben bereits aktives GeoIP-Blocking") + return + + print(f"\n{'=' * 60}") + print(f" DACH GeoIP-Blocking für ALLE Shops aktivieren") + print(f"{'=' * 60}") + print(f"\n📋 Folgende {len(available_shops)} Shop(s) werden aktiviert:\n") + + for shop in available_shops: + print(f" • {shop}") + + print(f"\n⚠️ Dies aktiviert den Schutz für alle oben genannten Shops!") + confirm = input(f"\nFortfahren? (ja/nein): ").strip().lower() + + if confirm not in ['ja', 'j', 'yes', 'y']: + print("\n❌ Abgebrochen") + return + + print(f"\n{'=' * 60}") + print(" Starte Aktivierung...") + print(f"{'=' * 60}") + + success_count = 0 + failed_count = 0 + failed_shops = [] + + # Install watcher service first if needed + if not active_shops and check_crowdsec(): + print("\n📦 Installiere CrowdSec-Watcher-Service...") + install_watcher_service() + + for i, shop in enumerate(available_shops, 1): + print(f"\n[{i}/{len(available_shops)}] Aktiviere: {shop}") + + try: + # Use silent mode but show progress + httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs') + index_php = os.path.join(httpdocs, 'index.php') + backup_php = os.path.join(httpdocs, f'index.php{BACKUP_SUFFIX}') + blocking_file = os.path.join(httpdocs, BLOCKING_FILE) + + if os.path.isfile(backup_php): + print(f" ⚠️ Bereits aktiv - überspringe") + continue + + if not os.path.isfile(index_php): + print(f" ❌ index.php nicht gefunden") + failed_count += 1 + failed_shops.append(shop) + continue + + # Create backup + shutil.copy2(index_php, backup_php) + + # Modify index.php + with open(index_php, 'r', encoding='utf-8') as f: + content = f.read() + + lines = content.split('\n') + insert_line = 0 + + for idx, line in enumerate(lines): + if 'declare(strict_types' in line: + insert_line = idx + 1 + break + elif ' 0 else "" + print(f" ├─ {shop}: {count} {bar}") + + # Display CrowdSec bans + print(f"\n🛡️ CrowdSec-Bans gesamt: {total_crowdsec}") + if crowdsec_stats: + for shop in sorted(crowdsec_stats.keys()): + count = crowdsec_stats[shop] + bar = "█" * min(count // 10, 20) if count > 0 else "" + print(f" ├─ {shop}: {count} {bar}") + elif check_crowdsec(): + print(" └─ Keine aktiven Bans") + else: + print(" └─ CrowdSec nicht verfügbar") + + # Top blocked IPs + if all_ips: + print(f"\n🔥 Top 10 blockierte IPs (alle Shops):") + sorted_ips = sorted(all_ips.items(), key=lambda x: x[1], reverse=True)[:10] + for ip, count in sorted_ips: + bar = "█" * min(count // 5, 20) if count > 0 else "█" + print(f" {ip}: {count} {bar}") + + print(f"\n{'═' * 60}") + + # Wait for user + input("\nDrücke Enter um fortzufahren...") + + def show_logs(shop): - """Show logs""" + """Show logs for a single shop""" httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs') log_file = os.path.join(httpdocs, LOG_FILE) @@ -677,10 +1027,15 @@ def main(): print(" ⚠️ Watcher-Service: Nicht aktiv") while True: - print("\n[1] GeoIP-Blocking AKTIVIEREN") - print("[2] GeoIP-Blocking DEAKTIVIEREN") + print("\n" + "-" * 40) + print("[1] GeoIP-Blocking AKTIVIEREN (einzeln)") + print("[2] GeoIP-Blocking DEAKTIVIEREN (einzeln)") print("[3] Logs anzeigen") print("[4] Status anzeigen") + print("-" * 40) + print("[5] 🚀 ALLE Shops aktivieren") + print("[6] 🛑 ALLE Shops deaktivieren") + print("-" * 40) print("[0] Beenden") choice = input("\nWähle eine Option: ").strip() @@ -741,17 +1096,22 @@ def main(): print("\n⚠️ Keine aktiven Shops") continue - print("\n📋 Shops mit Logs:") + print("\n📋 Logs anzeigen für:") + print(f" [0] 📊 ALLE Shops (Zusammenfassung)") for i, shop in enumerate(active_shops, 1): print(f" [{i}] {shop}") - shop_choice = input("\nWähle einen Shop: ").strip() + shop_choice = input("\nWähle eine Option: ").strip() try: - shop_idx = int(shop_choice) - 1 - if 0 <= shop_idx < len(active_shops): - show_logs(active_shops[shop_idx]) + shop_idx = int(shop_choice) + if shop_idx == 0: + show_all_logs() + elif 1 <= shop_idx <= len(active_shops): + show_logs(active_shops[shop_idx - 1]) + else: + print("❌ Ungültig") except ValueError: - pass + print("❌ Ungültig") elif choice == "4": shops = get_available_shops() @@ -763,6 +1123,12 @@ def main(): for shop in active_shops: print(f" ✓ {shop}") + elif choice == "5": + activate_all_shops() + + elif choice == "6": + deactivate_all_shops() + elif choice == "0": print("\n👋 Auf Wiedersehen!") break