docs: rewrite architecture/README, update deployment/development

- architecture.md: complete rewrite (French) with dual-database diagram,
  5-phase data flow, full table ownership, triple-voice ML pipeline,
  7 dictionaries, 13 SQL files, updated tech stack
- README.md: complete rewrite (English) with updated pipeline diagram,
  services table, scripts section, integration tests, full doc index,
  Go 1.24.6 workspace
- deployment.md: update to 13 SQL files, remove Anubis UA/Country refs,
  add scripts section, add ensemble env vars (AE_WEIGHT, XGB_WEIGHT),
  update verification queries and network diagram
- development.md: translate to French, add bot-detector 11-module structure,
  add Python ML deps, add scripts/integration test sections,
  fix bot-detector run command, add make targets

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-09 22:00:29 +02:00
parent 7bdc6e2865
commit d05969867f
4 changed files with 578 additions and 282 deletions

View File

@ -1,162 +1,285 @@
# Architecture
The ja4-platform is a security pipeline that captures live network traffic, generates JA4/JA3 TLS fingerprints, correlates them with HTTP requests, applies machine-learning anomaly detection, and surfaces results through a SOC analyst dashboard. ClickHouse serves as the central data store linking all services.
ja4-platform est un pipeline de sécurité qui capture le trafic réseau en temps réel, génère des empreintes TLS JA4/JA3, corrèle les handshakes TLS avec les requêtes HTTP, applique une détection d'anomalies par apprentissage automatique (ensemble triple voix), et présente les résultats dans un tableau de bord SOC. ClickHouse sert de magasin central reliant tous les services, organisé en deux bases de données distinctes.
## System Architecture
## Architecture système
```
┌───────────────────────────────────────────────────────────────────────────────────┐
Target Linux Server
│ │
│ ┌─────────────┐ HTTP req ┌───────────────────────┐ UNIX socket (DGRAM)
│ │ Client │────────────▶│ Apache HTTPD │──────────────┐
│ │ (browser / │ │ + mod-reqin-log
│ │ bot) │ └──────────────────────┘
│ │ │
│ │ │ TLS CH ┌───────────────────────┐ ┌─────────────────────┐
│ │ │────────────▶│ sentinel correlator
│ │ │ (pcap) │ (packet capture) │──▶│ (event join)
└─────────────┘ └───────────────────────┘ └────────┬────────────┘
└────────────────────────────────────────────────────────────────────┼──────────────┘
INSERT JSON
┌─────────────────────┐
ClickHouse
│ ja4_processing
http_logs_raw
──(MV)──▶ http_logs
│ ──(MV)──▶ agg_* │
│ view_ai_features │
│ ml_detected_anom. │
│ ml_all_scores │
└──────┬──────┬───────┘
┌──────────────────┘ └──────────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ bot-detector │ │ dashboard
(Python) │ │ (FastAPI + React)
│ │ │
│ Reads: │ Reads:
│ view_ai_features ml_detected_anom.
view_ip_recurrence │ │ ml_all_scores
│ Writes: │ http_logs
│ ml_detected_anom. │ │ agg_* tables
│ ml_all_scores audit_logs
└──────────────────────┘ └──────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────
Serveur Linux cible (Apache)
│ ┌─────────────────┐ HTTP req ┌───────────────────────┐
│ │ Client │────────────▶│ Apache HTTPD
│ │ (navigateur / │ │ + mod-reqin-log (C) │ │
│ │ bot) │ └──────────────────────┘ │
│ │ │ JSON / UNIX DGRAM
│ │ │ │ /var/run/logcorrelator/http.socket
│ │ │ ▼
│ │ │ TLS CH ┌──────────────────────────────────────┐
│ │────────────▶│ sentinel (Go · libpcap) │
└─────────────────┘ (pcap) → JA4/JA3 fingerprints │ │
│ └───────────┬──────────────────────────┘
JSON / UNIX DGRAM │
│ /var/run/logcorrelator/network.socket│
▼ │
┌───────────────────────────────┐
correlator (Go · hex. arch) │
join src_ip:src_port + TTL │
└───────────┬───────────────────┘
└───────────────────────────────────────────────┼─────────────────────────────────────┘
│ INSERT (Native TCP :9000)
┌───────────────────────────────────────────────────────┐
ClickHouse 24.8
│ ja4_logs ja4_processing │
┌────────────────┐ ┌────────────────────┐ │
│ │ http_logs_raw │──(MV)──▶ │ agg_host_ip_ja4_1h│ │
│ │ ↓ mv_http_logs │ agg_header_fp_1h │
http_logs │──(MVs)──▶│ agg_path_seq_1h │
│ └────────────────┘ │ agg_request_tm_1h│
agg_ip_behavior_1h│
agg_resource_cas_1h│
│ ml_detected_anom. │
│ ml_all_scores
│ view_ai_features
view_thesis_feat. │
│ audit_logs, dicts │ │
│ └────────────────────┘ │
└──────────┬──────────────────────────┬────────────────┘
│ SELECT │ SELECT / INSERT
┌──────────────┘ └──────────────┐
▼ ▼
┌───────────────────────┐ ┌───────────────────────┐
│ bot-detector │ │ dashboard │
│ Python 3.11 │ │ FastAPI + Jinja2 │
│ │ │ htmx + Chart.js │
│ Lit : │ │ Tailwind CSS (CDN) │
│ view_ai_features_1h │ │ │
│ view_thesis_feat_1h │ │ 55 routes (API+pages) │
│ view_ip_recurrence │ │ 15 templates Jinja2 │
│ Écrit : │ │ 14 pages SOC │
│ ml_detected_anomalies│ │ │
│ ml_all_scores │ │ Lit : ml_*, agg_*, │
└───────────────────────┘ │ http_logs, audit_logs│
└───────────────────────┘
```
## Data Flow
## Flux de données — 5 phases
### 1. Capture Phase
### Phase 1 — Capture
1. **mod-reqin-log** (Apache C module) hooks into `post_read_request`. On each HTTP request, it serializes method, path, headers, client IP/port into JSON and sends it via UNIX datagram socket to `/var/run/logcorrelator/http.socket`.
1. **mod-reqin-log** (module Apache C11) intercepte chaque requête HTTP dans le hook `post_read_request`. Il sérialise method, path, headers, client IP/port en JSON et envoie le datagramme vers `/var/run/logcorrelator/http.socket`.
2. **sentinel** (Go daemon) uses libpcap to capture live TLS ClientHello packets on configured ports (default: 443, 8443). It extracts IP/TCP metadata, generates JA4 and JA3 fingerprints, and sends the result as JSON via UNIX datagram socket to `/var/run/logcorrelator/network.socket`.
2. **sentinel** (démon Go) capture les paquets TLS ClientHello via libpcap sur les ports configurés (défaut : 443, 8443). Il extrait les métadonnées IP/TCP, génère les empreintes JA4 et JA3, et envoie le résultat en JSON vers `/var/run/logcorrelator/network.socket`.
### 2. Correlation Phase
### Phase 2 — Corrélation
3. **correlator** (Go daemon) listens on both UNIX sockets. It buffers incoming events and correlates them by matching `src_ip:src_port` within a configurable time window (default: 10 s). HTTP Keep-Alive connections are supported via `one_to_many` matching mode where a single TLS handshake (source B) is reused for multiple HTTP requests (source A). Correlated events merge HTTP fields (method, path, headers) with TLS fields (JA4, JA3, IP/TCP metadata) into a single `CorrelatedLog` JSON object, which is inserted into `http_logs_raw`.
3. **correlator** (démon Go, architecture hexagonale) écoute les deux sockets Unix. Il met en tampon les événements entrants et les corrèle par `src_ip:src_port` dans une fenêtre temporelle configurable (défaut : 10 s). Le mode `one_to_many` (Keep-Alive) permet de réutiliser un seul handshake TLS (source B) pour plusieurs requêtes HTTP (source A). Les événements corrélés fusionnent les champs HTTP + TLS en un objet `CorrelatedLog` JSON, inséré dans **`ja4_logs.http_logs_raw`**.
### 3. Enrichment Phase (ClickHouse)
### Phase 3 — Enrichissement (ClickHouse)
4. **mv_http_logs** materialized view automatically transforms `http_logs_raw` JSON into the structured `http_logs` table, enriching each row with:
- ASN/geo data via `dict_iplocate_asn`
- Anubis bot identification via `dict_anubis_ua`, `dict_anubis_ip`, `dict_anubis_asn`, `dict_anubis_country`
4. **mv_http_logs** (vue matérialisée) transforme le JSON de `http_logs_raw` en la table structurée `ja4_logs.http_logs`, enrichissant chaque ligne avec :
- Données ASN via `dict_iplocate_asn` (IP_TRIE)
- Identification Anubis via `dict_anubis_ip` (IP_TRIE) et `dict_anubis_asn` (FLAT) — règles IP/CIDR + ASN uniquement, avec priorité COALESCE(IP, ASN)
5. **mv_agg_host_ip_ja4_1h** and **mv_agg_header_fingerprint_1h** aggregate `http_logs` into 1-hour behavioral windows.
5. **6 vues matérialisées d'agrégation** alimentent les tables `ja4_processing.agg_*` en fenêtres comportementales d'1 heure :
- `agg_host_ip_ja4_1h` — Agrégations par (host, src_ip, ja4)
- `agg_header_fingerprint_1h` — Empreintes d'en-têtes HTTP
- `agg_path_sequences_1h` — Séquences de chemins (n-grams)
- `agg_request_timing_1h` — Métriques de timing inter-requêtes
- `agg_ip_behavior_1h` — Comportement réseau par IP
- `agg_resource_cascade_1h` — Cascades de ressources
6. **view_ai_features_1h** joins the two aggregation tables and computes 50+ ML features per `(src_ip, ja4, host)` tuple.
6. **view_ai_features_1h** joint les tables d'agrégation et calcule ~63 features ML par tuple `(src_ip, ja4, host)`.
### 4. Detection Phase
### Phase 4 — Détection
7. **bot-detector** (Python) runs on a 5-minute cycle:
- Reads `view_ai_features_1h` for the last 24 hours
- Separates known bots (via reputation dictionaries) from unknown traffic
- Trains/loads Isolation Forest models on human-baseline traffic
- Scores unknown traffic and writes anomalies to `ml_detected_anomalies` and all scores to `ml_all_scores`
7. **bot-detector** (Python 3.11, 11 modules) s'exécute en cycle de 5 minutes :
- **Pipeline bifurqué** :
- **Complet** (L3→L7, ~63 features, `correlated=1`) — trafic corrélé TCP+TLS+HTTP
- **Applicatif** (L7 seulement, ~51 features, `correlated=0`) — trafic HTTP non corrélé
- **Ensemble triple voix** :
- **Extended Isolation Forest** (isotree) — scoreur non supervisé principal
- **Autoencoder** (PyTorch, architecture n→64→32→16→32→64→n) — erreur de reconstruction
- **XGBoost** — supervisé, entraîné sur les labels SOC (`soc_feedback`)
- **Score final** : `final = (1-β) × ((1-α) × eif_norm + α × ae_norm) + β × xgb_prob` (α=0.30, β=0.20)
- **Seuil adaptatif** par percentile, détection de dérive conceptuelle
- **HDBSCAN** — regroupement en campagnes d'attaque
- **Détection de navigateur** — 5 axes multifactoriels (confiance ≥ 0.55 → `LEGITIMATE_BROWSER`)
- **Explicabilité SHAP** — contribution de chaque feature au score d'anomalie
- **Niveaux de menace** : `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `NORMAL`, `LEGITIMATE_BROWSER`, `KNOWN_BOT`, `ANUBIS_DENY`, `ANUBIS_ALLOW`
### 5. Visualization Phase
### Phase 5 — Visualisation
8. **dashboard** (FastAPI + React) queries ClickHouse to display detections, feature analysis, investigation summaries, and clustering to SOC analysts.
8. **dashboard** (FastAPI + Jinja2 + htmx + Chart.js + Tailwind CSS CDN) expose 55 routes (35 API JSON + 14 pages HTML + health/static) et 15 templates Jinja2 pour les analystes SOC :
- Pages : overview, detections, scores, traffic, ip_detail, ja4_detail, cluster_detail, campaigns, features, models, classify, tactics, reflists, network
## Component Interaction Matrix
## Matrice d'interaction des composants
| From → To | mod-reqin-log | sentinel | correlator | ClickHouse | bot-detector | dashboard |
|-----------|:---:|:---:|:---:|:---:|:---:|:---:|
| **mod-reqin-log** | — | — | UNIX socket (DGRAM) | — | — | — |
| **sentinel** | — | — | UNIX socket (DGRAM) | — | — | — |
| De ↓ \ Vers → | mod-reqin-log | sentinel | correlator | ClickHouse | bot-detector | dashboard |
|----------------|:---:|:---:|:---:|:---:|:---:|:---:|
| **mod-reqin-log** | — | — | UNIX DGRAM (source A) | — | — | — |
| **sentinel** | — | — | UNIX DGRAM (source B) | — | — | — |
| **correlator** | — | — | — | Native TCP :9000 (INSERT) | — | — |
| **ClickHouse** | — | — | — | | — | — |
| **ClickHouse** | — | — | — | MVs internes | — | — |
| **bot-detector** | — | — | — | HTTP :8123 (SELECT/INSERT) | — | — |
| **dashboard** | — | — | — | HTTP :8123 (SELECT/INSERT) | — | — |
## ClickHouse Table Ownership
## Propriété des tables ClickHouse
| Table/View | Written By | Read By |
|------------|-----------|---------|
### Base `ja4_logs`
| Table / Vue | Écrit par | Lu par |
|-------------|-----------|--------|
| `http_logs_raw` | correlator | mv_http_logs (MV) |
| `http_logs` | mv_http_logs (MV) | mv_agg_*, dashboard |
| `agg_host_ip_ja4_1h` | mv_agg_host_ip_ja4_1h (MV) | view_ai_features_1h |
| `agg_header_fingerprint_1h` | mv_agg_header_fingerprint_1h (MV) | view_ai_features_1h |
| `view_ai_features_1h` | — (view) | bot-detector |
| `view_ip_recurrence` | — (view) | bot-detector |
| `http_logs` | mv_http_logs (MV) | mv_agg_* (6 MVs), dashboard |
| `mv_http_logs` | — (MV automatique) | — |
### Base `ja4_processing`
| Table / Vue | Écrit par | Lu par |
|-------------|-----------|--------|
| `agg_host_ip_ja4_1h` | mv_agg_host_ip_ja4_1h | view_ai_features_1h, dashboard |
| `agg_header_fingerprint_1h` | mv_agg_header_fingerprint_1h | view_ai_features_1h, dashboard |
| `agg_path_sequences_1h` | mv_agg_path_sequences_1h | view_thesis_features_1h |
| `agg_request_timing_1h` | mv_agg_request_timing_1h | view_thesis_features_1h |
| `agg_ip_behavior_1h` | mv_agg_ip_behavior_1h | view_thesis_features_1h |
| `agg_resource_cascade_1h` | mv_agg_resource_cascade_1h | view_thesis_features_1h |
| `ml_detected_anomalies` | bot-detector | dashboard |
| `ml_all_scores` | bot-detector | dashboard |
| `audit_logs` | dashboard | dashboard |
| `anubis_ip_rules` | fetch_rules.py | dict_anubis_ip |
| `anubis_asn_rules` | fetch_rules.py | dict_anubis_asn |
| `ref_bot_networks` | update-csv-data.sh | dict_bot_ip |
| `bot_ip` | update-csv-data.sh | dict_bot_ip |
| `bot_ja4` | update-csv-data.sh | dict_bot_ja4 |
| `view_ai_features_1h` | — (vue) | bot-detector |
| `view_ip_recurrence` | — (vue) | bot-detector |
| `view_thesis_features_1h` | — (vue) | bot-detector |
| `view_form_bruteforce_detected` | — (vue) | dashboard |
| `view_host_ip_ja4_rotation` | — (vue) | dashboard |
| `view_dashboard_user_agents` | — (vue) | dashboard |
| `view_dashboard_entities` | — (vue) | dashboard |
| `view_resource_cascade_1h` | — (vue) | dashboard |
## Correlation Algorithm
### Dictionnaires (7)
The correlator joins HTTP events (source A) with TLS/network events (source B) using a two-key correlation:
| Dictionnaire | Layout | Source | Utilisation |
|--------------|--------|--------|-------------|
| `dict_iplocate_asn` | IP_TRIE | Fichier CSV | Géolocalisation IP → ASN |
| `dict_bot_ip` | IP_TRIE | Table `bot_ip` | IPs de bots connues |
| `dict_bot_ja4` | COMPLEX_KEY_HASHED | Table `bot_ja4` | Signatures JA4 de bots |
| `dict_browser_ja4` | COMPLEX_KEY_HASHED | Table (CSV) | Signatures JA4 de navigateurs |
| `dict_asn_reputation` | HASHED | Fichier CSV | Réputation ASN (isp/datacenter/hosting/cdn) |
| `dict_anubis_ip` | IP_TRIE | Table `anubis_ip_rules` | Règles Anubis IP/CIDR |
| `dict_anubis_asn` | FLAT | Table `anubis_asn_rules` | Règles Anubis ASN |
1. **Key**: `src_ip + src_port` — the client's source IP and ephemeral port uniquely identify a TCP connection.
2. **Time window**: Events must arrive within the configured window (default 10 seconds).
3. **Matching mode**:
- `one_to_one`: Each B event matches at most one A event (consumed after match).
- `one_to_many` (default, Keep-Alive): A single B (TLS handshake) can match multiple A events (HTTP requests) on the same connection. The B event has a configurable TTL (default 120 s) that resets on each match.
4. **Orphan handling**: Unmatched A events are emitted after a configurable delay (default 500 ms) with `correlated=false` and `orphan_side=A`.
## Algorithme de corrélation
## JA4/JA3 Fingerprint Format
Le correlator joint les événements HTTP (source A) avec les événements TLS/réseau (source B) via une corrélation à deux clés :
1. **Clé** : `src_ip + src_port` — l'IP source et le port éphémère du client identifient une connexion TCP de manière unique.
2. **Fenêtre temporelle** : Les événements doivent arriver dans la fenêtre configurée (défaut 10 secondes).
3. **Mode de correspondance** :
- `one_to_one` : Chaque événement B correspond à un seul événement A (consommé après correspondance).
- `one_to_many` (défaut, Keep-Alive) : Un seul B (handshake TLS) peut correspondre à plusieurs A (requêtes HTTP) sur la même connexion. Le B possède un TTL configurable (défaut 120 s) réinitialisé à chaque correspondance.
4. **Gestion des orphelins** : Les événements A sans correspondance sont émis après un délai configurable (défaut 500 ms) avec `correlated=false` et `orphan_side=A`.
La sortie est insérée dans **`ja4_logs.http_logs_raw`** (base `ja4_logs`), pas dans `ja4_processing`.
## Pipeline ML — bot-detector (détail)
```
view_ai_features_1h ──┐ ┌─── ml_detected_anomalies
view_thesis_feat_1h ──┤ ┌────────────┐ │
view_ip_recurrence ───┤ │ Pré- │ │
├──▶│ traitement │──▶│ Bifurcation :
│ │ + filtrage │ │ ├── Complet (correlated=1, ~63 feat.)
│ └────────────┘ │ └── Applicatif(correlated=0, ~51 feat.)
│ │
│ ┌────────────┐ │ Pour chaque branche :
│ │ Ensemble │ │ ├── Extended Isolation Forest (EIF)
│ │ triple │──▶│ ├── Autoencoder (PyTorch)
│ │ voix │ │ └── XGBoost (supervisé)
│ └────────────┘ │
│ │ Score = (1-β)×((1-α)×EIF + α×AE) + β×XGB
│ ┌────────────┐ │
│ │ Post- │ ├─── ml_all_scores
└──▶│ traitement │──▶│
│ HDBSCAN │ │ Niveaux : CRITICAL / HIGH / MEDIUM /
│ Browser 5ax│ │ LOW / NORMAL / LEGITIMATE_BROWSER /
│ SHAP │ │ KNOWN_BOT / ANUBIS_DENY / ANUBIS_ALLOW
└────────────┘ └───
```
## Référence des empreintes JA4/JA3
### JA4
JA4 is a modern TLS fingerprinting format (successor to JA3) with the structure:
Format moderne de fingerprinting TLS (successeur de JA3) :
```
t{TLS_VER}{SNI}{CIPHER_COUNT}{EXT_COUNT}_{CIPHER_HASH}_{EXT_HASH}
```
Example: `t13d1516h2_8daaf6152771_b0da82dd1658`
Exemple : `t13d1516h2_8daaf6152771_b0da82dd1658`
- Prefix `t` = TLS, followed by version (`13` = TLS 1.3)
- `d` = SNI present, `i` = SNI absent
- Cipher suite count and extension count
- SHA-256 truncated hashes of sorted cipher suites and extensions
- Préfixe `t` = TLS, suivi de la version (`13` = TLS 1.3)
- `d` = SNI présent, `i` = SNI absent
- Nombre de cipher suites et nombre d'extensions
- Hash SHA-256 tronqué des cipher suites et extensions triées
### JA3
JA3 is the original TLS fingerprinting format:
Format original de fingerprinting TLS :
```
{TLS_VER},{CIPHERS},{EXTENSIONS},{ELLIPTIC_CURVES},{EC_POINT_FORMATS}
```
The `ja3_hash` is the MD5 hash of the JA3 string.
Le `ja3_hash` est le hash MD5 de la chaîne JA3.
Both fingerprints are generated by sentinel from the TLS ClientHello payload.
Les deux empreintes sont générées par sentinel à partir du payload TLS ClientHello.
## Technology Stack
## Stack technologique
| Component | Technology |
|-----------|-----------|
| Packet capture | Go + libpcap (gopacket) |
| HTTP logging | C Apache module (APR) |
| Event correlation | Go (hexagonal architecture) |
| ML detection | Python 3.11 + scikit-learn |
| Dashboard backend | FastAPI (Python) |
| Dashboard frontend | React + Vite |
| Data store | ClickHouse |
| Deployment | systemd, Docker, RPM |
| IPC | UNIX datagram sockets |
| Composant | Technologie |
|-----------|-------------|
| Capture de paquets | Go 1.24.6 + libpcap (gopacket) |
| Logging HTTP | Module Apache C11 (APR, `apxs`) |
| Corrélation d'événements | Go 1.24.6 (architecture hexagonale) |
| tection ML — EIF | Python 3.11 + isotree |
| Détection ML — Autoencoder | Python 3.11 + PyTorch |
| Détection ML — Supervisé | Python 3.11 + XGBoost |
| Clustering de campagnes | HDBSCAN |
| Explicabilité | SHAP |
| Backend dashboard | FastAPI + Jinja2 (Python 3.11) |
| Frontend dashboard | htmx + Chart.js + ECharts + Tailwind CSS (CDN) |
| Magasin de données | ClickHouse 24.8 (dual-database) |
| Déploiement | systemd, Docker, RPM (Rocky 8/9/10) |
| IPC | Sockets UNIX datagramme |
| Workspace Go | `go.work` (Go 1.24.6) |
## Fichiers de schéma SQL (13)
```
shared/clickhouse/
├── 00_database.sql # Création des bases ja4_logs + ja4_processing
├── 01_raw_tables.sql # ja4_logs.http_logs_raw (TTL 2 heures)
├── 02_dictionaries.sql # dict_iplocate_asn, ref_bot_networks, bot_ip, bot_ja4
├── 03_anubis_tables.sql # anubis_ip_rules, anubis_asn_rules + 2 dictionnaires
├── 04_mv_http_logs.sql # ja4_logs.http_logs + mv_http_logs (JSON → colonnes)
├── 05_aggregation_tables.sql # agg_host_ip_ja4_1h, agg_header_fingerprint_1h + MVs + 4 dicts
├── 06_ml_tables.sql # ml_detected_anomalies, ml_all_scores, view_ip_recurrence
├── 07_ai_features_view.sql # view_ai_features_1h (feature engineering ~63 features)
├── 08_users.sql # Utilisateurs data_writer + analyst
├── 09_audit_table.sql # audit_logs (trace SOC, TTL 90 jours)
├── 10_perf_indexes.sql # Index et projections de performance
├── 11_views.sql # Vues métier du dashboard (4 vues)
├── 12_thesis_features.sql # agg_path_sequences, agg_request_timing, agg_ip_behavior,
│ # agg_resource_cascade + MVs + view_thesis_features_1h
│ # + view_resource_cascade_1h
└── deploy_schema.sh # Script de déploiement automatisé (substitution env vars)
```