# 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 ```bash make build-all ``` Cela construit les images Docker pour : - `ja4-platform/ja4ebpf:latest` - `ja4-platform/bot-detector:latest` - `ja4-platform/dashboard:latest` ### Compilation individuelle ```bash 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 ```bash 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 : ```bash 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 ```bash 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 : ```bash # 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) ```bash # 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 (11 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 | ```bash 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 : ```bash 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 : - [Configuration de ja4ebpf](services/ja4ebpf.md#configuration) - [Configuration du Bot Detector](services/bot-detector.md#environment-variables) - [Configuration du Dashboard](services/dashboard.md#configuration)