# πŸ›‘οΈ JTL-WAFi v2.4 **Web Application Firewall fΓΌr JTL-Shops** - Ein verteiltes Bot-Protection und GeoIP-Blocking System mit Echtzeit-Dashboard, WebSocket-Kommunikation und zentraler Verwaltung mehrerer Server. --- ## πŸ“‹ Inhaltsverzeichnis - [Überblick](#-ΓΌberblick) - [Features](#-features) - [Architektur](#-architektur) - [Voraussetzungen](#-voraussetzungen) - [Installation](#-installation) - [Dashboard Server](#1-dashboard-server-zentral) - [Agent Server](#2-agent-server-pro-shop-server) - [Konfiguration](#-konfiguration) - [Verwendung](#-verwendung) - [Einzelne Shops](#einzelne-shops-verwalten) - [Massenaktionen](#massenaktionen) - [Monitoring](#monitoring) - [Blocking-Mechanismus](#-blocking-mechanismus) - [Bot-Erkennung](#-bot-erkennung) - [API-Referenz](#-api-referenz) - [WebSocket Events](#-websocket-events) - [Datenstrukturen](#-datenstrukturen) - [Troubleshooting](#-troubleshooting) - [Changelog](#-changelog) --- ## 🎯 Überblick JTL-WAFi besteht aus zwei Komponenten: | Komponente | Beschreibung | Deployment | |------------|--------------|------------| | **Dashboard** | Zentrale Web-OberflΓ€che zur Verwaltung aller Shops | 1x auf Management-Server | | **Agent** | Lokaler Dienst der das Blocking durchfΓΌhrt | 1x pro Shop-Server | ### Schutzmodi | Modus | Beschreibung | Anwendungsfall | |-------|--------------|----------------| | **πŸ€– Bot Rate-Limiting** | Erkennt und limitiert aggressive Bots basierend auf User-Agent und IP-Analyse | Schutz vor Scraping, SEO-Bots, AI-Crawlern | | **πŸ” Bot Monitor-Only** | Erkennt und loggt Bots ohne zu blockieren | Analyse vor Aktivierung | | **🌍 GeoIP-Blocking** | Blockiert Traffic aus nicht-relevanten Regionen | Shops die nur DACH/EU beliefern | --- ## ✨ Features ### Dashboard (v2.4) #### Übersicht & Monitoring - **πŸ“Š Echtzeit-Statistiken** - Server online, aktive Shops, Requests/min, aktive Bans - **πŸ”₯ Top 10 Shops** - Übersicht der Shops mit hΓΆchster Last - **πŸ“ˆ Bot-AktivitΓ€ts-Graph** - Zeitbasierte Darstellung pro Bot-Typ mit Zeitachse - **πŸ“œ Live Logs** - Echtzeit Log-Streaming pro Shop - **πŸ›‘οΈ Link11 Kategorisierung** - Unterscheidung zwischen CDN- und Direkt-Shops #### Verwaltung - **⚑ Massenaktionen** - Alle Shops gleichzeitig aktivieren/deaktivieren - **πŸ” Sortierbare Shop-Liste** - Nach Requests/min oder aktiven Bans - **πŸ–₯️ Multi-Agent Support** - Verwaltung beliebig vieler Server von einem Dashboard - **πŸ” Token-basierte Auth** - Sichere Agent-Freigabe - **πŸ”„ Modus-Wechsel** - Direkter Wechsel zwischen Bot/GeoIP/Monitor im Detail-Modal #### Technisch - **WebSocket Real-Time** - Keine Polling, sofortige Updates - **In-Memory Storage** - Keine Datenbank-Locks, maximale Performance - **SSL/TLS** - Automatische selbstsignierte Zertifikatsgenerierung - **Responsive Design** - Funktioniert auf Desktop, Tablet und Mobile ### Agent (v2.4) #### Erkennung & Blocking - **πŸ” Auto-Discovery** - Findet automatisch alle JTL-Shops in `/var/www/vhosts/` - **πŸ“ Log-Analyse** - Liest Shop-Logs fΓΌr Statistiken - **πŸ€– Bot-Erkennung** - Identifiziert **200+ bekannte Bot-Typen** via User-Agent - **🌐 IP-basierte Erkennung** - Erkennt getarnte Bots (z.B. Alibaba) anhand ihrer IP-Ranges - **🚫 PHP-Blocking** - Dynamisches Blocking via PHP-Skript (kein iptables!) - **🌍 GeoIP-Lookup** - IP-Ranges von ipdeny.com fΓΌr LΓ€nder-Blocking #### ZuverlΓ€ssigkeit - **♻️ Auto-Reconnect** - Automatische Wiederverbindung zum Dashboard mit Exponential Backoff - **πŸ”‘ Token-Auth** - Sichere Authentifizierung nach Freigabe - **⏹️ Graceful Shutdown** - Sauberes Beenden mit Ctrl+C (SIGINT/SIGTERM) - **πŸ’Ύ Token-Persistenz** - Token wird lokal in `/etc/jtl-wafi/token` gespeichert - **πŸ“‹ Log-Rotation** - Automatische Rotation bei 10 MB (3 Backups) --- ## πŸ— Architektur ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ DASHBOARD SERVER β”‚ β”‚ (shop000.example.com) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ jtl_wafi_dashboard.py β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ FastAPI β”‚ β”‚ WebSocket β”‚ β”‚ In-Memory β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ HTTP API β”‚ β”‚ Server β”‚ β”‚ DataStore β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ WSS (Port 8000) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ AGENT SERVER 1 β”‚ β”‚ AGENT SERVER 2 β”‚ β”‚ AGENT SERVER N β”‚ β”‚ (shop020.xxx) β”‚ β”‚ (shop043.xxx) β”‚ β”‚ (shopXXX.xxx) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Agent β”‚ β”‚ β”‚ β”‚ Agent β”‚ β”‚ β”‚ β”‚ Agent β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Shop A β”‚ β”‚ β”‚ β”‚ Shop D β”‚ β”‚ β”‚ β”‚ Shop X β”‚ β”‚ β”‚ β”‚ Shop B β”‚ β”‚ β”‚ β”‚ Shop E β”‚ β”‚ β”‚ β”‚ Shop Y β”‚ β”‚ β”‚ β”‚ Shop C β”‚ β”‚ β”‚ β”‚ Shop F β”‚ β”‚ β”‚ β”‚ Shop Z β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Datenfluss ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Agent β”‚ ──── agent.connect ────────► β”‚ Dashboard β”‚ β”‚ β”‚ ◄─── auth.approved ───────── β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ ──── agent.heartbeat ──────► β”‚ β”‚ (alle 60s) β”‚ β”‚ ──── shop.full_update ─────► β”‚ β”‚ β”‚ β”‚ ──── shop.stats ───────────► β”‚ β”‚ (alle 10s) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ ◄─── command.activate ────── β”‚ β”‚ β”‚ β”‚ ◄─── command.deactivate ──── β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ ──── log.entry ────────────► β”‚ β”‚ (live) β”‚ β”‚ ──── bot.banned ───────────► β”‚ β”‚ (events) β”‚ β”‚ ──── command.result ───────► β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## πŸ”§ Blocking-Mechanismus ### So funktioniert das Blocking JTL-WAFi blockiert **NICHT** via iptables, sondern durch ein **PHP-Skript**, das in die Shop-`index.php` eingebunden wird: ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ HTTP Request β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Nginx / Apache β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ index.php β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ require_once __DIR__ . '/jtl-wafi.php'; ◄── NEU β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ jtl-wafi.php β”‚ β”‚ β”‚ β”‚ β€’ PrΓΌft IP gegen erlaubte LΓ€nder (GeoIP-Mode) β”‚ β”‚ β”‚ β”‚ β€’ Erkennt Bots via User-Agent + IP-Ranges β”‚ β”‚ β”‚ β”‚ β€’ Rate-Limiting pro Bot-Typ (nicht pro IP!) β”‚ β”‚ β”‚ β”‚ β€’ Bei Verstoß: 403 Forbidden + exit β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ [Rest der Shop-Logik] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Dateien pro Shop (bei Aktivierung) | Datei | Beschreibung | |-------|--------------| | `index.php` | Modifiziert mit `require_once` fΓΌr jtl-wafi.php | | `index.php.jtl-wafi_backup` | Backup der Original index.php | | `jtl-wafi.php` | Das eigentliche Blocking-Skript | | `jtl-wafi_ip_ranges.cache` | Gecachte IP-Ranges (nur GeoIP-Mode) | | `jtl-wafi_blocked.log` | Log der blockierten Requests | | `jtl-wafi_ratelimit/` | Verzeichnis fΓΌr Rate-Limit-Daten (nur Bot-Mode) | ### GeoIP-Blocking - LΓ€dt IP-Ranges von **ipdeny.com** (z.B. `de-aggregated.zone`) - Cached die Ranges lokal fΓΌr 24 Stunden - **FAIL-OPEN**: Bei Problemen mit dem Cache wird Traffic durchgelassen - Mindestanforderung: 1000 Ranges (DACH) / 5000 Ranges (Eurozone) ### Bot Rate-Limiting - Erkennung via **User-Agent Patterns** (200+ Bots) - Erkennung via **IP-Ranges** (z.B. Alibaba Cloud) - Rate-Limit gilt **pro Bot-Typ**, nicht pro IP - Beispiel: Alle AhrefsBot-Requests teilen sich ein Limit - Ban-Dateien speichern Bot-Namen fΓΌr Dashboard-Anzeige --- ## πŸ€– Bot-Erkennung ### Erkannte Bot-Kategorien | Kategorie | Beispiele | Anzahl | |-----------|-----------|--------| | **AI/LLM Services** | GPTBot, ClaudeBot, PerplexityBot, Bytespider | 50+ | | **Suchmaschinen** | Googlebot, Bingbot, Baiduspider, YandexBot | 30+ | | **SEO & Marketing** | AhrefsBot, SemrushBot, MJ12Bot, DotBot | 15+ | | **Social Media** | FacebookBot, Twitterbot, LinkedInBot | 20+ | | **E-Commerce** | Amazonbot, Alibaba-Bot, Idealo, Shopify | 15+ | | **Archiv & Research** | Archive.org Bot, CCBot, Heritrix | 10+ | | **HTTP Libraries** | Python-Requests, cURL, Wget, Scrapy | 30+ | | **Security Scanner** | Nessus, SQLMap, Nikto, Burp Suite | 15+ | | **Headless Browsers** | PhantomJS, Puppeteer, Playwright | 10+ | ### IP-basierte Erkennung Manche Bots tarnen sich mit normalem User-Agent. Diese werden ΓΌber ihre IP-Ranges erkannt: ``` Alibaba-Bot IP-Ranges: β”œβ”€β”€ 43.0.0.0/9 (Alibaba Cloud Singapore) β”œβ”€β”€ 8.128.0.0/10 (Alibaba Cloud) β”œβ”€β”€ 47.74.0.0/15 (Alibaba Cloud) β”œβ”€β”€ 39.96.0.0/13 (Aliyun China) └── ... (40+ weitere Ranges) ``` ### Generische Fallback-Patterns Falls kein spezifischer Bot erkannt wird, prΓΌft das System auf generische Begriffe: `bot`, `crawler`, `spider`, `scraper`, `fetch`, `scan`, `monitor`, `probe`, `index`, `archive`, etc. --- ## πŸ“¦ Voraussetzungen ### Dashboard Server ```bash # Python 3.8+ python3 --version # BenΓΆtigte Pakete pip3 install fastapi uvicorn python-multipart --break-system-packages # OpenSSL fΓΌr Zertifikate apt install openssl ``` ### Agent Server ```bash # Python 3.8+ python3 --version # BenΓΆtigte Pakete (NUR websockets!) pip3 install websockets --break-system-packages # PHP CLI (fΓΌr Cache-Generierung) apt install php-cli # Nginx oder Apache (muss bereits installiert sein) ``` > **Hinweis**: Der Agent benΓΆtigt KEIN `geoip2` oder `watchdog` Modul! Die GeoIP-PrΓΌfung erfolgt komplett im PHP-Skript. --- ## πŸš€ Installation ### 1. Dashboard Server (Zentral) ```bash # Verzeichnis erstellen mkdir -p /opt/jtl-wafi cd /opt/jtl-wafi # Dashboard kopieren cp jtl_wafi_dashboard.py /opt/jtl-wafi/ # Datenverzeichnis erstellen mkdir -p /var/lib/jtl-wafi/ssl # Systemd Service installieren python3 /opt/jtl-wafi/jtl_wafi_dashboard.py --install-service # Service aktivieren und starten systemctl daemon-reload systemctl enable jtl-wafi systemctl start jtl-wafi # Status prΓΌfen systemctl status jtl-wafi ``` #### Firewall konfigurieren ```bash # Port 8000 ΓΆffnen (oder anderen konfigurierten Port) ufw allow 8000/tcp ``` #### Erster Login 1. Browser ΓΆffnen: `https://dashboard-server:8000` 2. SSL-Warnung akzeptieren (selbstsigniertes Zertifikat) 3. Admin-Passwort setzen (mind. 8 Zeichen) 4. Dashboard ist einsatzbereit --- ### 2. Agent Server (Pro Shop-Server) ```bash # Verzeichnis erstellen mkdir -p /opt/jtl-wafi mkdir -p /etc/jtl-wafi mkdir -p /var/lib/jtl-wafi cd /opt/jtl-wafi # Agent kopieren cp jtl_wafi_agent.py /opt/jtl-wafi/ # Systemd Service installieren python3 /opt/jtl-wafi/jtl_wafi_agent.py --install-service # Service konfigurieren (Dashboard URL setzen) nano /etc/systemd/system/jtl-wafi-agent.service # ExecStart anpassen: # ExecStart=/usr/bin/python3 /opt/jtl-wafi/jtl_wafi_agent.py --url wss://DASHBOARD-IP:8000/ws/agent # Service aktivieren und starten systemctl daemon-reload systemctl enable jtl-wafi-agent systemctl start jtl-wafi-agent # Status prΓΌfen systemctl status jtl-wafi-agent ``` #### Agent freigeben 1. Im Dashboard erscheint der neue Agent mit Status "🟑 Warte" 2. Auf "βœ“ Freigeben" klicken 3. Agent erhΓ€lt Token und wird "🟒 Online" 4. Token wird automatisch in `/etc/jtl-wafi/token` gespeichert --- ## βš™οΈ Konfiguration ### Dashboard Umgebungsvariablen | Variable | Beschreibung | Standard | |----------|--------------|----------| | `DASHBOARD_SECRET` | Session Secret Key | Auto-generiert | ### Dashboard Kommandozeilen-Optionen ```bash python3 jtl_wafi_dashboard.py --help Options: --host TEXT Host zum Binden [default: 0.0.0.0] --port INTEGER Port [default: 8000] --no-ssl SSL deaktivieren --install-service Systemd Service erstellen ``` ### Agent Kommandozeilen-Optionen ```bash python3 jtl_wafi_agent.py --help Options: --url TEXT Dashboard WebSocket URL [default: wss://shop000.jtl-hosting.de:8000/ws/agent] --debug Debug-Logging aktivieren --install-service Systemd Service erstellen --check-deps AbhΓ€ngigkeiten prΓΌfen ``` ### Agent Pfade | Pfad | Beschreibung | |------|--------------| | `/etc/jtl-wafi/token` | Gespeicherter Auth-Token | | `/var/lib/jtl-wafi/active_shops.json` | Liste aktiver Shops mit Konfiguration | | `/var/log/jtl-wafi.log` | Agent-Logdatei (mit Rotation) | | `/var/www/vhosts/` | Shop-Verzeichnisse (Auto-Discovery) | ### GeoIP Regionen | Region | LΓ€nder | Beschreibung | |--------|--------|--------------| | `dach` | DE, AT, CH | Deutschland, Γ–sterreich, Schweiz | | `eurozone` | 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 | | `none` | - | Kein GeoIP (nur fΓΌr Bot-Mode) | ### Rate-Limit Defaults | Parameter | Wert | Beschreibung | |-----------|------|--------------| | Rate-Limit | 30 req/min | Pro Bot-Typ | | Ban-Dauer | 5 Minuten | Nach Überschreitung | | Script-GΓΌltigkeit | 72 Stunden | Danach automatische Deaktivierung | --- ## πŸ–₯️ Verwendung ### Einzelne Shops verwalten #### Aktivieren (Bot-Mode) ``` Dashboard β†’ Shop auswΓ€hlen β†’ "Aktivieren" β†’ Modus: Bot Rate-Limiting β†’ Rate-Limit: 30/min (Standard) β†’ Ban-Dauer: 5 min (Standard) ``` #### Aktivieren (GeoIP-Mode) ``` Dashboard β†’ Shop auswΓ€hlen β†’ "Aktivieren" β†’ Modus: GeoIP-Blocking β†’ Region: DACH oder Eurozone ``` #### Aktivieren (Monitor-Only) ``` Dashboard β†’ Shop auswΓ€hlen β†’ "Aktivieren" β†’ Modus: Bot Rate-Limiting β†’ β˜‘οΈ Nur Monitoring (kein Blocking) ``` #### Modus wechseln ``` Dashboard β†’ Shop-Karte klicken β†’ Detail-Modal β†’ "Modus wechseln" Button β†’ Ziel-Modus auswΓ€hlen ``` ### Massenaktionen #### Alle Shops aktivieren ``` Dashboard β†’ "⚑ Bulk-Aktivierung" β†’ Filter: Link11 / Direkt / Alle β†’ Modus und Parameter wΓ€hlen β†’ BestΓ€tigen ``` #### Alle Shops deaktivieren ``` Dashboard β†’ "πŸ›‘ Bulk-Deaktivierung" β†’ Filter: Link11 / Direkt / Alle β†’ BestΓ€tigen ``` ### Monitoring #### Live-Logs anzeigen ``` Dashboard β†’ Shop-Karte β†’ "πŸ“œ" Button β†’ Echtzeit-Log-Stream β†’ Gebannte Requests werden rot markiert ``` #### Shop-Details & Graph ``` Dashboard β†’ Shop-Karte klicken β†’ Statistiken, Top-Bots, aktive Bans β†’ Bot-AktivitΓ€ts-Graph mit Zeitachse ``` #### Alle Shops sortiert anzeigen ``` Dashboard β†’ "πŸ“Š Alle Shops" β†’ Sortieren nach: Requests/min oder Aktive Bans β†’ Klick auf Zeile ΓΆffnet Detail-Modal ``` --- ## πŸ“‘ API-Referenz ### HTTP Endpoints | Endpoint | Methode | Beschreibung | |----------|---------|--------------| | `/` | GET | Dashboard-OberflΓ€che | | `/login` | GET/POST | Login-Seite | | `/logout` | GET | Logout | | `/api/shops/activate` | POST | Shop aktivieren | | `/api/shops/deactivate` | POST | Shop deaktivieren | | `/api/shops/bulk-activate` | POST | Mehrere Shops aktivieren | | `/api/shops/bulk-deactivate` | POST | Mehrere Shops deaktivieren | | `/api/agents/approve` | POST | Agent freigeben | | `/api/change-password` | POST | Passwort Γ€ndern | ### Aktivierung Parameter | Parameter | Werte | Beschreibung | |-----------|-------|--------------| | `domain` | String | Shop-Domain | | `mode` | `bot`, `geoip` | Blocking-Modus | | `geo_region` | `dach`, `eurozone` | Nur bei GeoIP-Mode | | `rate_limit` | Integer | Requests/min (nur Bot-Mode) | | `ban_duration` | Integer | Sekunden (nur Bot-Mode) | | `bot_monitor_only` | `true`/`false` | Nur Logging (nur Bot-Mode) | --- ## πŸ”Œ WebSocket Events ### Endpoint: `/ws/agent` (Agent β†’ Dashboard) | Event | Richtung | Beschreibung | |-------|----------|--------------| | `agent.connect` | Agent β†’ Dashboard | Agent-Registrierung | | `agent.heartbeat` | Agent β†’ Dashboard | System-Status (alle 60s) | | `shop.full_update` | Agent β†’ Dashboard | Alle Shop-Daten | | `shop.stats` | Agent β†’ Dashboard | Shop-Statistiken (alle 10s) | | `log.entry` | Agent β†’ Dashboard | Log-Zeile (bei Subscription) | | `bot.banned` | Agent β†’ Dashboard | Ban-Event | | `command.result` | Agent β†’ Dashboard | Kommando-Ergebnis | | `auth.approved` | Dashboard β†’ Agent | Token nach Freigabe | | `command.activate` | Dashboard β†’ Agent | Shop aktivieren | | `command.deactivate` | Dashboard β†’ Agent | Shop deaktivieren | | `log.subscribe` | Dashboard β†’ Agent | Log-Streaming starten | | `log.unsubscribe` | Dashboard β†’ Agent | Log-Streaming stoppen | ### Endpoint: `/ws/dashboard` (Browser β†’ Dashboard) | Event | Richtung | Beschreibung | |-------|----------|--------------| | `initial_state` | Dashboard β†’ Browser | Initialer Zustand | | `refresh` | Dashboard β†’ Browser | Aktualisierte Daten | | `agent.online` | Dashboard β†’ Browser | Agent online | | `agent.offline` | Dashboard β†’ Browser | Agent offline | | `agent.pending` | Dashboard β†’ Browser | Agent wartet auf Freigabe | | `agent.approved` | Dashboard β†’ Browser | Agent freigegeben | | `shop.full_update` | Dashboard β†’ Browser | Shop-Update | | `shop.stats` | Dashboard β†’ Browser | Stats-Update | | `shop_history` | Dashboard β†’ Browser | Historie fΓΌr Graph | | `top_shops` | Dashboard β†’ Browser | Top 10 Shops | | `all_shops_sorted` | Dashboard β†’ Browser | Alle Shops sortiert | | `log.entry` | Dashboard β†’ Browser | Log-Zeile | | `bot.banned` | Dashboard β†’ Browser | Ban-Notification | | `command.result` | Dashboard β†’ Browser | Kommando-Ergebnis | | `get_shop_history` | Browser β†’ Dashboard | Historie anfordern | | `get_all_shops_sorted` | Browser β†’ Dashboard | Sortierte Liste anfordern | | `log.subscribe` | Browser β†’ Dashboard | Logs abonnieren | | `log.unsubscribe` | Browser β†’ Dashboard | Logs abbestellen | --- ## πŸ“Š Datenstrukturen ### Agent Connect ```json { "type": "agent.connect", "data": { "agent_id": "a1b2c3d4e5f6", "hostname": "shop020.jtl-hosting.de", "token": "stored-token-or-null", "version": "2.4.0", "os_info": { "system": "Linux", "release": "5.15.0", "hostname": "shop020" }, "shops_summary": { "total": 25, "active": 12 } } } ``` ### Shop Full Update ```json { "type": "shop.full_update", "data": { "domain": "example.com", "status": "active", "mode": "bot", "geo_region": "none", "rate_limit": 30, "ban_duration": 300, "bot_monitor_only": false, "link11": true, "link11_ip": "128.65.223.106", "activated": "2024-12-19T10:30:00", "runtime_minutes": 45.5, "stats": { "log_entries": 15234, "total_bans": 47, "active_bans": 3, "banned_bots": ["AhrefsBot", "SemrushBot"], "req_per_min": 45.7, "unique_ips": 234, "unique_bots": 12, "top_bots": { "Googlebot": 523, "bingbot": 234, "AhrefsBot": 189 }, "top_ips": { "66.249.66.1": 145, "157.55.39.1": 98 } } } } ``` ### Command Activate ```json { "type": "command.activate", "data": { "command_id": "cmd_abc123", "shop": "example.com", "mode": "bot", "geo_region": "none", "rate_limit": 30, "ban_duration": 300, "bot_monitor_only": false } } ``` --- ## πŸ”§ Troubleshooting ### Dashboard startet nicht ```bash # Logs prΓΌfen journalctl -u jtl-wafi -f # HΓ€ufige Ursachen: # 1. Port bereits belegt lsof -i :8000 # 2. Python-Pakete fehlen pip3 install fastapi uvicorn python-multipart --break-system-packages # 3. SSL-Verzeichnis fehlt mkdir -p /var/lib/jtl-wafi/ssl ``` ### Agent verbindet nicht ```bash # Logs prΓΌfen journalctl -u jtl-wafi-agent -f # HΓ€ufige Ursachen: # 1. Dashboard nicht erreichbar curl -k https://dashboard:8000/ # 2. Firewall blockiert telnet dashboard 8000 # 3. SSL-Zertifikat Problem (selbstsigniert) # Agent akzeptiert selbstsignierte Zertifikate automatisch # 4. websockets-Modul fehlt pip3 install websockets --break-system-packages ``` ### Agent wird nicht freigegeben ```bash # Token manuell lΓΆschen und neu verbinden rm /etc/jtl-wafi/token systemctl restart jtl-wafi-agent ``` ### Shops werden nicht erkannt ```bash # Agent Logs prΓΌfen journalctl -u jtl-wafi-agent | grep -i shop # Shop-Verzeichnisse prΓΌfen (muss index.php enthalten) ls -la /var/www/vhosts/*/httpdocs/index.php ``` ### Blocking funktioniert nicht ```bash # PrΓΌfe ob jtl-wafi.php existiert ls -la /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi.php # PrΓΌfe ob index.php modifiziert wurde head -20 /var/www/vhosts/DOMAIN/httpdocs/index.php # Sollte enthalten: require_once __DIR__ . '/jtl-wafi.php'; # PrΓΌfe Backup ls -la /var/www/vhosts/DOMAIN/httpdocs/index.php.jtl-wafi_backup # PHP-Fehler prΓΌfen tail -f /var/log/php*/error.log ``` ### GeoIP Cache-Probleme ```bash # Cache-Datei prΓΌfen ls -la /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi_ip_ranges.cache # Cache lΓΆschen (wird automatisch neu erstellt) rm /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi_ip_ranges.cache # ipdeny.com erreichbar? curl -I https://www.ipdeny.com/ipblocks/data/aggregated/de-aggregated.zone ``` ### Rate-Limit funktioniert nicht ```bash # Rate-Limit Verzeichnis prΓΌfen ls -la /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi_ratelimit/ # Berechtigungen prΓΌfen (muss 777 sein) stat /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi_ratelimit/ # Ban-Dateien anzeigen ls -la /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi_ratelimit/bans/ cat /var/www/vhosts/DOMAIN/httpdocs/jtl-wafi_ratelimit/bans/*.ban ``` ### Dashboard reagiert langsam ```bash # WebSocket Verbindungen prΓΌfen ss -tuln | grep 8000 # Memory-Nutzung prΓΌfen ps aux | grep jtl_wafi # Bei vielen Agents: Connection-Limits erhΓΆhen ulimit -n 65535 ``` --- ## πŸ“ Changelog ### v2.4.0 (2024-12) #### Neue Features - **πŸ” Monitor-Only Modus** - Bot-Erkennung ohne Blocking fΓΌr Analyse - **🌐 IP-basierte Bot-Erkennung** - Erkennt getarnte Bots (Alibaba) anhand IP-Ranges - **πŸ€– 200+ Bot-Patterns** - Massiv erweiterte Bot-Erkennung inkl. AI-Crawler - **⏱️ Heartbeat auf 60s** - Reduzierte Netzwerklast #### Verbesserungen - Modus-Wechsel direkt im Detail-Modal - Verbesserte Statistik-Auswertung fΓΌr Monitor-Mode ### v2.3.0 (2024-12) #### Neue Features - **πŸ”₯ Top 10 Shops** - Neue Übersichtskarte mit meistbelasteten Shops - **πŸ“Š Sortierbare Shop-Liste** - Modal mit allen Shops, sortierbar nach Requests oder Bans - **πŸ“ˆ Bot-AktivitΓ€ts-Graph** - Mehrere Linien pro Bot-Typ mit Zeitachse - **πŸ”„ Rebranding** - Umbenannt zu "JTL-WAFi" #### Verbesserungen - Dropdown bei Massenaktionen entfernt (Filter jetzt im Modal) - Laufzeit-Anzeige korrigiert - Graph zeigt jetzt Uhrzeiten auf X-Achse - Agent-Logging verbessert ### v2.2.0 (2024-12) #### Architektur-Γ„nderung - **In-Memory Storage** statt SQLite fΓΌr Echtzeit-Daten - Keine "database is locked" Fehler mehr - Massiv verbesserte Performance bei vielen Agents #### Neue Features - Passwort in JSON-Datei statt Datenbank - Agent-Tokens in JSON-Datei statt Datenbank ### v2.1.0 (2024-12) #### Neue Features - **Link11 Kategorisierung** - Shops werden nach CDN/Direkt getrennt - **Bulk Actions** - Massenaktivierung/-deaktivierung - **Shop Detail Modal** - AusfΓΌhrliche Statistiken und Graph - **Password Change** - Passwort im Dashboard Γ€ndern - **Live Clock** - Echtzeit-Uhr im Header - **Shop Link Button** - Direktlink zum Shop #### Fixes - Agent Ctrl+C Shutdown funktioniert jetzt sofort - Asyncio Signal Handler korrekt implementiert ### v2.0.0 (2024-12) #### Komplett neu - WebSocket-basierte Architektur - Echtzeit-Updates ohne Polling - Multi-Agent Support - Neue moderne UI - PHP-basiertes Blocking (kein iptables) --- ## πŸ“„ Lizenz MIT License - siehe [LICENSE](LICENSE) --- ## 🀝 Contributing 1. Fork erstellen 2. Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Commit (`git commit -m 'Add AmazingFeature'`) 4. Push (`git push origin feature/AmazingFeature`) 5. Pull Request erstellen --- ## πŸ“ž Support Bei Fragen oder Problemen: - GitHub Issues ΓΆffnen - Logs beifΓΌgen (`journalctl -u jtl-wafi -n 100`) --- **Made with ❀️ for JTL-Shop Hosting**