- Utilisation de 2 requêtes séparées + fusion en Python
- 1ère requête: ml_detected_anomalies pour les détections récentes
- 2ème requête: view_dashboard_entities avec IN clause pour les user-agents
- La clause IN permet d'utiliser l'index ClickHouse (splitByChar ne l'utilise pas)
- PREWHERE optimise les performances de requête
Problème résolu:
- unique_ua était toujours à 0 car la jointure LEFT JOIN ne fonctionnait pas
- La solution avec IN clause fonctionne car elle utilise l'index sur entity_value
Testé avec 141.98.11.0/24:
- 5 IPs, 8 détections, 65 user-agents uniques
- 141.98.11.209: 68 user-agents différents
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Nouveau service backend/services/reputation_ip.py
- IP-API.com: Géolocalisation + détection Proxy/Hosting
- IPinfo.io: ASN + Organisation
- Agrégation des sources avec score de menace 0-100
- Niveaux: clean/low/medium/high/critical
- Nouvelle route API GET /api/reputation/ip/:ip
- Validation IPv4
- Version complète et summary
- Timeout 10s par source
- Nouveau composant frontend ReputationPanel.tsx
- Badge de niveau de menace (code couleur)
- 4 badges détection: Proxy 🌐, Hosting ☁️, VPN 🔒, Tor 🧅
- Infos géographiques: pays, ville, ASN, organisation
- Liste des avertissements
- Sources et timestamp
- Intégration dans InvestigationView
- Panel affiché en premier (avant Graph de corrélations)
- Chargement asynchrone au montage du composant
- Dépendance: httpx==0.26.0 (requêtes HTTP async)
Testé avec 141.98.11.209 (Lithuania, AS209605) → 🟢 CLEAN (0/100)
Aucun proxy/hosting/VPN/Tor détecté
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Nouveau endpoint API GET /api/entities/subnet/:subnet
- Utilise view_dashboard_entities (données agrégées)
- Retourne stats globales + liste détaillée des IPs
- Filtre par les 3 premiers octets du subnet
- Nouveau composant frontend SubnetInvestigation.tsx
- Affiche toutes les IPs d'un subnet /24
- Tableau avec: IP, détections, JA4, UA, pays, ASN, menace, score
- Boutons 'Investiguer' et 'Détails' par IP
- URL simplifiée: /entities/subnet/x.x.x.x_24 (_ au lieu de /)
- Évite les problèmes d'encodage URL
- Conversion automatique _ → / côté frontend
- Correction route ordering dans App.tsx
- /entities/subnet/:subnet avant /entities/:type/:value
- Routes backend réordonnées
- /api/entities/subnet/:subnet avant les routes génériques
Testé avec 141.98.11.0/24 → 6 IPs trouvées, 1677 détections
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
🐛 PROBLÈME:
• ClickHouse stocke IPv4 en IPv6 (::ffff:x.x.x.x)
• Docker utilisait un cache et n'appliquait pas les modifs
• subnet et sample_ip avaient toujours ::ffff:
✅ SOLUTION:
• CTE cleaned_ips avec replaceRegexpAll pour enlever ::ffff:
• argMax(clean_ip, detected_at) pour sample_ip
• Rebuild complet avec --no-cache
RÉSULTAT:
• Avant: subnet='::ffff:176.65.132.0/24', sample_ip=null ❌
• Après: subnet='176.65.132.0/24', sample_ip='176.65.132.19' ✅📝 COMMANDE DE REBUILD:
docker compose down && docker build --no-cache -t dashboard-dashboard_web . && docker compose up -d
✅ TESTÉ ET VALIDÉ
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
🐛 CORRECTION:
• Problème: Les IPs n'étaient pas trouvées
• Cause: Utilisation du subnet (176.65.132.0) au lieu d'une IP réelle
• Solution: Ajout sample_ip + fallback getSampleIP()
BACKEND:
• API /api/incidents/clusters retourne sample_ip
• Utilisation de any(src_ip) dans la requête SQL
• Fallback sur None si pas d'IP trouvée
FRONTEND:
• Interface IncidentCluster: sample_ip optionnel
• Fonction getSampleIP() génère une IP depuis le subnet
• Fallback: sample_ip || getSampleIP(subnet)
• Tous les boutons utilisent la même logique
RÉSULTAT:
• Avant: /entities/ip/176.65.132.0 (n'existe pas)
• Après: /entities/ip/176.65.132.1 (IP valide)
✅ Build: SUCCESS
✅ Container: restarted
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>