Files
ja4-platform/docs/services/dashboard.md
toto 51dd376f7a docs: mise à jour complète — 7/8 techniques, 85 features, 12 modules
Reflète l'état réel du système après les étapes 1-9 du roadmap :

- §5.2 (fleet_detector NetworkX/Louvain) et §5.8 (Jaccard cross-domain) : 
- MetaLearner (régression logistique, fallback poids fixes) : documenté
- ExIFFI (profondeur isolation EIF) + erreur AE par feature : documenté
- KL divergence en complément du KS, drift adversarial : documenté
- HTTP/2 fingerprinting (h2_fingerprint, dict_browser_h2, axis_h2_coherence) : documenté
- Métriques de cycle (metrics.py, ml_performance_metrics, alertes) : documenté
- Browser confidence : 5 axes → 6 axes (axis_h2_coherence)
- 85 features (73 FEATURES + 12 FEATURES_COMPLET), 12 modules, 53 routes dashboard
- Conformité thèse : 99.4% (était 97.9%), §5 : 87.5% (était 62.5%)
- Tables nouvelles : fleet_detections, ml_performance_metrics, soc_feedback
- Dictionnaires : 8 (dict_browser_h2 ajouté)
- Dashboard : 16 pages + 37 API routes (fleet, health ajoutés)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 01:31:20 +02:00

16 KiB
Raw Blame History

Dashboard

Application web SOC (Security Operations Center) construite avec FastAPI + Jinja2 + htmx, offrant la visualisation en temps réel, l'investigation et l'analyse des détections de bots générées par le bot-detector. Interroge ClickHouse sur deux bases de données (ja4_processing et ja4_logs).


Pile technologique

Composant Technologie
Backend Python 3.11 + FastAPI
Templates Jinja2 (rendu côté serveur)
Interactions dynamiques htmx (mises à jour partielles via JSON API)
Graphiques Chart.js + ECharts
Style Tailwind CSS (CDN)
Base de données ClickHouse via clickhouse-connect (client propre, PAS ja4_common)
Documentation API Swagger UI (/docs) + OpenAPI JSON (/openapi.json)

Note : le dashboard n'utilise pas la bibliothèque partagée ja4_common. Il possède son propre client ClickHouse léger dans backend/database.py.


Structure des fichiers

services/dashboard/
├── backend/
│   ├── __init__.py
│   ├── main.py            Application FastAPI, montage templates + static, CORS, health
│   ├── config.py           Variables d'environnement, safe_identifier()
│   ├── database.py         Client clickhouse-connect singleton, query(), query_scalar(), execute()
│   └── routes/
│       ├── __init__.py
│       ├── api.py          37 routes JSON (1700+ lignes)
│       └── pages.py        16 routes de pages HTML (100+ lignes)
├── templates/
│   ├── base.html           Template de base (layout, navigation, Tailwind CDN)
│   ├── overview.html       Vue d'ensemble du dashboard
│   ├── detections.html     Tableau paginé des détections d'anomalies
│   ├── scores.html         Tableau paginé de tous les scores ML
│   ├── traffic.html        Tableau paginé du trafic HTTP brut
│   ├── ip_detail.html      Investigation détaillée d'une IP
│   ├── ja4_detail.html     Investigation détaillée d'une empreinte JA4
│   ├── cluster_detail.html Investigation détaillée d'un cluster/campagne
│   ├── campaigns.html      Vue des campagnes HDBSCAN
│   ├── features.html       Analyse des features ML
│   ├── models.html         Métadonnées et performances des modèles
│   ├── classify.html       Interface de classification SOC
│   ├── tactics.html        Tactiques de détection (brute-force, rotation, récurrence)
│   ├── reflists.html       Listes de référence et dictionnaires ClickHouse
│   ├── network.html        Graphe réseau des campagnes
│   ├── fleet.html          Détections de flottes coordonnées (graphe bipartite)
│   └── health.html         Santé du pipeline — métriques de performance par cycle
└── static/                 Fichiers statiques (JS, CSS)

Configuration

Toute la configuration est lue via os.getenv() dans backend/config.py.

Variable Type Défaut Description
CLICKHOUSE_HOST str localhost Nom d'hôte du serveur ClickHouse
CLICKHOUSE_PORT int 8123 Port HTTP ClickHouse
CLICKHOUSE_USER str default Utilisateur ClickHouse
CLICKHOUSE_PASSWORD str "" Mot de passe ClickHouse
CLICKHOUSE_DB_PROCESSING str ja4_processing Base de données ML/agrégations (fallback : CLICKHOUSE_DB)
CLICKHOUSE_DB_LOGS str ja4_logs Base de données des logs HTTP
API_HOST str 0.0.0.0 Adresse d'écoute du serveur
API_PORT int 8000 Port d'écoute du serveur

Schéma dual-database

Le dashboard utilise deux bases de données ClickHouse :

  • CLICKHOUSE_DB_PROCESSING (ja4_processing) : tables ML, agrégations, dictionnaires, feedback SOC
  • CLICKHOUSE_DB_LOGS (ja4_logs) : http_logs, trafic brut

Les noms de bases sont validés par safe_identifier() (regex alphanumérique + underscore) avant injection dans les requêtes SQL.

Dualité IPv4/IPv6

  • http_logs.src_ip est de type IPv4
  • Les tables ML (ml_all_scores, ml_detected_anomalies) stockent IPv6 (mappé ::ffff:x.x.x.x)
  • Utiliser toIPv6() pour les requêtes sur les tables ML
  • Utiliser toIPv4OrZero() pour les requêtes sur http_logs
  • Retirer le préfixe ::ffff: à l'affichage

Couche base de données (backend/database.py)

Client clickhouse-connect avec singleton paresseux :

Fonction Signature Description
get_client() → Client Singleton clickhouse_connect.get_client()
query(sql, params) → list[dict] Exécute un SELECT, retourne une liste de dicts
query_scalar(sql, params) → Any Exécute un SELECT, retourne une valeur scalaire
execute(sql, params) → None Exécute un DDL/DML sans retour

Conversion automatique des types : IPv4Address, IPv6Address, bytes → chaînes JSON-friendly.

Patron de requêtes paramétrées

from backend.config import DB_PROCESSING, DB_LOGS, safe_identifier
from backend.database import query, query_scalar

_DB = safe_identifier(DB_PROCESSING)
rows = query(
    f"SELECT src_ip, anomaly_score FROM {_DB}.ml_detected_anomalies "
    "WHERE src_ip = toIPv6({ip:String}) ORDER BY detected_at DESC LIMIT 10",
    {"ip": ip_value},
)

Routes de pages (16)

Toutes les pages sont rendues côté serveur via Jinja2 et utilisent htmx pour les mises à jour dynamiques.

# Chemin Template Description
1 / overview.html Vue d'ensemble : statistiques 24h, distribution des menaces, top IPs, timeline
2 /detections detections.html Tableau paginé des détections d'anomalies avec filtres
3 /scores scores.html Tableau paginé de tous les scores ML avec filtres
4 /traffic traffic.html Tableau paginé des logs HTTP bruts avec filtres
5 /ip/{ip} ip_detail.html Investigation détaillée d'une IP (détections, scores, logs, features, récurrence)
6 /classify classify.html Interface de classification SOC (feedback analyste)
7 /features features.html Analyse des features ML (profils humain/bot, importance)
8 /models models.html Métadonnées des modèles, statistiques de scoring
9 /network network.html Graphe réseau des campagnes (IP ↔ JA4 partagés)
10 /campaigns campaigns.html Campagnes HDBSCAN (clusters de bots agrégés)
11 /ja4/{fingerprint:path} ja4_detail.html Investigation détaillée d'une empreinte JA4
12 /cluster/{cid} cluster_detail.html Investigation détaillée d'un cluster
13 /tactics tactics.html Tactiques de détection (brute-force, rotation JA4/UA, récurrence)
14 /reflists reflists.html Listes de référence et dictionnaires ClickHouse
15 /fleet fleet.html Détections de flottes coordonnées — graphe bipartite JA4×ASN, communautés, fleet_score
16 /health health.html Santé du pipeline — métriques de cycle, alertes calibration/drift/corrélation/latence

Routes API (37)

Toutes les routes sont préfixées par /api et retournent du JSON. Utilisées par htmx depuis les templates et consommables par des clients externes.

Vue d'ensemble et statistiques

# Méthode Chemin Description
1 GET /api/overview Résumé du dashboard : détections/scores/trafic 24h, distribution des menaces, top IPs, timeline, modèles, statistiques navigateur
2 GET /api/heatmap Heatmap temporelle (heure × jour de semaine) depuis http_logs
3 GET /api/geo Répartition géographique et ASN des sessions
4 GET /api/alerts Flux d'alertes en direct (détections récentes HIGH/CRITICAL)
5 GET /api/timeline-detail Détail horaire de la timeline par niveau de menace

Détections et scores

# Méthode Chemin Description
6 GET /api/detections Liste paginée des détections d'anomalies avec filtres (threat_level, search, asn, country, ja4, bot, browser) et tri
7 GET /api/scores Liste paginée des scores ML avec filtres similaires
8 GET /api/traffic Liste paginée des logs HTTP bruts avec filtres

Investigation IP

# Méthode Chemin Description
9 GET /api/ip/{ip} Détail IP : détections, scores, logs HTTP, features AI, récurrence
10 GET /api/ip/{ip}/radar Données pour graphique radar : IP vs baseline ISP vs baseline bot

Features et modèles

# Méthode Chemin Description
11 GET /api/features Statistiques des features AI/thèse, profils humain/bot, importance (variance)
12 GET /api/models Métadonnées des modèles depuis fichiers JSON + statistiques de scoring ClickHouse
13 GET /api/models/timeline Volume horaire de scoring par modèle (7 jours)
14 GET /api/models/threats Répartition des niveaux de menace par modèle

Empreintes et navigateurs

# Méthode Chemin Description
15 GET /api/fingerprints Analyse des empreintes JA4 avec mapping de bots
16 GET /api/browsers Distribution des familles de navigateurs via JA4
17 GET /api/behavior Données scatter des features comportementales + distributions

Classification SOC

# Méthode Chemin Description
18 GET /api/classify/stats Résumé statistique des classifications SOC
19 GET /api/classify/suggested Top des IPs non classifiées triées par sévérité
20 POST /api/classify Soumettre un feedback analyste SOC (bot/legitimate/suspicious)
21 GET /api/classifications Entrées de feedback SOC récentes

Campagnes et clusters

# Méthode Chemin Description
22 GET /api/campaigns Clusters de campagnes HDBSCAN (agrégés)
23 GET /api/campaigns/graph Données de graphe réseau (nœuds IP + arêtes JA4 partagés)
24 GET /api/campaigns/scatter Scatter plot : score d'anomalie vs vélocité par IP et campagne
25 GET /api/campaigns/{cid} Détail campagne : membres, profil, timeline

Investigation JA4 et cluster

# Méthode Chemin Description
26 GET /api/ja4/{fingerprint:path} Investigation d'empreinte JA4 (IPs, scores, logs, features)
27 GET /api/cluster/{cid} Investigation enrichie de cluster (profil, membres, graphe, répartitions)

Tactiques de détection

# Méthode Chemin Description
28 GET /api/brute-force Détection de brute-force / credential stuffing
29 GET /api/ja4-rotation Détection de rotation d'empreintes JA4 (évasion)
30 GET /api/recurrence IPs de menaces persistantes/récurrentes
31 GET /api/cascade/{ip} Cascade de ressources pour détection de navigateur headless
32 GET /api/ua-rotation Détection de rotation de User-Agent

Flottes et santé

# Méthode Chemin Description
33 GET /api/fleet Flottes de bots coordonnées — communautés JA4×ASN, fleet_score, IPs membres
34 GET /api/health Métriques de performance du pipeline — cycle, drift, corrélation, alertes

Dictionnaires et listes de référence

# Méthode Chemin Description
35 GET /api/dictionaries Métadonnées des 8 dictionnaires ClickHouse
36 GET /api/reflist/{name} Contenu paginé d'une liste de référence / dictionnaire
37 GET /api/reflist/{name}/stats Statistiques agrégées d'une liste de référence

Autres routes

Méthode Chemin Description
GET /health Point de santé — retourne l'état de connexion ClickHouse
/static Montage de fichiers statiques (backend/static/)
GET /docs Documentation Swagger UI (auto-généré par FastAPI)
GET /openapi.json Schéma OpenAPI (auto-généré par FastAPI)

Total : 16 pages + 37 API + 1 health check = 54 routes applicatives


Paramètres de requête courants

Les endpoints paginés (/api/detections, /api/scores, /api/traffic) acceptent :

Paramètre Type Description
page int Numéro de page (défaut : 1)
page_size int Éléments par page (défaut : 20)
threat_level str Filtre par niveau de menace
model_name str Filtre par nom de modèle
search str Recherche plein texte (IP, JA4, host, bot_name)
sort_by str Champ de tri (validé contre une whitelist)
sort_order str asc ou desc

Workflow SOC

Le dashboard est conçu pour le workflow d'un analyste SOC :

  1. Vue d'ensemble (/) — identifier les tendances de menaces 24h, les pics d'anomalies
  2. Détections (/detections) — filtrer les anomalies par sévérité, rechercher des IPs spécifiques
  3. Investigation IP (/ip/{ip}) — examiner les détections, scores, logs HTTP, features ML, radar de comparaison
  4. Analyse JA4 (/ja4/{fp}) — investiguer une empreinte TLS, voir toutes les IPs associées
  5. Campagnes (/campaigns) — visualiser les clusters de bots, graphe réseau, scatter plot
  6. Cluster (/cluster/{cid}) — plonger dans un cluster spécifique, examiner les membres et profils
  7. Flottes (/fleet) — visualiser les communautés de botnets coordonnées (graphe bipartite JA4×ASN)
  8. Tactiques (/tactics) — surveiller le brute-force, la rotation JA4/UA, les menaces récurrentes
  9. Classification (/classify) — soumettre un feedback analyste (bot/légitime/suspect) pour alimenter XGBoost et le MetaLearner
  10. Features (/features) — comparer les profils de features humain vs bot
  11. Modèles (/models) — surveiller les performances des modèles ML
  12. Santé (/health) — métriques de cycle, alertes de calibration, drift, corrélation et latence

Architecture des templates

Template de base (base.html)

Fournit le layout commun :

  • Navigation latérale avec liens vers toutes les pages
  • Chargement CDN de Tailwind CSS, htmx, Chart.js, ECharts
  • Bloc {% block content %} pour le contenu de chaque page

Rendu côté serveur + htmx

Chaque page est rendue côté serveur par Jinja2. Les interactions dynamiques utilisent htmx :

<!-- Exemple : chargement dynamique des détections -->
<div hx-get="/api/detections?page=1&page_size=20"
     hx-trigger="load"
     hx-target="#detections-table">
</div>

Les graphiques sont rendus côté client par Chart.js et ECharts à partir des données JSON de l'API.


CORS

Le middleware CORS est configuré de manière permissive dans main.py :

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

L'application est principalement SSR mais l'API JSON est aussi consommable par des clients externes.


Déploiement

# Construction de l'image Docker
make build-dashboard

# Tests
make test-dashboard

# Exécution locale (développement)
cd services/dashboard
uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000

Point de santé

GET /health → {"status": "healthy", "clickhouse": "connected"}