From 511ade8666b29773000b6efad1300a1990048ae8 Mon Sep 17 00:00:00 2001 From: thomasciesla Date: Tue, 30 Dec 2025 13:29:35 +0100 Subject: [PATCH] jtl-wafi-agent.py aktualisiert --- jtl-wafi-agent.py | 97 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/jtl-wafi-agent.py b/jtl-wafi-agent.py index 5f2616e..38526f9 100644 --- a/jtl-wafi-agent.py +++ b/jtl-wafi-agent.py @@ -28,6 +28,8 @@ import ipaddress import signal import platform import threading +import urllib.request +import urllib.error from datetime import datetime, timedelta, timezone from pathlib import Path from collections import Counter @@ -70,6 +72,11 @@ RECONNECT_BASE_DELAY = 1 # Sekunden RECONNECT_MAX_DELAY = 60 # Sekunden STATS_UPDATE_INTERVAL = 10 # Sekunden +# ============================================================================= +# AUTO-UPDATE +# ============================================================================= +AGENT_UPDATE_URL = "https://git.jtl-hosting.de/thomasciesla/JTL-WAFI/raw/branch/main/jtl-wafi-agent.py" + # ============================================================================= # LOG ROTATION # ============================================================================= @@ -1608,9 +1615,9 @@ if ($detected_bot === null && !empty($user_agent)) {{ }} }} -// === STEP 2: Detect Country === +// === STEP 2: Detect Country (only if country_mode active) === $country = 'XX'; -if (!empty($visitor_ip) && filter_var($visitor_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {{ +if ($country_mode && !empty($visitor_ip) && filter_var($visitor_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {{ $country = get_country_for_ip($visitor_ip, $country_cache_dir); }} @@ -2752,6 +2759,9 @@ class JTLWAFiAgent: elif event_type == 'command.deactivate': await self._handle_deactivate_command(event_data) + elif event_type == 'command.update': + await self._handle_update_command(event_data) + elif event_type == 'log.subscribe': shop = event_data.get('shop') if shop: @@ -2899,6 +2909,89 @@ class JTLWAFiAgent: 'shop': shop }) + async def _handle_update_command(self, data: Dict[str, Any]): + """Verarbeitet update-Command - Agent selbst updaten.""" + command_id = data.get('command_id', 'unknown') + + logger.info("Update-Command empfangen - starte Self-Update...") + + try: + import urllib.request + + # 1. Download neue Version + logger.info(f"Lade neue Version von {AGENT_UPDATE_URL}...") + request = urllib.request.Request( + AGENT_UPDATE_URL, + headers={'User-Agent': f'JTL-WAFi-Agent/{VERSION}'} + ) + with urllib.request.urlopen(request, timeout=30) as response: + new_content = response.read().decode('utf-8') + + # 2. Syntax-Check + logger.info("Prüfe Syntax der neuen Version...") + compile(new_content, '', 'exec') + + # 3. Version extrahieren (optional, für Log) + new_version = "unknown" + for line in new_content.split('\n')[:50]: + if 'VERSION = ' in line: + new_version = line.split('=')[1].strip().strip('"\'') + break + + logger.info(f"Neue Version: {new_version} (aktuell: {VERSION})") + + # 4. Script-Pfad ermitteln + script_path = os.path.abspath(__file__) + backup_path = script_path + '.backup' + + # 5. Backup erstellen + logger.info(f"Erstelle Backup: {backup_path}") + shutil.copy(script_path, backup_path) + + # 6. Neue Version schreiben + logger.info(f"Schreibe neue Version nach {script_path}...") + with open(script_path, 'w', encoding='utf-8') as f: + f.write(new_content) + + # 7. Erfolg melden + await self._send_event('command.result', { + 'command_id': command_id, + 'status': 'success', + 'message': f'Update erfolgreich ({VERSION} -> {new_version}). Agent wird neugestartet...' + }) + + # Kurz warten damit Nachricht gesendet wird + await asyncio.sleep(1) + + # 8. Neustart via os.execv (ersetzt den aktuellen Prozess) + logger.info("Starte Agent neu via os.execv...") + os.execv(sys.executable, [sys.executable, script_path]) + + except urllib.error.URLError as e: + error_msg = f'Download fehlgeschlagen: {str(e)}' + logger.error(error_msg) + await self._send_event('command.result', { + 'command_id': command_id, + 'status': 'error', + 'message': error_msg + }) + except SyntaxError as e: + error_msg = f'Syntax-Fehler in neuer Version: {str(e)}' + logger.error(error_msg) + await self._send_event('command.result', { + 'command_id': command_id, + 'status': 'error', + 'message': error_msg + }) + except Exception as e: + error_msg = f'Update fehlgeschlagen: {str(e)}' + logger.error(error_msg) + await self._send_event('command.result', { + 'command_id': command_id, + 'status': 'error', + 'message': error_msg + }) + async def _periodic_tasks(self): """Führt periodische Tasks aus.""" while self.running: