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>
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:latestja4-platform/bot-detector:latestja4-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 :
- L'étape
go-buildercompile le bytecode eBPF (clang/llvm) puis le binaire Go statique - Les étapes
rpm-el8,rpm-el9,rpm-el10exécutentrpmbuildpour chaque distro cible - L'étape de sortie
alpinecollecte 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
-
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 -
Ajouter au
go.work:use ( ./shared/go/ja4common ./services/ja4ebpf ./services/my-service # <- add this ) -
Ajouter les cibles Makefile.
Service Python
- Créer le répertoire avec
requirements.txt. - Ajouter
ja4-commoncomme dépendance locale. - Utiliser
from ja4_common.clickhouse import get_clientpour l'accès ClickHouse.
Package Python ja4_common
Le package Python partagé (shared/python/ja4_common) fournit :
ClickHouseSettings— modèle pydantic-settings lisant depuis.envClickHouseClient— client singleton avec reconnexion automatiqueget_client()— accesseur singleton au niveau du module
Note : le dashboard n'utilise PAS ja4_common — il possède son propre client léger
clickhouse-connectdansbackend/database.py.
Variables d'environnement
Consultez la documentation de chaque service pour la référence complète :