geoip_shop_manager.py aktualisiert
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
#!/usr/bin/env python3
|
#!/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)
|
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
|
import os
|
||||||
@@ -20,6 +22,7 @@ from pathlib import Path
|
|||||||
COLOR_GREEN = "\033[92m"
|
COLOR_GREEN = "\033[92m"
|
||||||
COLOR_RED = "\033[91m"
|
COLOR_RED = "\033[91m"
|
||||||
COLOR_YELLOW = "\033[93m"
|
COLOR_YELLOW = "\033[93m"
|
||||||
|
COLOR_BLUE = "\033[94m"
|
||||||
COLOR_RESET = "\033[0m"
|
COLOR_RESET = "\033[0m"
|
||||||
COLOR_BOLD = "\033[1m"
|
COLOR_BOLD = "\033[1m"
|
||||||
|
|
||||||
@@ -33,13 +36,56 @@ DNS_CACHE = {}
|
|||||||
VHOSTS_DIR = "/var/www/vhosts"
|
VHOSTS_DIR = "/var/www/vhosts"
|
||||||
BACKUP_SUFFIX = ".geoip_backup"
|
BACKUP_SUFFIX = ".geoip_backup"
|
||||||
BLOCKING_FILE = "geoip_blocking.php"
|
BLOCKING_FILE = "geoip_blocking.php"
|
||||||
CACHE_FILE = "dach_ip_ranges.cache"
|
CACHE_FILE = "geoip_ip_ranges.cache"
|
||||||
LOG_FILE = "geoip_blocked.log"
|
LOG_FILE = "geoip_blocked.log"
|
||||||
CROWDSEC_QUEUE_FILE = "geoip_crowdsec_queue.log"
|
CROWDSEC_QUEUE_FILE = "geoip_crowdsec_queue.log"
|
||||||
WATCHER_SCRIPT = "/usr/local/bin/geoip_crowdsec_watcher.py"
|
WATCHER_SCRIPT = "/usr/local/bin/geoip_crowdsec_watcher.py"
|
||||||
SYSTEMD_SERVICE = "/etc/systemd/system/geoip-crowdsec-watcher.service"
|
SYSTEMD_SERVICE = "/etc/systemd/system/geoip-crowdsec-watcher.service"
|
||||||
ACTIVE_SHOPS_FILE = "/var/lib/crowdsec/geoip_active_shops.json"
|
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
|
# 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}"
|
return f"{prefix}{color}{shop}{suffix}{COLOR_RESET}"
|
||||||
|
|
||||||
|
|
||||||
# PHP GeoIP blocking script (no exec, just logging)
|
def get_geo_region_info(geo_region):
|
||||||
GEOIP_SCRIPT = '''<?php
|
"""Get info for a geo region"""
|
||||||
|
return GEO_REGIONS.get(geo_region, GEO_REGIONS["dach"])
|
||||||
|
|
||||||
|
|
||||||
|
def generate_php_countries_array(geo_region):
|
||||||
|
"""Generate PHP array string for countries"""
|
||||||
|
region_info = get_geo_region_info(geo_region)
|
||||||
|
countries = region_info["countries"]
|
||||||
|
return ", ".join([f"'{c}'" for c in countries])
|
||||||
|
|
||||||
|
|
||||||
|
# PHP GeoIP blocking script template (with CrowdSec)
|
||||||
|
GEOIP_SCRIPT_TEMPLATE = '''<?php
|
||||||
/**
|
/**
|
||||||
* GeoIP Blocking Script - Blocks all non-DACH IPs
|
* GeoIP Blocking Script - Blocks all IPs outside allowed region
|
||||||
* DACH = Germany (DE), Austria (AT), Switzerland (CH)
|
* Region: {region_name} ({region_description})
|
||||||
* Logs blocked IPs for CrowdSec watcher to process
|
* Logs blocked IPs for CrowdSec watcher to process
|
||||||
* Valid until: {expiry_date}
|
* Valid until: {expiry_date}
|
||||||
*/
|
*/
|
||||||
@@ -253,10 +311,12 @@ $cache_duration = 86400; // 24 hours
|
|||||||
$log_file = __DIR__ . '/{log_file}';
|
$log_file = __DIR__ . '/{log_file}';
|
||||||
$crowdsec_queue = __DIR__ . '/{crowdsec_queue}';
|
$crowdsec_queue = __DIR__ . '/{crowdsec_queue}';
|
||||||
|
|
||||||
// Function to download DACH IP ranges (Germany, Austria, Switzerland)
|
// Allowed countries
|
||||||
function download_dach_ranges() {{
|
$allowed_countries = [{countries_array}];
|
||||||
|
|
||||||
|
// Function to download IP ranges for allowed countries
|
||||||
|
function download_allowed_ranges($countries) {{
|
||||||
$ranges = [];
|
$ranges = [];
|
||||||
$countries = ['de', 'at', 'ch']; // Germany, Austria, Switzerland
|
|
||||||
|
|
||||||
foreach ($countries as $country) {{
|
foreach ($countries as $country) {{
|
||||||
$url = "https://www.ipdeny.com/ipblocks/data/aggregated/$country-aggregated.zone";
|
$url = "https://www.ipdeny.com/ipblocks/data/aggregated/$country-aggregated.zone";
|
||||||
@@ -286,27 +346,27 @@ function ip_in_range($ip, $cidr) {{
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
// Load or download IP ranges
|
// Load or download IP ranges
|
||||||
$dach_ranges = [];
|
$allowed_ranges = [];
|
||||||
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $cache_duration) {{
|
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $cache_duration) {{
|
||||||
$dach_ranges = unserialize(file_get_contents($cache_file));
|
$allowed_ranges = unserialize(file_get_contents($cache_file));
|
||||||
}} else {{
|
}} else {{
|
||||||
$dach_ranges = download_dach_ranges();
|
$allowed_ranges = download_allowed_ranges($allowed_countries);
|
||||||
if (!empty($dach_ranges)) {{
|
if (!empty($allowed_ranges)) {{
|
||||||
@file_put_contents($cache_file, serialize($dach_ranges));
|
@file_put_contents($cache_file, serialize($allowed_ranges));
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Check if visitor IP is from DACH region
|
// Check if visitor IP is from allowed region
|
||||||
$is_dach = false;
|
$is_allowed = false;
|
||||||
foreach ($dach_ranges as $range) {{
|
foreach ($allowed_ranges as $range) {{
|
||||||
if (ip_in_range($visitor_ip, $range)) {{
|
if (ip_in_range($visitor_ip, $range)) {{
|
||||||
$is_dach = true;
|
$is_allowed = true;
|
||||||
break;
|
break;
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Block non-DACH IPs
|
// Block non-allowed IPs
|
||||||
if (!$is_dach) {{
|
if (!$is_allowed) {{
|
||||||
$timestamp = date('Y-m-d H:i:s');
|
$timestamp = date('Y-m-d H:i:s');
|
||||||
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
|
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
|
||||||
$request_uri = $_SERVER['REQUEST_URI'] ?? '/';
|
$request_uri = $_SERVER['REQUEST_URI'] ?? '/';
|
||||||
@@ -324,11 +384,11 @@ if (!$is_dach) {{
|
|||||||
}}
|
}}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# PHP GeoIP blocking script - PHP ONLY (no CrowdSec queue)
|
# PHP GeoIP blocking script template - PHP ONLY (no CrowdSec queue)
|
||||||
GEOIP_SCRIPT_PHP_ONLY = '''<?php
|
GEOIP_SCRIPT_TEMPLATE_PHP_ONLY = '''<?php
|
||||||
/**
|
/**
|
||||||
* GeoIP Blocking Script - Blocks all non-DACH IPs (PHP-only mode)
|
* GeoIP Blocking Script - Blocks all IPs outside allowed region (PHP-only mode)
|
||||||
* DACH = Germany (DE), Austria (AT), Switzerland (CH)
|
* Region: {region_name} ({region_description})
|
||||||
* Logs blocked IPs (no CrowdSec synchronisation)
|
* Logs blocked IPs (no CrowdSec synchronisation)
|
||||||
* Valid until: {expiry_date}
|
* Valid until: {expiry_date}
|
||||||
*/
|
*/
|
||||||
@@ -355,10 +415,12 @@ $cache_file = __DIR__ . '/{cache_file}';
|
|||||||
$cache_duration = 86400; // 24 hours
|
$cache_duration = 86400; // 24 hours
|
||||||
$log_file = __DIR__ . '/{log_file}';
|
$log_file = __DIR__ . '/{log_file}';
|
||||||
|
|
||||||
// Function to download DACH IP ranges (Germany, Austria, Switzerland)
|
// Allowed countries
|
||||||
function download_dach_ranges() {{
|
$allowed_countries = [{countries_array}];
|
||||||
|
|
||||||
|
// Function to download IP ranges for allowed countries
|
||||||
|
function download_allowed_ranges($countries) {{
|
||||||
$ranges = [];
|
$ranges = [];
|
||||||
$countries = ['de', 'at', 'ch']; // Germany, Austria, Switzerland
|
|
||||||
|
|
||||||
foreach ($countries as $country) {{
|
foreach ($countries as $country) {{
|
||||||
$url = "https://www.ipdeny.com/ipblocks/data/aggregated/$country-aggregated.zone";
|
$url = "https://www.ipdeny.com/ipblocks/data/aggregated/$country-aggregated.zone";
|
||||||
@@ -388,27 +450,27 @@ function ip_in_range($ip, $cidr) {{
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
// Load or download IP ranges
|
// Load or download IP ranges
|
||||||
$dach_ranges = [];
|
$allowed_ranges = [];
|
||||||
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $cache_duration) {{
|
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $cache_duration) {{
|
||||||
$dach_ranges = unserialize(file_get_contents($cache_file));
|
$allowed_ranges = unserialize(file_get_contents($cache_file));
|
||||||
}} else {{
|
}} else {{
|
||||||
$dach_ranges = download_dach_ranges();
|
$allowed_ranges = download_allowed_ranges($allowed_countries);
|
||||||
if (!empty($dach_ranges)) {{
|
if (!empty($allowed_ranges)) {{
|
||||||
@file_put_contents($cache_file, serialize($dach_ranges));
|
@file_put_contents($cache_file, serialize($allowed_ranges));
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Check if visitor IP is from DACH region
|
// Check if visitor IP is from allowed region
|
||||||
$is_dach = false;
|
$is_allowed = false;
|
||||||
foreach ($dach_ranges as $range) {{
|
foreach ($allowed_ranges as $range) {{
|
||||||
if (ip_in_range($visitor_ip, $range)) {{
|
if (ip_in_range($visitor_ip, $range)) {{
|
||||||
$is_dach = true;
|
$is_allowed = true;
|
||||||
break;
|
break;
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Block non-DACH IPs
|
// Block non-allowed IPs
|
||||||
if (!$is_dach) {{
|
if (!$is_allowed) {{
|
||||||
$timestamp = date('Y-m-d H:i:s');
|
$timestamp = date('Y-m-d H:i:s');
|
||||||
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
|
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
|
||||||
$request_uri = $_SERVER['REQUEST_URI'] ?? '/';
|
$request_uri = $_SERVER['REQUEST_URI'] ?? '/';
|
||||||
@@ -468,7 +530,7 @@ def add_to_crowdsec(ip, shop):
|
|||||||
'--ip', ip,
|
'--ip', ip,
|
||||||
'--duration', '72h',
|
'--duration', '72h',
|
||||||
'--type', 'ban',
|
'--type', 'ban',
|
||||||
'--reason', f'GeoIP: Non-DACH IP blocked by {shop}'
|
'--reason', f'GeoIP: Non-allowed IP blocked by {shop}'
|
||||||
]
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -528,7 +590,7 @@ def process_queue_file(shop_path, shop):
|
|||||||
return processed
|
return processed
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
log("🚀 GeoIP CrowdSec Watcher started (DACH mode)")
|
log("🚀 GeoIP CrowdSec Watcher started")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@@ -564,7 +626,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Systemd service file
|
# Systemd service file
|
||||||
SYSTEMD_SERVICE_CONTENT = '''[Unit]
|
SYSTEMD_SERVICE_CONTENT = '''[Unit]
|
||||||
Description=GeoIP CrowdSec Watcher Service (DACH)
|
Description=GeoIP CrowdSec Watcher Service
|
||||||
After=network.target crowdsec.service
|
After=network.target crowdsec.service
|
||||||
Wants=crowdsec.service
|
Wants=crowdsec.service
|
||||||
|
|
||||||
@@ -652,8 +714,8 @@ def uninstall_watcher_service():
|
|||||||
print(" ✅ Service deinstalliert")
|
print(" ✅ Service deinstalliert")
|
||||||
|
|
||||||
|
|
||||||
def add_shop_to_active(shop, mode="php+crowdsec"):
|
def add_shop_to_active(shop, mode="php+crowdsec", geo_region="dach"):
|
||||||
"""Add shop to active shops tracking with mode"""
|
"""Add shop to active shops tracking with mode and geo region"""
|
||||||
os.makedirs(os.path.dirname(ACTIVE_SHOPS_FILE), exist_ok=True)
|
os.makedirs(os.path.dirname(ACTIVE_SHOPS_FILE), exist_ok=True)
|
||||||
|
|
||||||
shops = {}
|
shops = {}
|
||||||
@@ -664,7 +726,8 @@ def add_shop_to_active(shop, mode="php+crowdsec"):
|
|||||||
shops[shop] = {
|
shops[shop] = {
|
||||||
"activated": datetime.now().isoformat(),
|
"activated": datetime.now().isoformat(),
|
||||||
"expiry": (datetime.now() + timedelta(hours=72)).isoformat(),
|
"expiry": (datetime.now() + timedelta(hours=72)).isoformat(),
|
||||||
"mode": mode # "php+crowdsec" or "php-only"
|
"mode": mode, # "php+crowdsec" or "php-only"
|
||||||
|
"geo_region": geo_region # "dach" or "eurozone"
|
||||||
}
|
}
|
||||||
|
|
||||||
with open(ACTIVE_SHOPS_FILE, 'w') as f:
|
with open(ACTIVE_SHOPS_FILE, 'w') as f:
|
||||||
@@ -684,6 +747,19 @@ def get_shop_mode(shop):
|
|||||||
return "php+crowdsec"
|
return "php+crowdsec"
|
||||||
|
|
||||||
|
|
||||||
|
def get_shop_geo_region(shop):
|
||||||
|
"""Get the geo region for a shop"""
|
||||||
|
if not os.path.isfile(ACTIVE_SHOPS_FILE):
|
||||||
|
return "dach"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(ACTIVE_SHOPS_FILE, 'r') as f:
|
||||||
|
shops = json.load(f)
|
||||||
|
return shops.get(shop, {}).get("geo_region", "dach")
|
||||||
|
except:
|
||||||
|
return "dach"
|
||||||
|
|
||||||
|
|
||||||
def get_shop_activation_time(shop):
|
def get_shop_activation_time(shop):
|
||||||
"""Get the activation timestamp for a shop"""
|
"""Get the activation timestamp for a shop"""
|
||||||
if not os.path.isfile(ACTIVE_SHOPS_FILE):
|
if not os.path.isfile(ACTIVE_SHOPS_FILE):
|
||||||
@@ -819,13 +895,43 @@ def get_active_shops():
|
|||||||
return active
|
return active
|
||||||
|
|
||||||
|
|
||||||
def activate_blocking(shop, silent=False, mode="php+crowdsec"):
|
def select_geo_region():
|
||||||
|
"""Interactive geo region selection"""
|
||||||
|
print(f"\n🌍 Wähle die Geo-Region:")
|
||||||
|
print(f" [1] {GEO_REGIONS['dach']['icon']} DACH - {GEO_REGIONS['dach']['description']}")
|
||||||
|
print(f" [2] {GEO_REGIONS['eurozone']['icon']} Eurozone+GB - {len(GEO_REGIONS['eurozone']['countries'])} Länder")
|
||||||
|
|
||||||
|
choice = input(f"\nRegion wählen [1/2]: ").strip()
|
||||||
|
|
||||||
|
if choice == "2":
|
||||||
|
return "eurozone"
|
||||||
|
else:
|
||||||
|
return "dach"
|
||||||
|
|
||||||
|
|
||||||
|
def select_mode():
|
||||||
|
"""Interactive mode selection"""
|
||||||
|
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)")
|
||||||
|
|
||||||
|
choice = input(f"\nModus wählen [1/2]: ").strip()
|
||||||
|
|
||||||
|
if choice == "2":
|
||||||
|
return "php-only"
|
||||||
|
else:
|
||||||
|
return "php+crowdsec"
|
||||||
|
|
||||||
|
|
||||||
|
def activate_blocking(shop, silent=False, mode="php+crowdsec", geo_region="dach"):
|
||||||
"""Activate GeoIP blocking for a single shop"""
|
"""Activate GeoIP blocking for a single shop"""
|
||||||
httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs')
|
httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs')
|
||||||
index_php = os.path.join(httpdocs, 'index.php')
|
index_php = os.path.join(httpdocs, 'index.php')
|
||||||
backup_php = os.path.join(httpdocs, f'index.php{BACKUP_SUFFIX}')
|
backup_php = os.path.join(httpdocs, f'index.php{BACKUP_SUFFIX}')
|
||||||
blocking_file = os.path.join(httpdocs, BLOCKING_FILE)
|
blocking_file = os.path.join(httpdocs, BLOCKING_FILE)
|
||||||
|
|
||||||
|
region_info = get_geo_region_info(geo_region)
|
||||||
|
|
||||||
if os.path.isfile(backup_php):
|
if os.path.isfile(backup_php):
|
||||||
if not silent:
|
if not silent:
|
||||||
print(f"⚠️ GeoIP-Blocking bereits aktiv für {shop}")
|
print(f"⚠️ GeoIP-Blocking bereits aktiv für {shop}")
|
||||||
@@ -837,8 +943,8 @@ def activate_blocking(shop, silent=False, mode="php+crowdsec"):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
print(f"\n🔧 Aktiviere DACH GeoIP-Blocking für: {shop}")
|
print(f"\n🔧 Aktiviere {region_info['icon']} {region_info['name']} GeoIP-Blocking für: {shop}")
|
||||||
print(" (Erlaubt: Deutschland, Österreich, Schweiz)")
|
print(f" Erlaubt: {region_info['description']}")
|
||||||
print(f" Modus: {'PHP + CrowdSec' if mode == 'php+crowdsec' else 'Nur PHP'}")
|
print(f" Modus: {'PHP + CrowdSec' if mode == 'php+crowdsec' else 'Nur PHP'}")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
|
||||||
@@ -892,25 +998,31 @@ def activate_blocking(shop, silent=False, mode="php+crowdsec"):
|
|||||||
print(" ✏️ index.php modifiziert")
|
print(" ✏️ index.php modifiziert")
|
||||||
|
|
||||||
expiry = datetime.now() + timedelta(hours=72)
|
expiry = datetime.now() + timedelta(hours=72)
|
||||||
|
countries_array = generate_php_countries_array(geo_region)
|
||||||
|
|
||||||
# Generate PHP script based on mode
|
# Generate PHP script based on mode
|
||||||
if mode == "php+crowdsec":
|
if mode == "php+crowdsec":
|
||||||
geoip_content = GEOIP_SCRIPT.format(
|
geoip_content = GEOIP_SCRIPT_TEMPLATE.format(
|
||||||
|
region_name=region_info['name'],
|
||||||
|
region_description=region_info['description'],
|
||||||
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
||||||
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
cache_file=CACHE_FILE,
|
cache_file=CACHE_FILE,
|
||||||
log_file=LOG_FILE,
|
log_file=LOG_FILE,
|
||||||
crowdsec_queue=CROWDSEC_QUEUE_FILE,
|
crowdsec_queue=CROWDSEC_QUEUE_FILE,
|
||||||
shop_name=shop
|
shop_name=shop,
|
||||||
|
countries_array=countries_array
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# PHP-only mode: no crowdsec queue writing
|
geoip_content = GEOIP_SCRIPT_TEMPLATE_PHP_ONLY.format(
|
||||||
geoip_content = GEOIP_SCRIPT_PHP_ONLY.format(
|
region_name=region_info['name'],
|
||||||
|
region_description=region_info['description'],
|
||||||
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
||||||
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
cache_file=CACHE_FILE,
|
cache_file=CACHE_FILE,
|
||||||
log_file=LOG_FILE,
|
log_file=LOG_FILE,
|
||||||
shop_name=shop
|
shop_name=shop,
|
||||||
|
countries_array=countries_array
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(blocking_file, 'w', encoding='utf-8') as f:
|
with open(blocking_file, 'w', encoding='utf-8') as f:
|
||||||
@@ -921,14 +1033,14 @@ def activate_blocking(shop, silent=False, mode="php+crowdsec"):
|
|||||||
# Step 3: Register shop
|
# Step 3: Register shop
|
||||||
if not silent:
|
if not silent:
|
||||||
print("\n[3/3] Registriere Shop...")
|
print("\n[3/3] Registriere Shop...")
|
||||||
add_shop_to_active(shop, mode)
|
add_shop_to_active(shop, mode, geo_region)
|
||||||
if not silent:
|
if not silent:
|
||||||
print(" ✅ Shop registriert")
|
print(" ✅ Shop registriert")
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
print(f"✅ DACH GeoIP-Blocking aktiviert für: {shop}")
|
print(f"✅ {region_info['icon']} {region_info['name']} GeoIP-Blocking aktiviert für: {shop}")
|
||||||
print(f" Erlaubte Länder: 🇩🇪 DE | 🇦🇹 AT | 🇨🇭 CH")
|
print(f" Erlaubte Länder: {region_info['description']}")
|
||||||
print(f" Modus: {'PHP + CrowdSec 🛡️' if mode == 'php+crowdsec' else 'Nur PHP 📝'}")
|
print(f" Modus: {'PHP + CrowdSec 🛡️' if mode == 'php+crowdsec' else 'Nur PHP 📝'}")
|
||||||
print(f" Gültig bis: {expiry.strftime('%Y-%m-%d %H:%M:%S CET')}")
|
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" PHP-Log: {os.path.join(httpdocs, LOG_FILE)}")
|
||||||
@@ -950,11 +1062,13 @@ def deactivate_blocking(shop, silent=False):
|
|||||||
log_file = os.path.join(httpdocs, LOG_FILE)
|
log_file = os.path.join(httpdocs, LOG_FILE)
|
||||||
queue_file = os.path.join(httpdocs, CROWDSEC_QUEUE_FILE)
|
queue_file = os.path.join(httpdocs, CROWDSEC_QUEUE_FILE)
|
||||||
|
|
||||||
# Get mode before removing from tracking
|
# Get mode and geo region before removing from tracking
|
||||||
shop_mode = get_shop_mode(shop)
|
shop_mode = get_shop_mode(shop)
|
||||||
|
shop_geo = get_shop_geo_region(shop)
|
||||||
|
region_info = get_geo_region_info(shop_geo)
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
print(f"\n🔧 Deaktiviere DACH GeoIP-Blocking für: {shop}")
|
print(f"\n🔧 Deaktiviere {region_info['icon']} {region_info['name']} GeoIP-Blocking für: {shop}")
|
||||||
print(f" Modus war: {'PHP + CrowdSec' if shop_mode == 'php+crowdsec' else 'Nur PHP'}")
|
print(f" Modus war: {'PHP + CrowdSec' if shop_mode == 'php+crowdsec' else 'Nur PHP'}")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
|
||||||
@@ -1011,7 +1125,7 @@ def deactivate_blocking(shop, silent=False):
|
|||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
print(f"✅ DACH GeoIP-Blocking deaktiviert für: {shop}")
|
print(f"✅ GeoIP-Blocking deaktiviert für: {shop}")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -1029,7 +1143,7 @@ def activate_all_shops():
|
|||||||
return
|
return
|
||||||
|
|
||||||
print(f"\n{'=' * 60}")
|
print(f"\n{'=' * 60}")
|
||||||
print(f" DACH GeoIP-Blocking für ALLE Shops aktivieren")
|
print(f" GeoIP-Blocking für ALLE Shops aktivieren")
|
||||||
print(f"{'=' * 60}")
|
print(f"{'=' * 60}")
|
||||||
print(f"\n📋 Folgende {len(available_shops)} Shop(s) werden aktiviert:")
|
print(f"\n📋 Folgende {len(available_shops)} Shop(s) werden aktiviert:")
|
||||||
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}\n")
|
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}\n")
|
||||||
@@ -1040,20 +1154,16 @@ def activate_all_shops():
|
|||||||
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
||||||
print(f" • {color}{shop} {link11_tag}{COLOR_RESET}")
|
print(f" • {color}{shop} {link11_tag}{COLOR_RESET}")
|
||||||
|
|
||||||
# Ask for mode
|
# Ask for geo region
|
||||||
print(f"\n🔧 Wähle den Blocking-Modus:")
|
geo_region = select_geo_region()
|
||||||
print(f" [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet)")
|
region_info = get_geo_region_info(geo_region)
|
||||||
print(f" [2] Nur PHP (keine CrowdSec-Synchronisation)")
|
|
||||||
mode_choice = input(f"\nModus wählen [1/2]: ").strip()
|
|
||||||
|
|
||||||
if mode_choice == "2":
|
# Ask for mode
|
||||||
mode = "php-only"
|
mode = select_mode()
|
||||||
mode_display = "Nur PHP 📝"
|
mode_display = "PHP + CrowdSec 🛡️" if mode == "php+crowdsec" else "Nur PHP 📝"
|
||||||
else:
|
|
||||||
mode = "php+crowdsec"
|
|
||||||
mode_display = "PHP + CrowdSec 🛡️"
|
|
||||||
|
|
||||||
print(f"\n⚠️ Dies aktiviert den Schutz für alle oben genannten Shops!")
|
print(f"\n⚠️ Dies aktiviert den Schutz für alle oben genannten Shops!")
|
||||||
|
print(f" Region: {region_info['icon']} {region_info['name']}")
|
||||||
print(f" Modus: {mode_display}")
|
print(f" Modus: {mode_display}")
|
||||||
confirm = input(f"\nFortfahren? (ja/nein): ").strip().lower()
|
confirm = input(f"\nFortfahren? (ja/nein): ").strip().lower()
|
||||||
|
|
||||||
@@ -1062,7 +1172,7 @@ def activate_all_shops():
|
|||||||
return
|
return
|
||||||
|
|
||||||
print(f"\n{'=' * 60}")
|
print(f"\n{'=' * 60}")
|
||||||
print(f" Starte Aktivierung ({mode_display})...")
|
print(f" Starte Aktivierung ({region_info['icon']} {region_info['name']}, {mode_display})...")
|
||||||
print(f"{'=' * 60}")
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
success_count = 0
|
success_count = 0
|
||||||
@@ -1122,29 +1232,37 @@ def activate_all_shops():
|
|||||||
|
|
||||||
# Create blocking script based on mode
|
# Create blocking script based on mode
|
||||||
expiry = datetime.now() + timedelta(hours=72)
|
expiry = datetime.now() + timedelta(hours=72)
|
||||||
|
countries_array = generate_php_countries_array(geo_region)
|
||||||
|
|
||||||
if mode == "php+crowdsec":
|
if mode == "php+crowdsec":
|
||||||
geoip_content = GEOIP_SCRIPT.format(
|
geoip_content = GEOIP_SCRIPT_TEMPLATE.format(
|
||||||
|
region_name=region_info['name'],
|
||||||
|
region_description=region_info['description'],
|
||||||
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
||||||
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
cache_file=CACHE_FILE,
|
cache_file=CACHE_FILE,
|
||||||
log_file=LOG_FILE,
|
log_file=LOG_FILE,
|
||||||
crowdsec_queue=CROWDSEC_QUEUE_FILE,
|
crowdsec_queue=CROWDSEC_QUEUE_FILE,
|
||||||
shop_name=shop
|
shop_name=shop,
|
||||||
|
countries_array=countries_array
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
geoip_content = GEOIP_SCRIPT_PHP_ONLY.format(
|
geoip_content = GEOIP_SCRIPT_TEMPLATE_PHP_ONLY.format(
|
||||||
|
region_name=region_info['name'],
|
||||||
|
region_description=region_info['description'],
|
||||||
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
expiry_date=expiry.strftime('%Y-%m-%d %H:%M:%S CET'),
|
||||||
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
expiry_timestamp=expiry.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
cache_file=CACHE_FILE,
|
cache_file=CACHE_FILE,
|
||||||
log_file=LOG_FILE,
|
log_file=LOG_FILE,
|
||||||
shop_name=shop
|
shop_name=shop,
|
||||||
|
countries_array=countries_array
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(blocking_file, 'w', encoding='utf-8') as f:
|
with open(blocking_file, 'w', encoding='utf-8') as f:
|
||||||
f.write(geoip_content)
|
f.write(geoip_content)
|
||||||
|
|
||||||
# Register shop with mode
|
# Register shop with mode and geo region
|
||||||
add_shop_to_active(shop, mode)
|
add_shop_to_active(shop, mode, geo_region)
|
||||||
|
|
||||||
print(f" ✅ Aktiviert (bis {expiry.strftime('%Y-%m-%d %H:%M')})")
|
print(f" ✅ Aktiviert (bis {expiry.strftime('%Y-%m-%d %H:%M')})")
|
||||||
success_count += 1
|
success_count += 1
|
||||||
@@ -1166,7 +1284,7 @@ def activate_all_shops():
|
|||||||
for shop in failed_shops:
|
for shop in failed_shops:
|
||||||
print(f" • {shop}")
|
print(f" • {shop}")
|
||||||
|
|
||||||
print(f"\n 🇩🇪 🇦🇹 🇨🇭 Nur DACH-Traffic erlaubt")
|
print(f"\n {region_info['icon']} Region: {region_info['name']}")
|
||||||
print(f" 🔧 Modus: {mode_display}")
|
print(f" 🔧 Modus: {mode_display}")
|
||||||
print(f" ⏰ Gültig für 72 Stunden")
|
print(f" ⏰ Gültig für 72 Stunden")
|
||||||
print(f"{'=' * 60}")
|
print(f"{'=' * 60}")
|
||||||
@@ -1181,7 +1299,7 @@ def deactivate_all_shops():
|
|||||||
return
|
return
|
||||||
|
|
||||||
print(f"\n{'=' * 60}")
|
print(f"\n{'=' * 60}")
|
||||||
print(f" DACH GeoIP-Blocking für ALLE Shops deaktivieren")
|
print(f" GeoIP-Blocking für ALLE Shops deaktivieren")
|
||||||
print(f"{'=' * 60}")
|
print(f"{'=' * 60}")
|
||||||
print(f"\n📋 Folgende {len(active_shops)} Shop(s) werden deaktiviert:")
|
print(f"\n📋 Folgende {len(active_shops)} Shop(s) werden deaktiviert:")
|
||||||
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}\n")
|
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}\n")
|
||||||
@@ -1190,7 +1308,9 @@ def deactivate_all_shops():
|
|||||||
link11_info = check_link11(shop)
|
link11_info = check_link11(shop)
|
||||||
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
||||||
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
||||||
print(f" • {color}{shop} {link11_tag}{COLOR_RESET}")
|
geo_region = get_shop_geo_region(shop)
|
||||||
|
region_info = get_geo_region_info(geo_region)
|
||||||
|
print(f" • {color}{shop} {link11_tag}{COLOR_RESET} {region_info['icon']}")
|
||||||
|
|
||||||
print(f"\n⚠️ Dies deaktiviert den Schutz für alle oben genannten Shops!")
|
print(f"\n⚠️ Dies deaktiviert den Schutz für alle oben genannten Shops!")
|
||||||
print(f"⚠️ Alle zugehörigen CrowdSec-Decisions werden ebenfalls entfernt!")
|
print(f"⚠️ Alle zugehörigen CrowdSec-Decisions werden ebenfalls entfernt!")
|
||||||
@@ -1404,6 +1524,11 @@ def show_all_logs():
|
|||||||
bar = "█" * min(int(req_min * 2), 20) if req_min > 0 else ""
|
bar = "█" * min(int(req_min * 2), 20) if req_min > 0 else ""
|
||||||
runtime_str = format_duration(runtime) if runtime > 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
|
# Color shop name based on Link11 status
|
||||||
link11_info = check_link11(shop)
|
link11_info = check_link11(shop)
|
||||||
if link11_info['is_link11']:
|
if link11_info['is_link11']:
|
||||||
@@ -1411,7 +1536,7 @@ def show_all_logs():
|
|||||||
else:
|
else:
|
||||||
shop_colored = f"{COLOR_RED}{shop}{COLOR_RESET}"
|
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
|
# Show top IP for this shop
|
||||||
shop_ips = stats['ips']
|
shop_ips = stats['ips']
|
||||||
@@ -1438,6 +1563,11 @@ def show_all_logs():
|
|||||||
count = crowdsec_stats[shop]
|
count = crowdsec_stats[shop]
|
||||||
bar = "█" * min(count // 10, 20) if count > 0 else ""
|
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
|
# Color shop name based on Link11 status
|
||||||
link11_info = check_link11(shop)
|
link11_info = check_link11(shop)
|
||||||
if link11_info['is_link11']:
|
if link11_info['is_link11']:
|
||||||
@@ -1445,7 +1575,7 @@ def show_all_logs():
|
|||||||
else:
|
else:
|
||||||
shop_colored = f"{COLOR_RED}{shop}{COLOR_RESET}"
|
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():
|
elif check_crowdsec():
|
||||||
print(" └─ Keine aktiven Bans")
|
print(" └─ Keine aktiven Bans")
|
||||||
else:
|
else:
|
||||||
@@ -1507,6 +1637,8 @@ def show_logs(shop):
|
|||||||
httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs')
|
httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs')
|
||||||
log_file = os.path.join(httpdocs, LOG_FILE)
|
log_file = os.path.join(httpdocs, LOG_FILE)
|
||||||
shop_mode = get_shop_mode(shop)
|
shop_mode = get_shop_mode(shop)
|
||||||
|
shop_geo = get_shop_geo_region(shop)
|
||||||
|
region_info = get_geo_region_info(shop_geo)
|
||||||
|
|
||||||
# Get stats
|
# Get stats
|
||||||
blocks, ips, activation_time = get_shop_log_stats(shop)
|
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 📝"
|
mode_display = "PHP + CrowdSec 🛡️" if shop_mode == "php+crowdsec" else "Nur PHP 📝"
|
||||||
|
|
||||||
print(f"\n{'═' * 70}")
|
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"{'═' * 70}")
|
||||||
print(f"\n⏱️ Aktiviert: {activation_str}")
|
print(f"\n⏱️ Aktiviert: {activation_str}")
|
||||||
print(f"⏱️ Laufzeit: {runtime_str}")
|
print(f"⏱️ Laufzeit: {runtime_str}")
|
||||||
@@ -1613,8 +1746,8 @@ def show_logs(shop):
|
|||||||
def main():
|
def main():
|
||||||
"""Main menu"""
|
"""Main menu"""
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
print(" GeoIP Shop Blocker Manager - DACH Version")
|
print(" GeoIP Shop Blocker Manager")
|
||||||
print(" Erlaubt: 🇩🇪 Deutschland | 🇦🇹 Österreich | 🇨🇭 Schweiz")
|
print(" Regionen: 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB (22 Länder)")
|
||||||
print(" PHP + CrowdSec Watcher (systemd service)")
|
print(" PHP + CrowdSec Watcher (systemd service)")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
|
||||||
@@ -1664,22 +1797,17 @@ def main():
|
|||||||
if 0 <= shop_idx < len(available_shops):
|
if 0 <= shop_idx < len(available_shops):
|
||||||
selected_shop = available_shops[shop_idx]
|
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
|
# Ask for mode
|
||||||
print(f"\n🔧 Wähle den Blocking-Modus:")
|
mode = select_mode()
|
||||||
print(f" [1] PHP + CrowdSec (IPs werden an CrowdSec gemeldet)")
|
mode_display = "PHP + CrowdSec" if mode == "php+crowdsec" else "Nur PHP"
|
||||||
print(f" [2] Nur PHP (keine CrowdSec-Synchronisation)")
|
|
||||||
mode_choice = input(f"\nModus wählen [1/2]: ").strip()
|
|
||||||
|
|
||||||
if mode_choice == "2":
|
confirm = input(f"\n⚠️ {region_info['icon']} {region_info['name']}-Blocking ({mode_display}) aktivieren für '{selected_shop}'? (ja/nein): ").strip().lower()
|
||||||
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()
|
|
||||||
if confirm in ['ja', 'j', 'yes', 'y']:
|
if confirm in ['ja', 'j', 'yes', 'y']:
|
||||||
activate_blocking(selected_shop, mode=mode)
|
activate_blocking(selected_shop, mode=mode, geo_region=geo_region)
|
||||||
else:
|
else:
|
||||||
print("❌ Ungültig")
|
print("❌ Ungültig")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -1696,11 +1824,13 @@ def main():
|
|||||||
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}")
|
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}")
|
||||||
for i, shop in enumerate(active_shops, 1):
|
for i, shop in enumerate(active_shops, 1):
|
||||||
mode = get_shop_mode(shop)
|
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_icon = "🛡️" if mode == "php+crowdsec" else "📝"
|
||||||
link11_info = check_link11(shop)
|
link11_info = check_link11(shop)
|
||||||
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
||||||
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
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()
|
shop_choice = input("\nWähle einen Shop: ").strip()
|
||||||
try:
|
try:
|
||||||
@@ -1726,11 +1856,13 @@ def main():
|
|||||||
print(f" [0] 📊 ALLE Shops (Zusammenfassung)")
|
print(f" [0] 📊 ALLE Shops (Zusammenfassung)")
|
||||||
for i, shop in enumerate(active_shops, 1):
|
for i, shop in enumerate(active_shops, 1):
|
||||||
mode = get_shop_mode(shop)
|
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_icon = "🛡️" if mode == "php+crowdsec" else "📝"
|
||||||
link11_info = check_link11(shop)
|
link11_info = check_link11(shop)
|
||||||
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
||||||
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
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()
|
shop_choice = input("\nWähle eine Option: ").strip()
|
||||||
try:
|
try:
|
||||||
@@ -1749,11 +1881,13 @@ def main():
|
|||||||
active_shops = get_active_shops()
|
active_shops = get_active_shops()
|
||||||
print(f"\n📊 Status:")
|
print(f"\n📊 Status:")
|
||||||
print(f" Shops gesamt: {len(shops)}")
|
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}")
|
print(f" {COLOR_GREEN}Grün = hinter Link11{COLOR_RESET} | {COLOR_RED}Rot = Direkt{COLOR_RESET}")
|
||||||
if active_shops:
|
if active_shops:
|
||||||
for shop in active_shops:
|
for shop in active_shops:
|
||||||
mode = get_shop_mode(shop)
|
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_icon = "🛡️" if mode == "php+crowdsec" else "📝"
|
||||||
mode_text = "PHP+CS" if mode == "php+crowdsec" else "PHP"
|
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
|
color = COLOR_GREEN if link11_info['is_link11'] else COLOR_RED
|
||||||
link11_tag = "[Link11]" if link11_info['is_link11'] else "[Direkt]"
|
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":
|
elif choice == "5":
|
||||||
activate_all_shops()
|
activate_all_shops()
|
||||||
|
|||||||
Reference in New Issue
Block a user