From 6a253ad01d86ba2f3619eeb5f272f04f31bac9db Mon Sep 17 00:00:00 2001 From: thomasciesla Date: Tue, 9 Dec 2025 10:37:27 +0100 Subject: [PATCH] geoip_shop_manager.py aktualisiert --- geoip_shop_manager.py | 340 +++++++++++++++++++++++++++++------------- 1 file changed, 237 insertions(+), 103 deletions(-) diff --git a/geoip_shop_manager.py b/geoip_shop_manager.py index a8acc14..e6abd6a 100644 --- a/geoip_shop_manager.py +++ b/geoip_shop_manager.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 """ -GeoIP Shop Blocker Manager - DACH Version +GeoIP Shop Blocker Manager - DACH & Eurozone Version 2-Component System: PHP blocking + Python watcher (systemd service) -Blocks all IPs outside Germany, Austria, and Switzerland (DACH region) +Supports two geo regions: + - DACH: Germany, Austria, Switzerland (3 countries) + - Eurozone+GB: All Eurozone countries + GB + CH (22 countries) """ import os @@ -20,6 +22,7 @@ from pathlib import Path COLOR_GREEN = "\033[92m" COLOR_RED = "\033[91m" COLOR_YELLOW = "\033[93m" +COLOR_BLUE = "\033[94m" COLOR_RESET = "\033[0m" COLOR_BOLD = "\033[1m" @@ -33,13 +36,56 @@ DNS_CACHE = {} VHOSTS_DIR = "/var/www/vhosts" BACKUP_SUFFIX = ".geoip_backup" BLOCKING_FILE = "geoip_blocking.php" -CACHE_FILE = "dach_ip_ranges.cache" +CACHE_FILE = "geoip_ip_ranges.cache" LOG_FILE = "geoip_blocked.log" CROWDSEC_QUEUE_FILE = "geoip_crowdsec_queue.log" WATCHER_SCRIPT = "/usr/local/bin/geoip_crowdsec_watcher.py" SYSTEMD_SERVICE = "/etc/systemd/system/geoip-crowdsec-watcher.service" ACTIVE_SHOPS_FILE = "/var/lib/crowdsec/geoip_active_shops.json" +# ============================================================================= +# GEO REGIONS +# ============================================================================= +GEO_REGIONS = { + "dach": { + "name": "DACH", + "countries": ["de", "at", "ch"], + "description": "Deutschland, Österreich, Schweiz", + "icon": "🇩🇪🇦🇹🇨🇭", + "short": "DACH" + }, + "eurozone": { + "name": "Eurozone + GB", + "countries": [ + "de", # Deutschland + "at", # Österreich + "ch", # Schweiz + "be", # Belgien + "cy", # Zypern + "ee", # Estland + "es", # Spanien + "fi", # Finnland + "fr", # Frankreich + "gb", # Großbritannien + "gr", # Griechenland + "hr", # Kroatien + "ie", # Irland + "it", # Italien + "lt", # Litauen + "lu", # Luxemburg + "lv", # Lettland + "mt", # Malta + "nl", # Niederlande + "pt", # Portugal + "si", # Slowenien + "sk", # Slowakei + ], + "description": "22 Länder: DE, AT, CH, BE, CY, EE, ES, FI, FR, GB, GR, HR, IE, IT, LT, LU, LV, MT, NL, PT, SI, SK", + "icon": "🇪🇺", + "short": "EU+" + } +} + # ============================================================================= # BOT DETECTION - Comprehensive list of known bots/crawlers # ============================================================================= @@ -221,11 +267,23 @@ def format_shop_with_link11(shop, prefix="", show_index=None): return f"{prefix}{color}{shop}{suffix}{COLOR_RESET}" -# PHP GeoIP blocking script (no exec, just logging) -GEOIP_SCRIPT = ''' 0 else "" runtime_str = format_duration(runtime) if runtime > 0 else "?" + # Get geo region icon + geo_region = get_shop_geo_region(shop) + region_info = get_geo_region_info(geo_region) + geo_icon = region_info['icon'] + # Color shop name based on Link11 status link11_info = check_link11(shop) if link11_info['is_link11']: @@ -1411,7 +1536,7 @@ def show_all_logs(): else: shop_colored = f"{COLOR_RED}{shop}{COLOR_RESET}" - print(f" ├─ {shop_colored}: {count} ({req_min:.1f} req/min, seit {runtime_str}) {bar}") + print(f" ├─ {shop_colored} {geo_icon}: {count} ({req_min:.1f} req/min, seit {runtime_str}) {bar}") # Show top IP for this shop shop_ips = stats['ips'] @@ -1438,6 +1563,11 @@ def show_all_logs(): count = crowdsec_stats[shop] bar = "█" * min(count // 10, 20) if count > 0 else "" + # Get geo region icon + geo_region = get_shop_geo_region(shop) + region_info = get_geo_region_info(geo_region) + geo_icon = region_info['icon'] + # Color shop name based on Link11 status link11_info = check_link11(shop) if link11_info['is_link11']: @@ -1445,7 +1575,7 @@ def show_all_logs(): else: shop_colored = f"{COLOR_RED}{shop}{COLOR_RESET}" - print(f" ├─ {shop_colored}: {count} {bar}") + print(f" ├─ {shop_colored} {geo_icon}: {count} {bar}") elif check_crowdsec(): print(" └─ Keine aktiven Bans") else: @@ -1507,6 +1637,8 @@ def show_logs(shop): httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs') log_file = os.path.join(httpdocs, LOG_FILE) shop_mode = get_shop_mode(shop) + shop_geo = get_shop_geo_region(shop) + region_info = get_geo_region_info(shop_geo) # Get stats blocks, ips, activation_time = get_shop_log_stats(shop) @@ -1526,7 +1658,8 @@ def show_logs(shop): mode_display = "PHP + CrowdSec 🛡️" if shop_mode == "php+crowdsec" else "Nur PHP 📝" print(f"\n{'═' * 70}") - print(f"📊 Logs für {shop} [{mode_display}]") + print(f"📊 Logs für {shop}") + print(f" {region_info['icon']} {region_info['name']} | {mode_display}") print(f"{'═' * 70}") print(f"\n⏱️ Aktiviert: {activation_str}") print(f"⏱️ Laufzeit: {runtime_str}") @@ -1613,8 +1746,8 @@ def show_logs(shop): def main(): """Main menu""" print("\n" + "=" * 60) - print(" GeoIP Shop Blocker Manager - DACH Version") - print(" Erlaubt: 🇩🇪 Deutschland | 🇦🇹 Österreich | 🇨🇭 Schweiz") + print(" GeoIP Shop Blocker Manager") + print(" Regionen: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB (22 Länder)") print(" PHP + CrowdSec Watcher (systemd service)") print("=" * 60) @@ -1664,22 +1797,17 @@ def main(): if 0 <= shop_idx < len(available_shops): selected_shop = available_shops[shop_idx] + # Ask for geo region + geo_region = select_geo_region() + region_info = get_geo_region_info(geo_region) + # Ask for mode - print(f"\n🔧 Wähle den Blocking-Modus:") - print(f" [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet)") - print(f" [2] Nur PHP (keine CrowdSec-Synchronisation)") - mode_choice = input(f"\nModus wählen [1/2]: ").strip() + mode = select_mode() + mode_display = "PHP + CrowdSec" if mode == "php+crowdsec" else "Nur PHP" - if mode_choice == "2": - mode = "php-only" - mode_display = "Nur PHP" - else: - mode = "php+crowdsec" - mode_display = "PHP + CrowdSec" - - confirm = input(f"\n⚠️ DACH-Blocking ({mode_display}) aktivieren für '{selected_shop}'? (ja/nein): ").strip().lower() + confirm = input(f"\n⚠️ {region_info['icon']} {region_info['name']}-Blocking ({mode_display}) aktivieren für '{selected_shop}'? (ja/nein): ").strip().lower() if confirm in ['ja', 'j', 'yes', 'y']: - activate_blocking(selected_shop, mode=mode) + activate_blocking(selected_shop, mode=mode, geo_region=geo_region) else: print("❌ Ungültig") except ValueError: @@ -1696,11 +1824,13 @@ def main(): print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}") for i, shop in enumerate(active_shops, 1): mode = get_shop_mode(shop) + geo_region = get_shop_geo_region(shop) + region_info = get_geo_region_info(geo_region) mode_icon = "🛡️" if mode == "php+crowdsec" else "📝" link11_info = check_link11(shop) color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]" - print(f" [{i}] {color}{shop} {link11_tag}{COLOR_RESET} {mode_icon}") + print(f" [{i}] {color}{shop} {link11_tag}{COLOR_RESET} {region_info['icon']} {mode_icon}") shop_choice = input("\nWähle einen Shop: ").strip() try: @@ -1726,11 +1856,13 @@ def main(): print(f" [0] 📊 ALLE Shops (Zusammenfassung)") for i, shop in enumerate(active_shops, 1): mode = get_shop_mode(shop) + geo_region = get_shop_geo_region(shop) + region_info = get_geo_region_info(geo_region) mode_icon = "🛡️" if mode == "php+crowdsec" else "📝" link11_info = check_link11(shop) color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]" - print(f" [{i}] {color}{shop} {link11_tag}{COLOR_RESET} {mode_icon}") + print(f" [{i}] {color}{shop} {link11_tag}{COLOR_RESET} {region_info['icon']} {mode_icon}") shop_choice = input("\nWähle eine Option: ").strip() try: @@ -1749,11 +1881,13 @@ def main(): active_shops = get_active_shops() print(f"\n📊 Status:") print(f" Shops gesamt: {len(shops)}") - print(f" Aktive DACH-Blockings: {len(active_shops)}") + print(f" Aktive GeoIP-Blockings: {len(active_shops)}") print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}") if active_shops: for shop in active_shops: mode = get_shop_mode(shop) + geo_region = get_shop_geo_region(shop) + region_info = get_geo_region_info(geo_region) mode_icon = "🛡️" if mode == "php+crowdsec" else "📝" mode_text = "PHP+CS" if mode == "php+crowdsec" else "PHP" @@ -1772,7 +1906,7 @@ def main(): color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]" - print(f" ✓ {color}{shop} {link11_tag}{COLOR_RESET} [{mode_text}] {mode_icon} - {blocks} blocks ({req_min:.1f} req/min, {runtime_str})") + print(f" ✓ {color}{shop} {link11_tag}{COLOR_RESET} {region_info['icon']} [{mode_text}] {mode_icon} - {blocks} blocks ({req_min:.1f} req/min, {runtime_str})") elif choice == "5": activate_all_shops()