- 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>
18 KiB
Guide de déploiement — ja4-platform
Prérequis
| Composant | Version minimale | Notes |
|---|---|---|
| ClickHouse | 23.8+ | Requis pour REGEXP_TREE, IP_TRIE dictionaries |
| Docker | 20.10+ | Pour build des images et RPMs |
| Make | 3.81+ | Orchestration des builds |
| OS cible (RPM) | Rocky/RHEL 8, 9, ou 10 | RPMs générés pour les 3 versions |
Services et leur runtime
| Service | Runtime | Port par défaut |
|---|---|---|
| sentinel | Go binary + libpcap (RPM) | — (capture réseau passive) |
| correlator | Go binary (RPM) | 8080 (metrics, optionnel) |
| mod-reqin-log | Apache module .so (RPM) | — (intégré à httpd) |
| bot-detector | Python 3.11 (Docker) | 8080 (health check) |
| dashboard | Python 3.11 / FastAPI (Docker) | 8000 (API) + 3000 (frontend) |
Étape 1 — Installation de ClickHouse
Installation (Rocky Linux / RHEL)
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo
sudo yum install -y clickhouse-server clickhouse-client
sudo systemctl enable --now clickhouse-server
Vérification
clickhouse-client --query "SELECT version()"
Étape 2 — Déploiement du schéma ClickHouse
Le schéma est géré par 13 fichiers SQL ordonnés dans shared/clickhouse/ et un script de déploiement automatisé.
Architecture des bases de données
Le système utilise deux bases de données séparées :
| Base | Variable d'env | Défaut | Contenu |
|---|---|---|---|
| Logs | CLICKHOUSE_DB_LOGS |
ja4_logs |
Logs bruts et parsés |
| Traitement | CLICKHOUSE_DB_PROCESSING |
ja4_processing |
Agrégations, ML, dictionnaires, vues, audit |
Fichiers de migration
shared/clickhouse/
├── 00_database.sql # Création des bases ja4_logs + ja4_processing
├── 01_raw_tables.sql # ja4_logs.http_logs_raw (ingestion brute, TTL 2 heures)
├── 02_dictionaries.sql # ja4_processing : dict_iplocate_asn, ref_bot_networks, bot_ip, bot_ja4
├── 03_anubis_tables.sql # ja4_processing : anubis_ip_rules, anubis_asn_rules + 2 dicts (IP/CIDR + ASN)
├── 04_mv_http_logs.sql # ja4_logs.http_logs + mv_http_logs (parsing JSON → colonnes typées)
├── 05_aggregation_tables.sql # ja4_processing : agg_host_ip_ja4_1h, agg_header_fingerprint_1h + MVs + 4 dicts
├── 06_ml_tables.sql # ja4_processing : ml_detected_anomalies, ml_all_scores, view_ip_recurrence
├── 07_ai_features_view.sql # ja4_processing : view_ai_features_1h (feature engineering ~63 features)
├── 08_users.sql # Utilisateurs data_writer et analyst + permissions
├── 09_audit_table.sql # ja4_processing : audit_logs (trace SOC, TTL 90 jours)
├── 10_perf_indexes.sql # Index et projections de performance sur tables existantes
├── 11_views.sql # Vues métier du dashboard (bruteforce, rotation, user_agents, entities)
├── 12_thesis_features.sql # Tables d'agrégation avancées (path_sequences, request_timing,
│ # ip_behavior, resource_cascade) + MVs + vues thèse
└── deploy_schema.sh # Script de déploiement automatisé (substitution env vars)
Déploiement avec les noms par défaut
cd shared/clickhouse/
chmod +x deploy_schema.sh
./deploy_schema.sh
Déploiement avec des noms personnalisés
CLICKHOUSE_DB_LOGS=prod_logs \
CLICKHOUSE_DB_PROCESSING=prod_analysis \
CLICKHOUSE_HOST=clickhouse.internal \
CLICKHOUSE_PORT=9000 \
CLICKHOUSE_USER=default \
CLICKHOUSE_PASSWORD=MonMotDePasse \
./deploy_schema.sh
Le script effectue une substitution sed sur chaque fichier SQL avant de l'envoyer à clickhouse-client --multiquery.
Déploiement manuel (fichier par fichier)
clickhouse-client --multiquery < shared/clickhouse/00_database.sql
clickhouse-client --multiquery < shared/clickhouse/01_raw_tables.sql
# ... etc., dans l'ordre
Vérification du déploiement
# Tables dans ja4_logs
clickhouse-client --query "SHOW TABLES FROM ja4_logs"
# Attendu : http_logs, http_logs_raw
# Tables dans ja4_processing
clickhouse-client --query "SHOW TABLES FROM ja4_processing"
# Attendu : agg_header_fingerprint_1h, agg_host_ip_ja4_1h, agg_ip_behavior_1h,
# agg_path_sequences_1h, agg_request_timing_1h, agg_resource_cascade_1h,
# anubis_asn_rules, anubis_ip_rules, audit_logs, bot_ip, bot_ja4,
# ml_all_scores, ml_detected_anomalies, ref_bot_networks, ...
# Dictionnaires chargés
clickhouse-client --query "SELECT name, status FROM system.dictionaries WHERE database IN ('ja4_logs', 'ja4_processing')"
# Utilisateurs créés
clickhouse-client --query "SHOW USERS"
Étape 3 — Configuration des utilisateurs ClickHouse
Le fichier 08_users.sql crée deux utilisateurs avec des mots de passe par défaut à changer impérativement :
Utilisateurs et permissions
| Utilisateur | Mot de passe défaut | Rôle | Permissions |
|---|---|---|---|
data_writer |
ChangeMe |
Ingestion (correlator) | INSERT, SELECT sur ja4_logs.http_logs_raw |
analyst |
ChangeMe |
Lecture (dashboard, bot-detector) | SELECT sur ja4_logs.http_logs, ja4_processing.ml_*, ja4_processing.view_*, ja4_processing.audit_logs |
Changement des mots de passe (obligatoire en production)
# Utiliser SHA256 pour la production
clickhouse-client --query "
ALTER USER data_writer IDENTIFIED WITH sha256_password BY 'VotreMotDePasseWriter';
ALTER USER analyst IDENTIFIED WITH sha256_password BY 'VotreMotDePasseAnalyst';
"
Permissions supplémentaires pour le bot-detector
Le bot-detector a besoin d'écrire dans les tables ML. Ajoutez ces grants pour l'utilisateur utilisé par le bot-detector (ici admin ou un utilisateur dédié) :
-- Créer un utilisateur dédié pour le bot-detector
CREATE USER IF NOT EXISTS bot_writer IDENTIFIED WITH sha256_password BY 'VotreMotDePasse';
-- Lectures : features et récurrence (ja4_processing)
GRANT SELECT ON ja4_processing.view_ai_features_1h TO bot_writer;
GRANT SELECT ON ja4_processing.view_ip_recurrence TO bot_writer;
GRANT SELECT ON ja4_processing.ml_detected_anomalies TO bot_writer;
-- Écritures : résultats ML (ja4_processing)
GRANT INSERT ON ja4_processing.ml_all_scores TO bot_writer;
GRANT INSERT ON ja4_processing.ml_detected_anomalies TO bot_writer;
-- Lectures/écritures : tables Anubis (ja4_processing) — pour fetch_rules.py
-- Seules les règles IP/CIDR et ASN sont utilisées (UA et Country ont été supprimés)
GRANT SELECT, INSERT, ALTER ON ja4_processing.anubis_ip_rules TO bot_writer;
GRANT SELECT, INSERT, ALTER ON ja4_processing.anubis_asn_rules TO bot_writer;
GRANT SYSTEM RELOAD DICTIONARY ON *.* TO bot_writer;
Permissions pour l'audit (dashboard)
-- Le dashboard doit pouvoir écrire dans audit_logs
GRANT INSERT ON ja4_processing.audit_logs TO analyst;
Étape 4 — Fichiers de données externes
Certains dictionnaires ClickHouse chargent des fichiers CSV depuis le disque :
# Répertoire des fichiers utilisateur ClickHouse
sudo mkdir -p /var/lib/clickhouse/user_files/
# Fichiers requis (à fournir par l'opérateur) :
# - iplocate_asn.csv → dict_iplocate_asn (géolocalisation IP/ASN)
# - bot_ip.csv → bot_ip (IPs de bots connues)
# - bot_ja4.csv → bot_ja4 (signatures JA4 de bots)
# - asn_reputation.csv → dict_asn_reputation (réputation ASN)
# Exemple de format bot_ip.csv :
# prefix,bot_name
# 198.51.100.0/24,ExampleBot
# 203.0.113.42/32,ScannerBot
# Permissions
sudo chown -R clickhouse:clickhouse /var/lib/clickhouse/user_files/
Étape 5 — Installation des services Go (RPM)
Build des RPMs
# Tous les RPMs (sentinel + correlator + mod-reqin-log) × 3 distros
make rpm-all
# Ou individuellement
make rpm-sentinel # → services/sentinel/dist/
make rpm-correlator # → services/correlator/dist/
make rpm-mod-reqin-log # → services/mod-reqin-log/dist/
Les RPMs sont générés dans services/<nom>/dist/ avec un sous-dossier par distro (el8, el9, el10).
Installation des RPMs
# Sur le serveur cible (Rocky 9 par exemple)
sudo yum install -y ./ja4sentinel-*.el9.x86_64.rpm
sudo yum install -y ./logcorrelator-*.el9.x86_64.rpm
sudo yum install -y ./mod_reqin_log-*.el9.x86_64.rpm
Configuration du sentinel
# Fichier de configuration principal
sudo cp /etc/ja4sentinel/config.yml.default /etc/ja4sentinel/config.yml
sudo vi /etc/ja4sentinel/config.yml
Variables d'environnement (dans /etc/sysconfig/ja4sentinel ou .env) :
JA4SENTINEL_INTERFACE=eth0 # Interface réseau à capturer
JA4SENTINEL_PORTS=443,8443 # Ports TLS à surveiller
Le sentinel écrit vers le socket Unix du correlator : /var/run/logcorrelator/network.socket
sudo systemctl enable --now ja4sentinel
sudo systemctl status ja4sentinel
journalctl -u ja4sentinel -f
Configuration du correlator
sudo cp /etc/logcorrelator/config.yml.default /etc/logcorrelator/config.yml
sudo vi /etc/logcorrelator/config.yml
Configuration minimale pour activer ClickHouse (config.yml) :
outputs:
clickhouse:
enabled: true
dsn: clickhouse://data_writer:VotreMotDePasse@localhost:9000/ja4_logs
table: http_logs_raw
batch_size: 500
flush_interval_ms: 200
file:
enabled: true
path: /var/log/logcorrelator/correlated.log
Variable d'environnement alternative (dans /etc/sysconfig/logcorrelator) :
LOGCORRELATOR_CLICKHOUSE_DSN=clickhouse://data_writer:VotreMotDePasse@localhost:9000/ja4_logs
sudo systemctl enable --now logcorrelator
sudo systemctl status logcorrelator
Configuration de mod-reqin-log
Le module Apache écrit les requêtes HTTP en JSON vers le socket Unix du correlator.
# Le RPM installe automatiquement le module dans Apache
# Vérifier le chargement
httpd -M | grep reqin
# La configuration est dans /etc/httpd/conf.d/mod_reqin_log.conf
# Le socket par défaut : /var/run/logcorrelator/http.socket
sudo systemctl restart httpd
Étape 6 — Installation des services Python (Docker)
Bot-detector
cd services/bot-detector
# Copier et configurer .env
cp .env.example .env
vi .env # Renseigner CLICKHOUSE_HOST, mots de passe, etc.
Variables d'environnement clés :
| Variable | Défaut | Description |
|---|---|---|
CLICKHOUSE_HOST |
clickhouse |
Hôte ClickHouse |
CLICKHOUSE_PORT |
8123 |
Port HTTP ClickHouse |
CLICKHOUSE_DB_PROCESSING |
ja4_processing |
Base de traitement |
CLICKHOUSE_DB_LOGS |
ja4_logs |
Base de logs |
CLICKHOUSE_USER |
admin |
Utilisateur (utiliser bot_writer en prod) |
CLICKHOUSE_PASSWORD |
— | Mot de passe |
ANOMALY_THRESHOLD |
-0.05 |
Seuil de détection d'anomalies (fallback) |
CYCLE_INTERVAL_SEC |
300 |
Intervalle entre cycles de détection (secondes) |
RETRAIN_INTERVAL_HOURS |
24 |
Intervalle de réentraînement des modèles |
AE_WEIGHT |
0.30 |
Poids de l'Autoencoder dans l'ensemble (α) |
XGB_WEIGHT |
0.20 |
Poids de XGBoost dans l'ensemble (β) |
ENABLE_MULTIWINDOW |
false |
Active les variantes 24h (Complet/Applicatif) |
HEALTH_PORT |
8080 |
Port du endpoint /health |
docker compose up -d
Dashboard
cd services/dashboard
# Copier et configurer .env
cp .env.example .env
vi .env # Renseigner CLICKHOUSE_HOST, mots de passe, etc.
Variables d'environnement clés :
| Variable | Défaut | Description |
|---|---|---|
CLICKHOUSE_HOST |
clickhouse |
Hôte ClickHouse |
CLICKHOUSE_PORT |
8123 |
Port HTTP ClickHouse |
CLICKHOUSE_DB_PROCESSING |
ja4_processing |
Base de traitement |
CLICKHOUSE_DB_LOGS |
ja4_logs |
Base de logs |
CLICKHOUSE_USER |
analyst |
Utilisateur en lecture |
CLICKHOUSE_PASSWORD |
— | Mot de passe |
API_HOST |
0.0.0.0 |
Adresse d'écoute de l'API |
API_PORT |
8000 |
Port de l'API FastAPI |
CORS_ORIGINS |
["http://localhost:3000"] |
Origines CORS autorisées |
docker compose up -d
Étape 7 — Vérification de bout en bout
1. Vérifier que les services tournent
# Services systemd (Go)
sudo systemctl status ja4sentinel logcorrelator httpd
# Services Docker (Python)
docker compose -f services/bot-detector/docker-compose.yml ps
docker compose -f services/dashboard/docker-compose.yaml ps
2. Vérifier l'ingestion des logs
# Logs bruts ingérés par le correlator
clickhouse-client --query "SELECT count() FROM ja4_logs.http_logs_raw"
# Logs parsés par la vue matérialisée
clickhouse-client --query "SELECT count() FROM ja4_logs.http_logs"
# Derniers logs
clickhouse-client --query "
SELECT time, src_ip, method, host, path, ja4
FROM ja4_logs.http_logs
ORDER BY time DESC
LIMIT 5
"
3. Vérifier les agrégations
clickhouse-client --query "
SELECT window_start, count()
FROM ja4_processing.agg_host_ip_ja4_1h
GROUP BY window_start
ORDER BY window_start DESC
LIMIT 5
"
4. Vérifier les détections ML
clickhouse-client --query "
SELECT src_ip, anomaly_score, label, detected_at
FROM ja4_processing.ml_detected_anomalies
ORDER BY detected_at DESC
LIMIT 5
"
5. Tester le dashboard
curl -s http://localhost:8000/api/metrics | python3 -m json.tool | head -20
curl -s http://localhost:8000/api/health
Scripts utilitaires
Les scripts dans scripts/ facilitent l'initialisation et la maintenance de la stack :
init-stack.sh — Initialisation complète
Déploie le schéma SQL, charge les données CSV de référence et vérifie que tous les composants sont opérationnels :
./scripts/init-stack.sh # init stack de dev
./scripts/init-stack.sh --container my-ch-1 # conteneur ClickHouse spécifique
./scripts/init-stack.sh --reset # DROP databases, tout recréer
./scripts/init-stack.sh --import-prod # init + import données prod
import-prod-data.sh — Import de données de production
Importe les données exportées au format Native avec décalage temporel automatique :
./scripts/import-prod-data.sh # décalage auto (max(time) → now)
./scripts/import-prod-data.sh --shift 3600 # décalage manuel (secondes)
./scripts/import-prod-data.sh --no-truncate # conserver les données existantes
reload-prod-logs.sh — Rechargement depuis la production
Exporte les http_logs de la production et les réimporte dans la base de dev :
./scripts/reload-prod-logs.sh # décalage auto
./scripts/reload-prod-logs.sh --days 7 # exporte les N derniers jours
./scripts/reload-prod-logs.sh --cron # mode silencieux (pour crontab)
update-csv-data.sh — Mise à jour des données CSV
Télécharge et génère tous les fichiers CSV de référence (bot IPs, JA4, ASN) :
./scripts/update-csv-data.sh # génère tout
./scripts/update-csv-data.sh --install-stubs # copie aussi les stubs de test
Schéma réseau récapitulatif
┌──────────────┐ Unix socket ┌──────────────┐ ClickHouse ┌──────────────────┐
│ mod-reqin-log│──── http.socket ─────→│ │ INSERT INTO │ │
│ (Apache C11) │ (source A) │ correlator │───→ ja4_logs. │ ClickHouse │
└──────────────┘ │ │ http_logs_raw │ │
│ │ │ ┌──────────────┐ │
┌──────────────┐ Unix socket │ │ MV parse JSON │ │ ja4_logs │ │
│ sentinel │──── network.socket ──→│ │ ↓ │ │ _raw → _logs│ │
│ (Go+libpcap) │ (source B) └──────────────┘ ja4_logs. │ └──────────────┘ │
└──────────────┘ http_logs │ │
│ │ ┌──────────────┐ │
6 MVs agrégation│ │ ja4_processing│ │
↓ │ │ agg_* (×6) │ │
┌──────────────┐ SELECT features ┌──────────────┐ ja4_processing. │ │ ml_* (×2) │ │
│ bot-detector │←─── view_ai_features ─│ │ agg_*, view_* │ │ views, dicts│ │
│ (Python 3.11)│ view_thesis_feat │ ClickHouse │ │ │ audit_logs │ │
│ EIF+AE+XGB │ │ │ ml_all_scores │ └──────────────┘ │
│ │───→ INSERT scores ────→│ │ ml_detected_* │ │
└──────────────┘ └──────────────┘ └──────────────────┘
↑
┌──────────────┐ SELECT * │
│ dashboard │←─── ja4_processing.ml_*, agg_*, views ────────────────────────────┘
│ (FastAPI) │←─── ja4_logs.http_logs ───────────────────────────────────────────┘
└──────────────┘