Files
ja4-platform/docs/development.md
Jacquin Antoine c60ce97f23 feat(bot-detector): add dynamic browser profiling engine with HDBSCAN clustering
Implement offline profile building (profile_builder.py) and real-time
dynamic scoring (browser_matcher_dynamic.py) using HDBSCAN-based browser
fingerprint clustering. Add ClickHouse materialized view (13_h2_profiling.sql)
for h2_profile_stats aggregation. Update thesis and project documentation
to cover the new dynamic profiling architecture.

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

7.4 KiB

Guide de développement

Ce guide couvre la compilation, les tests, le packaging et l'extension du monorepo ja4-platform. Toutes les opérations de build et de test s'exécutent dans Docker — aucune toolchain Go, Python, C ou eBPF n'est requise sur la machine hôte.

Prérequis

Outil Version minimale Notes
Docker 20.10+ BuildKit activé (DOCKER_BUILDKIT=1)
Docker Compose 2.x Pour bot-detector et dashboard
make 3.81+ GNU Make
git 2.x Pour le versioning

Compilation de tous les services

make build-all

Cela construit les images Docker pour :

  • ja4-platform/ja4ebpf:latest
  • ja4-platform/bot-detector:latest
  • ja4-platform/dashboard:latest

Compilation individuelle

make build-ja4ebpf      # Bytecode eBPF (clang) + binaire Go dans Docker Rocky Linux
make build-bot-detector  # Image Python
make build-dashboard     # Image FastAPI + Jinja2

Exécution des tests

make test-all

Tests par service

Service Commande Détails
ja4ebpf make test-ja4ebpf Tests Go avec -race, nécessite NET_RAW/NET_ADMIN/BPF
bot-detector make test-bot-detector Suite pytest Python
dashboard make test-dashboard pytest pour les routes FastAPI
ja4_common (Python) make test-ja4common-python Tests de la librairie Python partagée

Tests d'intégration

Les tests d'intégration full-stack s'exécutent contre Docker Compose avec une instance ClickHouse réelle :

make test-integration          # 8 phases : build -> start -> schema -> traffic -> pipeline -> dashboard -> bot-detector -> ja4ebpf
make test-integration-keep     # idem mais laisse la stack en fonctionnement
make test-integration-down     # démontage de la stack d'intégration
make test-nginx                # stack nginx + ja4ebpf
make test-nginx-varnish        # nginx + Varnish + ja4ebpf
make test-hitch-varnish        # hitch (TLS) + Varnish + ja4ebpf
make test-all-stacks           # les 3 stacks serveur en séquence

La suite de tests se trouve dans tests/integration/ et réinitialise la base entre chaque exécution.

Construction des paquets RPM

make rpm-ja4ebpf
# RPMs dans services/ja4ebpf/dist/rpm/el{8,9,10}/

Le build RPM utilise un pipeline Docker multi-étapes Rocky Linux :

  1. L'étape go-builder compile le bytecode eBPF (clang/llvm) puis le binaire Go statique
  2. Les étapes rpm-el8, rpm-el9, rpm-el10 exécutent rpmbuild pour chaque distro cible
  3. L'étape de sortie alpine collecte tous les RPMs via --output type=local

Développement local

Service Go/eBPF (ja4ebpf)

Le fichier go.work relie les modules Go :

go 1.24.6

use (
    ./shared/go/ja4common
    ./services/ja4ebpf
)

La compilation locale du bytecode eBPF nécessite clang, llvm et bpftool. En pratique, on passe toujours par Docker :

# Rebuild du bytecode eBPF + binaire Go (Docker Rocky Linux)
make build-ja4ebpf

# Tests unitaires ja4ebpf (Docker avec cap NET_RAW + BPF)
make test-ja4ebpf

# Test single dans Docker
docker run --rm --cap-add=NET_RAW --cap-add=NET_ADMIN --cap-add=BPF \
  ja4ebpf:tests go test -v -run TestDispatcher ./internal/dispatcher/

Services Python (bot-detector, dashboard)

# Installer la librairie partagée en mode développement
cd shared/python/ja4_common && pip install -e .

# Lancer le bot-detector localement
cd services/bot-detector && pip install -r bot_detector/requirements.txt
python -m bot_detector

# Lancer le dashboard localement
cd services/dashboard && pip install -r backend/requirements.txt
uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000

Dépendances Python pour le développement local du bot-detector

Librairie Usage
isotree Extended Isolation Forest (scoreur principal non supervisé)
torch Autoencoder (PyTorch, architecture n->64->32->16->32->64->n)
xgboost Modèle supervisé (entraîné sur les labels SOC)
hdbscan Clustering de campagnes d'attaque
shap Explicabilité des scores d'anomalie
scikit-learn Fallback pour Isolation Forest si isotree indisponible
clickhouse-connect Client ClickHouse (via ja4_common)

Structure modulaire du bot-detector (16 modules)

services/bot-detector/bot_detector/
├── __init__.py          # Package init
├── __main__.py          # Point d'entrée (python -m bot_detector)
├── config.py            # Configuration (os.getenv, PAS pydantic-settings)
├── log.py               # Configuration du logging
├── infra.py             # Connexion ClickHouse, health check
├── preprocessing.py     # Feature engineering, filtrage, normalisation
├── models.py            # EIF, Autoencoder, XGBoost (entraînement + scoring)
├── scoring.py           # Ensemble triple voix, seuils adaptatifs
├── browser.py           # Détection de navigateur 5 axes multifactoriels
├── pipeline.py          # Orchestration du cycle de détection
├── cycle.py             # Boucle principale (cycle de 5 minutes)
└── tests/               # Tests pytest (self-contained, pas d'import lourd)

Scripts utilitaires

Script Commande Make Description
init-stack.sh make init-stack Initialisation complète de la stack ClickHouse (schéma + données CSV)
import-prod-data.sh make import-prod-data Import de données de prod avec décalage temporel
reload-prod-logs.sh make reload-prod-logs Export prod -> réimport dev avec décalage
update-csv-data.sh -- Téléchargement et génération de toutes les données CSV de référence
make init-and-import   # Initialisation complète (schéma + CSV + import prod)
make init-stack        # Initialisation seule (schéma + CSV)
make import-prod-data  # Import des données prod pré-exportées
make reload-prod-logs  # Rechargement depuis la prod

Ajout d'un nouveau service

Service Go

  1. Créer le répertoire et initialiser le module :

    mkdir -p services/my-service/cmd/my-service services/my-service/internal
    cd services/my-service && go mod init github.com/antitbone/ja4/my-service
    
  2. Ajouter au go.work :

    use (
        ./shared/go/ja4common
        ./services/ja4ebpf
        ./services/my-service      # <- add this
    )
    
  3. Ajouter les cibles Makefile.

Service Python

  1. Créer le répertoire avec requirements.txt.
  2. Ajouter ja4-common comme dépendance locale.
  3. Utiliser from ja4_common.clickhouse import get_client pour l'accès ClickHouse.

Package Python ja4_common

Le package Python partagé (shared/python/ja4_common) fournit :

  • ClickHouseSettings — modèle pydantic-settings lisant depuis .env
  • ClickHouseClient — client singleton avec reconnexion automatique
  • get_client() — accesseur singleton au niveau du module

Note : le dashboard n'utilise PAS ja4_common — il possède son propre client léger clickhouse-connect dans backend/database.py.

Variables d'environnement

Consultez la documentation de chaque service pour la référence complète :