Files
ja4-platform/docs/testing-e2e.md
Jacquin Antoine f88b739992 feat(e2e): add distributed E2E test framework with parametric traffic generation
Add run-e2e-test.sh with CLI parameters (--hits, --http-ratio, --dns, --tls,
--src-ips, --keep-analysis, --up) for configurable traffic generation. Traffic
runs from VM endpoints with multiple source IPs (alias IPs on eth0) to produce
distinct sessions for the ML pipeline. Fix curl TLS flags (--tlsv1.2 instead
of --tls-v1-2), skip redundant local verification in distributed mode, and
fix dashboard is_available() cache that never retried after ClickHouse recovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 00:09:32 +02:00

190 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Test E2E distribué — Stack de test complète ja4-platform
## Objectif
Valider le pipeline complet de bout en bout :
```
trafic simulé → ja4ebpf (capture eBPF) → ClickHouse (stockage + agrégation MV)
→ bot-detector (ML) → dashboard (visualisation)
```
Les tests unitaires et d'intégration existants testent la capture eBPF isolément.
Le test E2E distribué valide la **chaine complète** sur une architecture multi-VMs.
## Architecture
```
HOST (orchestrateur — run-e2e-test.sh)
├── centos8 (el8) ── nginx + ja4ebpf ──eth1──┐
├── rocky9 (el9) ── nginx + ja4ebpf ──eth1──┤ réseau privé ja4-e2e
├── rocky10 (el10) ── nginx + ja4ebpf ──eth1──┤ 192.168.42.0/24
│ │
│ analysis ────┘ 192.168.42.10 (fixe)
│ ├── Docker ClickHouse :9000/:8123
│ ├── Docker bot-detector :8080
│ └── Docker dashboard :8000
└── Trafic curl/httpx → endpoints :80/:443
```
### VMs
| VM | Rôle | Box | IP | Services |
|----|------|-----|-----|----------|
| centos8 | Endpoint el8 | centos/8 | DHCP eth0 | nginx, ja4ebpf |
| rocky9 | Endpoint el9 | generic/rocky9 | DHCP eth0 | nginx, ja4ebpf |
| rocky10 | Endpoint el10 | almalinux/10 | DHCP eth0 | nginx, ja4ebpf |
| analysis | Serveur central | generic/rocky9 | 192.168.42.10 (eth1 fixe) | Docker: ClickHouse, bot-detector, dashboard |
### Réseau
- **eth0** (NAT libvirt) : SSH depuis le host, réception du trafic de test
- **eth1** (réseau privé `ja4-e2e`) : communication inter-VMs
- Les endpoints utilisent eth1 pour envoyer les logs ja4ebpf vers `192.168.42.10:9000`
- Le host accède au dashboard et ClickHouse via l'IP eth0 de la VM analysis (routée via libvirt NAT)
## Pipeline de données
```
1. HOST → endpoints curl/httpx génère du trafic HTTP/HTTPS/H2
2. ja4ebpf Capture eBPF : TLS ClientHello (JA4), TCP SYN (L3/L4),
HTTP via uprobe SSL_read (L7)
3. → ClickHouse :9000 ja4ebpf écrit dans ja4_logs.http_logs_raw (batch 100 lignes, flush 1s)
4. MV mv_http_logs Materialized View : http_logs_raw → http_logs (parsed, corrélé)
5. MV mv_agg_host_ip_ja4_1h Agrégation horaire par (host, src_ip, ja4) → agg_host_ip_ja4_1h
6. view_ai_features_1h Vue qui joint les features pour le ML
7. bot-detector Cycle ML toutes les 30s (config de test) :
- Lit view_ai_features_1h
- Pipeline : NFEnsemble (M=5 NF) → ADWIN (River) → MLP fusion
- Écrit ml_all_scores + ml_detected_anomalies
8. dashboard API FastAPI sur :8000, requête ClickHouse
```
## Principe clé : DB vierge avant chaque test
Avant chaque exécution E2E, la Phase 1 fait un `docker compose down -v` qui supprime tous les volumes Docker (y compris les données ClickHouse). Cela garantit que :
- ClickHouse démarre avec un schéma vierge
- Les données observées sont exclusivement celles générées par le test
- Les vérifications de la Phase 5 sont déterministes
## Stack Docker (VM analysis)
Définie dans `tests/vm/analysis/docker-compose.yml` :
### ClickHouse
- Image : `clickhouse/clickhouse-server:24.8`
- Ports : `0.0.0.0:9000` (native, ja4ebpf), `0.0.0.0:8123` (HTTP, API)
- Schéma : 12 fichiers SQL de `shared/clickhouse/*.sql`, exécutés via `clickhouse-init.sh`
- Credentials : `user=default, password=""` (patché par clickhouse-init.sh)
- Dictionnaires : CSV stubs de `tests/integration/platform/csv-stubs/`
### bot-detector
- Build : `services/bot-detector/bot_detector/Dockerfile`
- Port : `0.0.0.0:8080` (health check)
- Configuration accélérée pour les tests :
- `CYCLE_INTERVAL_SEC: 30` (vs 300 en prod)
- `MIN_VALID_FEATURE_RATIO: 0.10` (vs 0.50 en prod)
- SHAP, clustering, multi-fenêtres désactivés
### dashboard
- Build : `services/dashboard/Dockerfile`
- Port : `0.0.0.0:8000`
- Routes de vérification : `/health`, `/api/overview`, `/api/detections`
## Phases du test (run-e2e-test.sh)
| Phase | Description | Durée |
|-------|-------------|-------|
| 0 | Setup : démarrage VMs, rsync, découverte IPs | ~2 min (si VMs existantes) |
| 1 | Stack analysis : purge volumes (DB vierge), `docker compose up -d --build`, attente healthy | ~3 min |
| 2 | Endpoints : nginx + ja4ebpf (DSN → analysis:9000), en parallèle | ~1 min |
| 3 | Trafic : 500 req/VM × 3 VMs, HTTP/HTTPS/H2, méthodes variées | ~5 min |
| 4 | Attente : flush ja4ebpf 15s, poll ml_all_scores (max 120s) | ~2 min |
| 5 | Vérifications : 15+ checks sur 4 layers | ~1 min |
## Vérifications (Phase 5)
### Layer 1 — Données brutes
- `ja4_logs.http_logs_raw` : lignes > 0
- `uniqExact(host)` : >= 2 hôtes distincts (multi-source)
### Layer 2 — Pipeline ClickHouse (MVs)
- `ja4_logs.http_logs` : JA4 fingerprints capturés
- `ja4_logs.http_logs` : méthodes HTTP capturées (L7 via uprobe SSL_read)
- `ja4_processing.agg_host_ip_ja4_1h` : agrégation horaire peuplée
- `ja4_processing.view_ai_features_1h` : features ML disponibles
### Layer 3 — ML bot-detector
- `ja4_processing.ml_all_scores` : classifications produites
- `ja4_processing.ml_detected_anomalies` : anomalies détectées (optionnel)
- Health check `:8080`
### Layer 4 — Dashboard
- `/health` : OK
- `/api/overview` : données non-vides
- `/api/detections` : accessible
## Utilisation
```bash
# Créer les 4 VMs
make e2e-up
# Test complet (500 req/VM, ~15 min)
make test-e2e
# Test rapide (100 req/VM)
make test-e2e-quick
# Garder les VMs après le test (pour debug)
KEEP_RUNNING=true make test-e2e
# Détruire les VMs
make e2e-down
```
## Accès manuel (debug)
```bash
# ClickHouse — vérifier les données
curl "http://192.168.42.10:8123/?query=SELECT+count()+FROM+ja4_logs.http_logs"
# Dashboard
curl http://192.168.42.10:8000/health
curl http://192.168.42.10:8000/api/overview | python3 -m json.tool
# bot-detector
curl http://192.168.42.10:8080/
# SSH dans la VM analysis
cd tests/vm && vagrant ssh analysis
# Logs des conteneurs
vagrant ssh analysis -- "docker logs bot_detector_ai --tail 50"
vagrant ssh analysis -- "docker logs ja4-dashboard --tail 50"
```
## Fichiers
| Fichier | Rôle |
|---------|------|
| `tests/vm/Vagrantfile` | Définition des 4 VMs + réseau ja4-e2e |
| `tests/vm/provision-analysis.sh` | Provisionneur VM analysis (Docker, firewall) |
| `tests/vm/analysis/docker-compose.yml` | Stack centralisée CH + bot-detector + dashboard |
| `tests/vm/run-e2e-test.sh` | Orchestrateur E2E 5 phases |
| `tests/vm/run-tests-vm.sh` | Script endpoint (modifié pour CH_HOST) |
| `Makefile` | Cibles e2e-up, e2e-down, test-e2e, test-e2e-quick |
## Dépannage
| Problème | Diagnostic |
|----------|------------|
| ClickHouse inaccessible | `vagrant ssh analysis -- "docker ps"` ; vérifier le port binding |
| ja4ebpf n'écrit pas | `vagrant ssh rocky9 -- "cat /tmp/ja4ebpf.log \| tail 20"` |
| Pas de JA4 | Le hook TC nécessite CAP_BPF ; vérifier `dmesg \| grep bpf` |
| bot-detector ne démarre pas | `vagrant ssh analysis -- "docker logs bot_detector_ai"` |
| Pas de données ML | Volume insuffisant pour les fenêtres d'agrégation horaire |
| Dashboard vide | Le bot-detector doit avoir complété au moins 1 cycle (30s) |