From 9734e21fe352b3a863062333390f5bfe61232850 Mon Sep 17 00:00:00 2001 From: toto Date: Sun, 12 Apr 2026 01:48:14 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20suppression=20des=20services=20obsol?= =?UTF-8?q?=C3=A8tes=20(sentinel,=20correlator,=20mod-reqin-log)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remplacés par l'agent ja4ebpf (eBPF CO-RE). Nettoyage complet : Supprimé : - old/ (archive de l'ancienne architecture) - services/correlator/ (logcorrelator Go) - services/sentinel/ (capture pcap Go) - services/mod-reqin-log/ (module Apache C) - shared/go/ja4common/ (lib Go partagée — plus importée par ja4ebpf) - tests/integration/platform/ (test correlator+sentinel+httpd) - tests/integration/docker-compose.yml (compose ancienne archi) - tests/integration/run-tests.sh (runner correlator/sentinel) - tests/integration/verify_mvs.py (script orphelin) Nettoyé : - go.work : retire ./shared/go/ja4common - services/ja4ebpf/go.mod : retire replace ja4common (jamais importé) - services/ja4ebpf/Dockerfile* : retire les COPY ja4common inutiles - Makefile : retire test-ja4common-python, test-integration*, targets obsolètes - tests/integration/README.md : réécrit pour l'architecture ja4ebpf Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Makefile | 29 +- go.work | 5 +- go.work.sum | 2 - old/services/correlator/.dockerignore | 19 - old/services/correlator/.env.example | 2 - .../correlator/.github/workflows/ci.yml | 73 - old/services/correlator/.gitignore | 32 - old/services/correlator/Dockerfile | 43 - old/services/correlator/Dockerfile.package | 108 - old/services/correlator/Makefile | 148 -- old/services/correlator/README.md | 426 ---- old/services/correlator/architecture.yml | 974 --------- .../correlator/cmd/logcorrelator/main.go | 204 -- old/services/correlator/config.example.yml | 92 - old/services/correlator/docs/detection.md | 224 -- old/services/correlator/go.mod | 29 - old/services/correlator/go.sum | 110 - old/services/correlator/idees/champs.md | 111 - old/services/correlator/idees/idees.txt | 30 - old/services/correlator/idees/views.md | 521 ----- .../adapters/inbound/unixsocket/source.go | 386 ---- .../inbound/unixsocket/source_test.go | 596 ------ .../adapters/outbound/clickhouse/sink.go | 391 ---- .../adapters/outbound/clickhouse/sink_test.go | 538 ----- .../internal/adapters/outbound/file/sink.go | 191 -- .../adapters/outbound/file/sink_test.go | 524 ----- .../internal/adapters/outbound/multi/sink.go | 137 -- .../adapters/outbound/multi/sink_test.go | 233 -- .../internal/adapters/outbound/stdout/sink.go | 46 - .../adapters/outbound/stdout/sink_test.go | 81 - .../correlator/internal/app/orchestrator.go | 161 -- .../internal/app/orchestrator_test.go | 300 --- .../correlator/internal/config/config.go | 412 ---- .../correlator/internal/config/config_test.go | 1253 ----------- .../internal/domain/correlated_log.go | 155 -- .../internal/domain/correlated_log_test.go | 365 ---- .../internal/domain/correlation_service.go | 1027 --------- .../domain/correlation_service_test.go | 1865 ----------------- .../correlator/internal/domain/event.go | 33 - .../internal/observability/logger.go | 27 - .../internal/observability/logger_test.go | 296 --- .../internal/observability/metrics.go | 176 -- .../internal/observability/metrics_server.go | 128 -- .../correlator/internal/ports/source.go | 57 - old/services/correlator/logcorrelator.service | 34 - .../packaging/rpm/logcorrelator.spec | 366 ---- .../correlator/packaging/rpm/logrotate | 13 - .../correlator/packaging/test/test-rpm.sh | 271 --- .../correlator/scripts/audit-architecture.sh | 118 -- .../scripts/test-correlation-advanced.py | 582 ----- .../correlator/scripts/test-correlation.sh | 404 ---- old/services/correlator/sql/bots.sql | 21 - old/services/correlator/sql/init.sql | 235 --- .../sql/migrations/01_ttl_adjustments.sql | 90 - .../sql/migrations/02_detection_features.sql | 17 - .../03_remove_ua_browser_detection.sql | 45 - .../sql/migrations/04_http2_fields.sql | 52 - .../migrations/05_fleet_metrics_tables.sql | 55 - .../06_browser_signature_detection.sql | 72 - old/services/correlator/sql/tables.sql | 29 - old/services/mod-reqin-log/.gitignore | 35 - old/services/mod-reqin-log/.gitlab-ci.yml | 94 - old/services/mod-reqin-log/CMakeLists.txt | 47 - old/services/mod-reqin-log/Dockerfile.package | 176 -- old/services/mod-reqin-log/Dockerfile.tests | 43 - old/services/mod-reqin-log/LICENSE | 107 - old/services/mod-reqin-log/Makefile | 153 -- old/services/mod-reqin-log/README.md | 284 --- old/services/mod-reqin-log/architecture.yml | 443 ---- .../mod-reqin-log/conf/mod_reqin_log.conf | 40 - old/services/mod-reqin-log/mod_reqin_log.spec | 123 -- .../mod-reqin-log/src/mod_reqin_log.c | 1814 ---------------- .../mod-reqin-log/src/mod_reqin_log.h | 56 - .../tests/unit/test_config_parsing.c | 333 --- .../tests/unit/test_h2_parsing.c | 458 ---- .../tests/unit/test_header_handling.c | 226 -- .../tests/unit/test_json_serialization.c | 266 --- .../tests/unit/test_module_real.c | 1141 ---------- old/services/sentinel/.dockerignore | 37 - old/services/sentinel/.env.example | 7 - .../sentinel/.github/workflows/build-rpm.yml | 125 -- old/services/sentinel/.gitignore | 59 - old/services/sentinel/Dockerfile | 37 - old/services/sentinel/Dockerfile.dev | 25 - old/services/sentinel/Dockerfile.package | 109 - old/services/sentinel/Dockerfile.test-server | 105 - old/services/sentinel/Makefile | 158 -- old/services/sentinel/README.md | 291 --- old/services/sentinel/api/types.go | 307 --- old/services/sentinel/api/types_test.go | 340 --- old/services/sentinel/architecture.yml | 524 ----- old/services/sentinel/cmd/ja4sentinel/main.go | 357 ---- .../sentinel/cmd/ja4sentinel/main_test.go | 221 -- old/services/sentinel/config.yml.example | 57 - old/services/sentinel/docker-compose.test.yml | 49 - old/services/sentinel/go.mod | 21 - old/services/sentinel/go.sum | 27 - .../sentinel/internal/capture/capture.go | 397 ---- .../sentinel/internal/capture/capture_test.go | 661 ------ .../sentinel/internal/config/loader.go | 295 --- .../sentinel/internal/config/loader_test.go | 1008 --------- .../sentinel/internal/fingerprint/engine.go | 192 -- .../internal/fingerprint/engine_test.go | 585 ------ .../internal/integration/pipeline_test.go | 402 ---- .../sentinel/internal/ipfilter/ipfilter.go | 15 - .../internal/ipfilter/ipfilter_test.go | 160 -- .../internal/logging/logger_factory.go | 19 - .../internal/logging/service_logger.go | 47 - .../internal/logging/service_logger_test.go | 79 - .../sentinel/internal/output/writers.go | 644 ------ .../sentinel/internal/output/writers_test.go | 1110 ---------- .../sentinel/internal/tlsparse/parser.go | 1015 --------- .../sentinel/internal/tlsparse/parser_test.go | 1824 ---------------- .../sentinel/packaging/logrotate/ja4sentinel | 17 - .../sentinel/packaging/rpm/ja4sentinel.spec | 328 --- .../packaging/systemd/ja4sentinel.service | 41 - services/correlator/.dockerignore | 19 - services/correlator/.env.example | 2 - services/correlator/.github/workflows/ci.yml | 73 - services/correlator/.gitignore | 32 - services/correlator/Dockerfile | 43 - services/correlator/Dockerfile.package | 108 - services/correlator/Makefile | 148 -- services/correlator/README.md | 426 ---- services/correlator/architecture.yml | 974 --------- services/correlator/cmd/logcorrelator/main.go | 204 -- services/correlator/config.example.yml | 92 - services/correlator/docs/detection.md | 224 -- services/correlator/go.mod | 29 - services/correlator/go.sum | 110 - services/correlator/idees/champs.md | 111 - services/correlator/idees/idees.txt | 30 - services/correlator/idees/views.md | 521 ----- .../adapters/inbound/unixsocket/source.go | 386 ---- .../inbound/unixsocket/source_test.go | 596 ------ .../adapters/outbound/clickhouse/sink.go | 391 ---- .../adapters/outbound/clickhouse/sink_test.go | 538 ----- .../internal/adapters/outbound/file/sink.go | 191 -- .../adapters/outbound/file/sink_test.go | 524 ----- .../internal/adapters/outbound/multi/sink.go | 137 -- .../adapters/outbound/multi/sink_test.go | 233 -- .../internal/adapters/outbound/stdout/sink.go | 46 - .../adapters/outbound/stdout/sink_test.go | 81 - .../correlator/internal/app/orchestrator.go | 161 -- .../internal/app/orchestrator_test.go | 300 --- services/correlator/internal/config/config.go | 412 ---- .../correlator/internal/config/config_test.go | 1253 ----------- .../internal/domain/correlated_log.go | 155 -- .../internal/domain/correlated_log_test.go | 365 ---- .../internal/domain/correlation_service.go | 1027 --------- .../domain/correlation_service_test.go | 1865 ----------------- services/correlator/internal/domain/event.go | 33 - .../internal/observability/logger.go | 27 - .../internal/observability/logger_test.go | 296 --- .../internal/observability/metrics.go | 176 -- .../internal/observability/metrics_server.go | 128 -- services/correlator/internal/ports/source.go | 57 - services/correlator/logcorrelator.service | 34 - .../packaging/rpm/logcorrelator.spec | 366 ---- services/correlator/packaging/rpm/logrotate | 13 - .../correlator/packaging/test/test-rpm.sh | 271 --- .../correlator/scripts/audit-architecture.sh | 118 -- .../scripts/test-correlation-advanced.py | 582 ----- .../correlator/scripts/test-correlation.sh | 404 ---- services/correlator/sql/bots.sql | 21 - services/correlator/sql/init.sql | 235 --- .../sql/migrations/01_ttl_adjustments.sql | 90 - .../sql/migrations/02_detection_features.sql | 17 - .../03_remove_ua_browser_detection.sql | 45 - .../sql/migrations/04_http2_fields.sql | 52 - .../migrations/05_fleet_metrics_tables.sql | 55 - .../06_browser_signature_detection.sql | 72 - services/correlator/sql/tables.sql | 29 - services/ja4ebpf/Dockerfile | 3 - services/ja4ebpf/Dockerfile.package | 3 - services/ja4ebpf/Dockerfile.tests | 3 - services/ja4ebpf/go.mod | 1 - services/mod-reqin-log/.gitignore | 35 - services/mod-reqin-log/.gitlab-ci.yml | 94 - services/mod-reqin-log/CMakeLists.txt | 47 - services/mod-reqin-log/Dockerfile.package | 176 -- services/mod-reqin-log/Dockerfile.tests | 43 - services/mod-reqin-log/LICENSE | 107 - services/mod-reqin-log/Makefile | 153 -- services/mod-reqin-log/README.md | 284 --- services/mod-reqin-log/architecture.yml | 443 ---- .../mod-reqin-log/conf/mod_reqin_log.conf | 40 - services/mod-reqin-log/mod_reqin_log.spec | 123 -- services/mod-reqin-log/src/mod_reqin_log.c | 1814 ---------------- services/mod-reqin-log/src/mod_reqin_log.h | 56 - .../tests/unit/test_config_parsing.c | 333 --- .../tests/unit/test_h2_parsing.c | 458 ---- .../tests/unit/test_header_handling.c | 226 -- .../tests/unit/test_json_serialization.c | 266 --- .../tests/unit/test_module_real.c | 1141 ---------- services/sentinel/.dockerignore | 37 - services/sentinel/.env.example | 7 - .../sentinel/.github/workflows/build-rpm.yml | 125 -- services/sentinel/.gitignore | 59 - services/sentinel/Dockerfile | 37 - services/sentinel/Dockerfile.dev | 25 - services/sentinel/Dockerfile.package | 109 - services/sentinel/Dockerfile.test-server | 105 - services/sentinel/Makefile | 158 -- services/sentinel/README.md | 291 --- services/sentinel/api/types.go | 307 --- services/sentinel/api/types_test.go | 340 --- services/sentinel/architecture.yml | 524 ----- services/sentinel/cmd/ja4sentinel/main.go | 357 ---- .../sentinel/cmd/ja4sentinel/main_test.go | 221 -- services/sentinel/config.yml.example | 57 - services/sentinel/docker-compose.test.yml | 49 - services/sentinel/go.mod | 21 - services/sentinel/go.sum | 27 - services/sentinel/internal/capture/capture.go | 397 ---- .../sentinel/internal/capture/capture_test.go | 661 ------ services/sentinel/internal/config/loader.go | 295 --- .../sentinel/internal/config/loader_test.go | 1008 --------- .../sentinel/internal/fingerprint/engine.go | 192 -- .../internal/fingerprint/engine_test.go | 585 ------ .../internal/integration/pipeline_test.go | 402 ---- .../sentinel/internal/ipfilter/ipfilter.go | 15 - .../internal/ipfilter/ipfilter_test.go | 160 -- .../internal/logging/logger_factory.go | 19 - .../internal/logging/service_logger.go | 47 - .../internal/logging/service_logger_test.go | 79 - services/sentinel/internal/output/writers.go | 644 ------ .../sentinel/internal/output/writers_test.go | 1110 ---------- services/sentinel/internal/tlsparse/parser.go | 1015 --------- .../sentinel/internal/tlsparse/parser_test.go | 1824 ---------------- .../sentinel/packaging/logrotate/ja4sentinel | 17 - .../sentinel/packaging/rpm/ja4sentinel.spec | 328 --- .../packaging/systemd/ja4sentinel.service | 41 - shared/go/ja4common/config/loader.go | 114 - shared/go/ja4common/config/loader_test.go | 139 -- shared/go/ja4common/go.mod | 9 - shared/go/ja4common/ipfilter/ipfilter.go | 84 - shared/go/ja4common/ipfilter/ipfilter_test.go | 160 -- shared/go/ja4common/logger/logger.go | 263 --- shared/go/ja4common/logger/logger_test.go | 139 -- shared/go/ja4common/shutdown/handler.go | 45 - shared/go/ja4common/shutdown/handler_test.go | 133 -- tests/integration/README.md | 120 +- tests/integration/docker-compose.yml | 169 -- tests/integration/platform/Dockerfile | 97 - tests/integration/platform/clickhouse-init.sh | 48 - tests/integration/platform/correlator.yml | 51 - tests/integration/platform/entrypoint.sh | 59 - .../platform/httpd-integration.conf | 40 - tests/integration/platform/sentinel.yml | 18 - tests/integration/run-tests.sh | 411 ---- tests/integration/verify_mvs.py | 313 --- 252 files changed, 34 insertions(+), 67348 deletions(-) delete mode 100644 go.work.sum delete mode 100644 old/services/correlator/.dockerignore delete mode 100644 old/services/correlator/.env.example delete mode 100644 old/services/correlator/.github/workflows/ci.yml delete mode 100644 old/services/correlator/.gitignore delete mode 100644 old/services/correlator/Dockerfile delete mode 100644 old/services/correlator/Dockerfile.package delete mode 100644 old/services/correlator/Makefile delete mode 100644 old/services/correlator/README.md delete mode 100644 old/services/correlator/architecture.yml delete mode 100644 old/services/correlator/cmd/logcorrelator/main.go delete mode 100644 old/services/correlator/config.example.yml delete mode 100644 old/services/correlator/docs/detection.md delete mode 100644 old/services/correlator/go.mod delete mode 100644 old/services/correlator/go.sum delete mode 100644 old/services/correlator/idees/champs.md delete mode 100644 old/services/correlator/idees/idees.txt delete mode 100644 old/services/correlator/idees/views.md delete mode 100644 old/services/correlator/internal/adapters/inbound/unixsocket/source.go delete mode 100644 old/services/correlator/internal/adapters/inbound/unixsocket/source_test.go delete mode 100644 old/services/correlator/internal/adapters/outbound/clickhouse/sink.go delete mode 100644 old/services/correlator/internal/adapters/outbound/clickhouse/sink_test.go delete mode 100644 old/services/correlator/internal/adapters/outbound/file/sink.go delete mode 100644 old/services/correlator/internal/adapters/outbound/file/sink_test.go delete mode 100644 old/services/correlator/internal/adapters/outbound/multi/sink.go delete mode 100644 old/services/correlator/internal/adapters/outbound/multi/sink_test.go delete mode 100644 old/services/correlator/internal/adapters/outbound/stdout/sink.go delete mode 100644 old/services/correlator/internal/adapters/outbound/stdout/sink_test.go delete mode 100644 old/services/correlator/internal/app/orchestrator.go delete mode 100644 old/services/correlator/internal/app/orchestrator_test.go delete mode 100644 old/services/correlator/internal/config/config.go delete mode 100644 old/services/correlator/internal/config/config_test.go delete mode 100644 old/services/correlator/internal/domain/correlated_log.go delete mode 100644 old/services/correlator/internal/domain/correlated_log_test.go delete mode 100644 old/services/correlator/internal/domain/correlation_service.go delete mode 100644 old/services/correlator/internal/domain/correlation_service_test.go delete mode 100644 old/services/correlator/internal/domain/event.go delete mode 100644 old/services/correlator/internal/observability/logger.go delete mode 100644 old/services/correlator/internal/observability/logger_test.go delete mode 100644 old/services/correlator/internal/observability/metrics.go delete mode 100644 old/services/correlator/internal/observability/metrics_server.go delete mode 100644 old/services/correlator/internal/ports/source.go delete mode 100644 old/services/correlator/logcorrelator.service delete mode 100644 old/services/correlator/packaging/rpm/logcorrelator.spec delete mode 100644 old/services/correlator/packaging/rpm/logrotate delete mode 100755 old/services/correlator/packaging/test/test-rpm.sh delete mode 100755 old/services/correlator/scripts/audit-architecture.sh delete mode 100755 old/services/correlator/scripts/test-correlation-advanced.py delete mode 100755 old/services/correlator/scripts/test-correlation.sh delete mode 100644 old/services/correlator/sql/bots.sql delete mode 100644 old/services/correlator/sql/init.sql delete mode 100644 old/services/correlator/sql/migrations/01_ttl_adjustments.sql delete mode 100644 old/services/correlator/sql/migrations/02_detection_features.sql delete mode 100644 old/services/correlator/sql/migrations/03_remove_ua_browser_detection.sql delete mode 100644 old/services/correlator/sql/migrations/04_http2_fields.sql delete mode 100644 old/services/correlator/sql/migrations/05_fleet_metrics_tables.sql delete mode 100644 old/services/correlator/sql/migrations/06_browser_signature_detection.sql delete mode 100644 old/services/correlator/sql/tables.sql delete mode 100644 old/services/mod-reqin-log/.gitignore delete mode 100644 old/services/mod-reqin-log/.gitlab-ci.yml delete mode 100644 old/services/mod-reqin-log/CMakeLists.txt delete mode 100644 old/services/mod-reqin-log/Dockerfile.package delete mode 100644 old/services/mod-reqin-log/Dockerfile.tests delete mode 100644 old/services/mod-reqin-log/LICENSE delete mode 100644 old/services/mod-reqin-log/Makefile delete mode 100644 old/services/mod-reqin-log/README.md delete mode 100644 old/services/mod-reqin-log/architecture.yml delete mode 100644 old/services/mod-reqin-log/conf/mod_reqin_log.conf delete mode 100644 old/services/mod-reqin-log/mod_reqin_log.spec delete mode 100644 old/services/mod-reqin-log/src/mod_reqin_log.c delete mode 100644 old/services/mod-reqin-log/src/mod_reqin_log.h delete mode 100644 old/services/mod-reqin-log/tests/unit/test_config_parsing.c delete mode 100644 old/services/mod-reqin-log/tests/unit/test_h2_parsing.c delete mode 100644 old/services/mod-reqin-log/tests/unit/test_header_handling.c delete mode 100644 old/services/mod-reqin-log/tests/unit/test_json_serialization.c delete mode 100644 old/services/mod-reqin-log/tests/unit/test_module_real.c delete mode 100644 old/services/sentinel/.dockerignore delete mode 100644 old/services/sentinel/.env.example delete mode 100644 old/services/sentinel/.github/workflows/build-rpm.yml delete mode 100644 old/services/sentinel/.gitignore delete mode 100644 old/services/sentinel/Dockerfile delete mode 100644 old/services/sentinel/Dockerfile.dev delete mode 100644 old/services/sentinel/Dockerfile.package delete mode 100644 old/services/sentinel/Dockerfile.test-server delete mode 100644 old/services/sentinel/Makefile delete mode 100644 old/services/sentinel/README.md delete mode 100644 old/services/sentinel/api/types.go delete mode 100644 old/services/sentinel/api/types_test.go delete mode 100644 old/services/sentinel/architecture.yml delete mode 100644 old/services/sentinel/cmd/ja4sentinel/main.go delete mode 100644 old/services/sentinel/cmd/ja4sentinel/main_test.go delete mode 100644 old/services/sentinel/config.yml.example delete mode 100644 old/services/sentinel/docker-compose.test.yml delete mode 100644 old/services/sentinel/go.mod delete mode 100644 old/services/sentinel/go.sum delete mode 100644 old/services/sentinel/internal/capture/capture.go delete mode 100644 old/services/sentinel/internal/capture/capture_test.go delete mode 100644 old/services/sentinel/internal/config/loader.go delete mode 100644 old/services/sentinel/internal/config/loader_test.go delete mode 100644 old/services/sentinel/internal/fingerprint/engine.go delete mode 100644 old/services/sentinel/internal/fingerprint/engine_test.go delete mode 100644 old/services/sentinel/internal/integration/pipeline_test.go delete mode 100644 old/services/sentinel/internal/ipfilter/ipfilter.go delete mode 100644 old/services/sentinel/internal/ipfilter/ipfilter_test.go delete mode 100644 old/services/sentinel/internal/logging/logger_factory.go delete mode 100644 old/services/sentinel/internal/logging/service_logger.go delete mode 100644 old/services/sentinel/internal/logging/service_logger_test.go delete mode 100644 old/services/sentinel/internal/output/writers.go delete mode 100644 old/services/sentinel/internal/output/writers_test.go delete mode 100644 old/services/sentinel/internal/tlsparse/parser.go delete mode 100644 old/services/sentinel/internal/tlsparse/parser_test.go delete mode 100644 old/services/sentinel/packaging/logrotate/ja4sentinel delete mode 100644 old/services/sentinel/packaging/rpm/ja4sentinel.spec delete mode 100644 old/services/sentinel/packaging/systemd/ja4sentinel.service delete mode 100644 services/correlator/.dockerignore delete mode 100644 services/correlator/.env.example delete mode 100644 services/correlator/.github/workflows/ci.yml delete mode 100644 services/correlator/.gitignore delete mode 100644 services/correlator/Dockerfile delete mode 100644 services/correlator/Dockerfile.package delete mode 100644 services/correlator/Makefile delete mode 100644 services/correlator/README.md delete mode 100644 services/correlator/architecture.yml delete mode 100644 services/correlator/cmd/logcorrelator/main.go delete mode 100644 services/correlator/config.example.yml delete mode 100644 services/correlator/docs/detection.md delete mode 100644 services/correlator/go.mod delete mode 100644 services/correlator/go.sum delete mode 100644 services/correlator/idees/champs.md delete mode 100644 services/correlator/idees/idees.txt delete mode 100644 services/correlator/idees/views.md delete mode 100644 services/correlator/internal/adapters/inbound/unixsocket/source.go delete mode 100644 services/correlator/internal/adapters/inbound/unixsocket/source_test.go delete mode 100644 services/correlator/internal/adapters/outbound/clickhouse/sink.go delete mode 100644 services/correlator/internal/adapters/outbound/clickhouse/sink_test.go delete mode 100644 services/correlator/internal/adapters/outbound/file/sink.go delete mode 100644 services/correlator/internal/adapters/outbound/file/sink_test.go delete mode 100644 services/correlator/internal/adapters/outbound/multi/sink.go delete mode 100644 services/correlator/internal/adapters/outbound/multi/sink_test.go delete mode 100644 services/correlator/internal/adapters/outbound/stdout/sink.go delete mode 100644 services/correlator/internal/adapters/outbound/stdout/sink_test.go delete mode 100644 services/correlator/internal/app/orchestrator.go delete mode 100644 services/correlator/internal/app/orchestrator_test.go delete mode 100644 services/correlator/internal/config/config.go delete mode 100644 services/correlator/internal/config/config_test.go delete mode 100644 services/correlator/internal/domain/correlated_log.go delete mode 100644 services/correlator/internal/domain/correlated_log_test.go delete mode 100644 services/correlator/internal/domain/correlation_service.go delete mode 100644 services/correlator/internal/domain/correlation_service_test.go delete mode 100644 services/correlator/internal/domain/event.go delete mode 100644 services/correlator/internal/observability/logger.go delete mode 100644 services/correlator/internal/observability/logger_test.go delete mode 100644 services/correlator/internal/observability/metrics.go delete mode 100644 services/correlator/internal/observability/metrics_server.go delete mode 100644 services/correlator/internal/ports/source.go delete mode 100644 services/correlator/logcorrelator.service delete mode 100644 services/correlator/packaging/rpm/logcorrelator.spec delete mode 100644 services/correlator/packaging/rpm/logrotate delete mode 100755 services/correlator/packaging/test/test-rpm.sh delete mode 100755 services/correlator/scripts/audit-architecture.sh delete mode 100755 services/correlator/scripts/test-correlation-advanced.py delete mode 100755 services/correlator/scripts/test-correlation.sh delete mode 100644 services/correlator/sql/bots.sql delete mode 100644 services/correlator/sql/init.sql delete mode 100644 services/correlator/sql/migrations/01_ttl_adjustments.sql delete mode 100644 services/correlator/sql/migrations/02_detection_features.sql delete mode 100644 services/correlator/sql/migrations/03_remove_ua_browser_detection.sql delete mode 100644 services/correlator/sql/migrations/04_http2_fields.sql delete mode 100644 services/correlator/sql/migrations/05_fleet_metrics_tables.sql delete mode 100644 services/correlator/sql/migrations/06_browser_signature_detection.sql delete mode 100644 services/correlator/sql/tables.sql delete mode 100644 services/mod-reqin-log/.gitignore delete mode 100644 services/mod-reqin-log/.gitlab-ci.yml delete mode 100644 services/mod-reqin-log/CMakeLists.txt delete mode 100644 services/mod-reqin-log/Dockerfile.package delete mode 100644 services/mod-reqin-log/Dockerfile.tests delete mode 100644 services/mod-reqin-log/LICENSE delete mode 100644 services/mod-reqin-log/Makefile delete mode 100644 services/mod-reqin-log/README.md delete mode 100644 services/mod-reqin-log/architecture.yml delete mode 100644 services/mod-reqin-log/conf/mod_reqin_log.conf delete mode 100644 services/mod-reqin-log/mod_reqin_log.spec delete mode 100644 services/mod-reqin-log/src/mod_reqin_log.c delete mode 100644 services/mod-reqin-log/src/mod_reqin_log.h delete mode 100644 services/mod-reqin-log/tests/unit/test_config_parsing.c delete mode 100644 services/mod-reqin-log/tests/unit/test_h2_parsing.c delete mode 100644 services/mod-reqin-log/tests/unit/test_header_handling.c delete mode 100644 services/mod-reqin-log/tests/unit/test_json_serialization.c delete mode 100644 services/mod-reqin-log/tests/unit/test_module_real.c delete mode 100644 services/sentinel/.dockerignore delete mode 100644 services/sentinel/.env.example delete mode 100644 services/sentinel/.github/workflows/build-rpm.yml delete mode 100644 services/sentinel/.gitignore delete mode 100644 services/sentinel/Dockerfile delete mode 100644 services/sentinel/Dockerfile.dev delete mode 100644 services/sentinel/Dockerfile.package delete mode 100644 services/sentinel/Dockerfile.test-server delete mode 100644 services/sentinel/Makefile delete mode 100644 services/sentinel/README.md delete mode 100644 services/sentinel/api/types.go delete mode 100644 services/sentinel/api/types_test.go delete mode 100644 services/sentinel/architecture.yml delete mode 100644 services/sentinel/cmd/ja4sentinel/main.go delete mode 100644 services/sentinel/cmd/ja4sentinel/main_test.go delete mode 100644 services/sentinel/config.yml.example delete mode 100644 services/sentinel/docker-compose.test.yml delete mode 100644 services/sentinel/go.mod delete mode 100644 services/sentinel/go.sum delete mode 100644 services/sentinel/internal/capture/capture.go delete mode 100644 services/sentinel/internal/capture/capture_test.go delete mode 100644 services/sentinel/internal/config/loader.go delete mode 100644 services/sentinel/internal/config/loader_test.go delete mode 100644 services/sentinel/internal/fingerprint/engine.go delete mode 100644 services/sentinel/internal/fingerprint/engine_test.go delete mode 100644 services/sentinel/internal/integration/pipeline_test.go delete mode 100644 services/sentinel/internal/ipfilter/ipfilter.go delete mode 100644 services/sentinel/internal/ipfilter/ipfilter_test.go delete mode 100644 services/sentinel/internal/logging/logger_factory.go delete mode 100644 services/sentinel/internal/logging/service_logger.go delete mode 100644 services/sentinel/internal/logging/service_logger_test.go delete mode 100644 services/sentinel/internal/output/writers.go delete mode 100644 services/sentinel/internal/output/writers_test.go delete mode 100644 services/sentinel/internal/tlsparse/parser.go delete mode 100644 services/sentinel/internal/tlsparse/parser_test.go delete mode 100644 services/sentinel/packaging/logrotate/ja4sentinel delete mode 100644 services/sentinel/packaging/rpm/ja4sentinel.spec delete mode 100644 services/sentinel/packaging/systemd/ja4sentinel.service delete mode 100644 shared/go/ja4common/config/loader.go delete mode 100644 shared/go/ja4common/config/loader_test.go delete mode 100644 shared/go/ja4common/go.mod delete mode 100644 shared/go/ja4common/ipfilter/ipfilter.go delete mode 100644 shared/go/ja4common/ipfilter/ipfilter_test.go delete mode 100644 shared/go/ja4common/logger/logger.go delete mode 100644 shared/go/ja4common/logger/logger_test.go delete mode 100644 shared/go/ja4common/shutdown/handler.go delete mode 100644 shared/go/ja4common/shutdown/handler_test.go delete mode 100644 tests/integration/docker-compose.yml delete mode 100644 tests/integration/platform/Dockerfile delete mode 100755 tests/integration/platform/clickhouse-init.sh delete mode 100644 tests/integration/platform/correlator.yml delete mode 100755 tests/integration/platform/entrypoint.sh delete mode 100644 tests/integration/platform/httpd-integration.conf delete mode 100644 tests/integration/platform/sentinel.yml delete mode 100755 tests/integration/run-tests.sh delete mode 100644 tests/integration/verify_mvs.py diff --git a/Makefile b/Makefile index 118b1a3..2bea9cc 100644 --- a/Makefile +++ b/Makefile @@ -10,10 +10,8 @@ VERSION ?= $(shell git describe --tags --always 2>/dev/null || echo dev) build-ja4ebpf test-ja4ebpf rpm-ja4ebpf \ build-bot-detector test-bot-detector \ build-dashboard test-dashboard \ - test-ja4common-python \ test-all-stacks test-nginx test-nginx-varnish test-hitch-varnish test-apache \ test-matrix \ - test-integration test-integration-keep test-integration-down \ reload-prod-logs init-stack import-prod-data init-and-import \ purge-db @@ -35,7 +33,6 @@ help: ## Affiche cette aide @echo " make test-ja4ebpf Tests Go ja4ebpf" @echo " make test-bot-detector Tests Python bot-detector" @echo " make test-dashboard Tests Python dashboard" - @echo " make test-ja4common-python Tests Python ja4_common" @echo "" @echo " Tests d'intégration (par stack)" @echo " make test-all-stacks Toutes les stacks sur Rocky Linux 9" @@ -66,7 +63,7 @@ help: ## Affiche cette aide build-all: build-ja4ebpf build-bot-detector build-dashboard @echo "All services built." -test-all: test-ja4ebpf test-bot-detector test-dashboard test-ja4common-python +test-all: test-ja4ebpf test-bot-detector test-dashboard @echo "All unit tests completed." rpm-all: rpm-ja4ebpf @@ -134,15 +131,6 @@ test-dashboard: . docker run --rm ja4-platform/dashboard-tests:latest -# ── shared/python/ja4_common ───────────────────────────────────────────────── - -test-ja4common-python: - docker build \ - -f shared/python/ja4_common/Dockerfile.tests \ - -t ja4-platform/ja4common-python-tests:latest \ - shared/python/ja4_common/ - docker run --rm ja4-platform/ja4common-python-tests:latest - # ── Tests d'intégration par stack ──────────────────────────────────────────── test-all-stacks: ## Toutes les stacks sur la distro par défaut (Rocky Linux 9) @@ -167,21 +155,6 @@ test-matrix: ## Toutes stacks × el8 + el9 + el10 $${MATRIX_STACKS:+--stacks=$${MATRIX_STACKS}} \ $${MATRIX_DISTROS:+--distros=$${MATRIX_DISTROS}} -# ── Compat : anciens targets d'intégration ─────────────────────────────────── - -test-integration: ## Ancien target — alias vers test-all-stacks - $(MAKE) test-all-stacks - -test-integration-keep: - cd tests/integration && bash run-all-stacks.sh --no-down - -test-integration-down: - cd tests/integration && \ - for stack in apache nginx nginx-varnish hitch-varnish; do \ - [ -f "$$stack/docker-compose.yml" ] && \ - docker compose -f "$$stack/docker-compose.yml" down -v --remove-orphans 2>/dev/null || true; \ - done - # ── Base de données ─────────────────────────────────────────────────────────── reload-prod-logs: diff --git a/go.work b/go.work index 3a151b4..3b3103e 100644 --- a/go.work +++ b/go.work @@ -1,6 +1,3 @@ go 1.24.6 -use ( - ./shared/go/ja4common - ./services/ja4ebpf -) +use ./services/ja4ebpf diff --git a/go.work.sum b/go.work.sum deleted file mode 100644 index e7d96a9..0000000 --- a/go.work.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= diff --git a/old/services/correlator/.dockerignore b/old/services/correlator/.dockerignore deleted file mode 100644 index 5d5369f..0000000 --- a/old/services/correlator/.dockerignore +++ /dev/null @@ -1,19 +0,0 @@ -# Build outputs -dist/ - -# Dependency directories -vendor/ - -# IDE -.idea/ -.vscode/ -*.swp -*.swo -*~ - -# OS -.DS_Store -Thumbs.db - -# Aider cache -.aider* diff --git a/old/services/correlator/.env.example b/old/services/correlator/.env.example deleted file mode 100644 index 0f036d0..0000000 --- a/old/services/correlator/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -# correlator configuration — DO NOT COMMIT real values -LOGCORRELATOR_CLICKHOUSE_DSN=clickhouse://data_writer:ChangeMe@clickhouse:9000/ja4_logs diff --git a/old/services/correlator/.github/workflows/ci.yml b/old/services/correlator/.github/workflows/ci.yml deleted file mode 100644 index 92d1b8d..0000000 --- a/old/services/correlator/.github/workflows/ci.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Build and Test - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.21' - - - name: Download dependencies - run: go mod download - - - name: Run tests with coverage - run: | - go test -race -coverprofile=coverage.txt -covermode=atomic ./... - TOTAL=$(go tool cover -func=coverage.txt | grep total | awk '{gsub(/%/, "", $3); print $3}') - echo "Coverage: ${TOTAL}%" - if (( $(echo "$TOTAL < 80" | bc -l) )); then - echo "Coverage ${TOTAL}% is below 80% threshold" - exit 1 - fi - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - file: ./coverage.txt - - build: - runs-on: ubuntu-latest - needs: test - steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.21' - - - name: Build binary - run: | - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ - -ldflags="-w -s" \ - -o logcorrelator \ - ./cmd/logcorrelator - - - name: Upload binary artifact - uses: actions/upload-artifact@v4 - with: - name: logcorrelator-linux-amd64 - path: logcorrelator - - docker: - runs-on: ubuntu-latest - needs: test - steps: - - uses: actions/checkout@v4 - - - name: Build Docker image - run: docker build -t logcorrelator:latest . - - - name: Run tests in Docker - run: | - docker run --rm logcorrelator:latest --help || true diff --git a/old/services/correlator/.gitignore b/old/services/correlator/.gitignore deleted file mode 100644 index fa69443..0000000 --- a/old/services/correlator/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# Build directory -/build/ -/dist/ - -# Binaries -*.exe -*.exe~ -*.dll -*.so -*.dylib -/logcorrelator - -# Test binary -*.test - -# Output of the go coverage tool -*.out - -# Dependency directories -vendor/ - -# IDE -.idea/ -.vscode/ -*.swp -*.swo -*~ - -# OS -.DS_Store -Thumbs.db -.aider* diff --git a/old/services/correlator/Dockerfile b/old/services/correlator/Dockerfile deleted file mode 100644 index 54c4d4f..0000000 --- a/old/services/correlator/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# syntax=docker/dockerfile:1 -FROM golang:1.24 AS builder - -WORKDIR /build - -RUN apt-get update && apt-get install -y --no-install-recommends git bc && rm -rf /var/lib/apt/lists/* - -COPY go.work go.work.sum* ./ -COPY shared/go/ja4common/ ./shared/go/ja4common/ -COPY services/sentinel/go.mod services/sentinel/go.sum* ./services/sentinel/ -COPY services/correlator/go.mod services/correlator/go.sum* ./services/correlator/ - -WORKDIR /build/services/correlator -RUN --mount=type=cache,target=/go/pkg/mod go mod download - -COPY services/correlator/ /build/services/correlator/ - -ARG SKIP_TESTS=false -RUN --mount=type=cache,target=/go/pkg/mod \ - if [ "$SKIP_TESTS" = "false" ]; then \ - go test -race -coverprofile=coverage.txt -covermode=atomic ./... && \ - echo "=== Coverage Report ===" && \ - go tool cover -func=coverage.txt | grep total && \ - TOTAL=$(go tool cover -func=coverage.txt | grep total | awk '{gsub(/%/, "", $3); print $3}') && \ - echo "Total coverage: ${TOTAL}%" && \ - if (( $(echo "$TOTAL < 60" | bc -l) )); then \ - echo "ERROR: Coverage ${TOTAL}% is below 60% threshold"; \ - exit 1; \ - fi && \ - echo "Coverage check passed!"; \ - else \ - echo "Skipping tests (SKIP_TESTS=true)"; \ - fi - -RUN --mount=type=cache,target=/go/pkg/mod \ - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ - -ldflags="-w -s" -o /usr/bin/correlator ./cmd/logcorrelator - -FROM scratch AS runtime -COPY --from=builder /usr/bin/correlator /usr/bin/correlator -COPY --from=builder /build/services/correlator/config.example.yml /etc/correlator/correlator.yml -ENTRYPOINT ["/usr/bin/correlator"] -CMD ["-config", "/etc/correlator/correlator.yml"] diff --git a/old/services/correlator/Dockerfile.package b/old/services/correlator/Dockerfile.package deleted file mode 100644 index e74d61a..0000000 --- a/old/services/correlator/Dockerfile.package +++ /dev/null @@ -1,108 +0,0 @@ -# syntax=docker/dockerfile:1 -# ============================================================================= -# correlator — Dockerfile de packaging RPM (Rocky Linux 8/9, AlmaLinux 10) -# Build context: monorepo root (ja4-platform/) -# Méthode: 1 builder Rocky → 1 rpm-builder (rpmbuild, 3 × dist) → 1 output alpine -# ============================================================================= - -# ============================================================================= -# Stage 1: Builder — compilation du binaire Go sur Rocky Linux 9 -# CGO_ENABLED=0 → binaire statique, mais compilé sur la même distro cible -# ============================================================================= -FROM rockylinux:9 AS builder - -WORKDIR /build - -RUN dnf install -y golang git && dnf clean all - -# Copie du workspace Go et du module partagé en premier (meilleur cache) -COPY go.work go.work.sum* ./ -COPY shared/go/ja4common/ ./shared/go/ja4common/ -COPY services/sentinel/go.mod services/sentinel/go.sum* ./services/sentinel/ -COPY services/correlator/go.mod services/correlator/go.sum* ./services/correlator/ - -WORKDIR /build/services/correlator -RUN go mod download - -COPY services/correlator/ /build/services/correlator/ - -ARG VERSION=dev -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ - go build -ldflags="-w -s -X main.Version=${VERSION}" \ - -o /tmp/correlator \ - ./cmd/logcorrelator - -# ============================================================================= -# Stage 2: rpm-builder — construction des RPMs avec rpmbuild -# Un seul stage, trois appels rpmbuild successifs (el8, el9, el10). -# Le spec lit les fichiers depuis %{_builddir} (répertoire BUILD de rpmbuild). -# ============================================================================= -FROM rockylinux:9 AS rpm-builder - -WORKDIR /package - -ARG VERSION=dev - -RUN dnf install -y rpm-build rpmdevtools systemd-rpm-macros && dnf clean all - -RUN mkdir -p /root/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} && \ - mkdir -p /packages/rpm/{el8,el9,el10} - -# Disposition des fichiers dans BUILD/ (attendue par le spec correlator) -RUN mkdir -p /root/rpmbuild/BUILD/usr/bin \ - /root/rpmbuild/BUILD/etc/logcorrelator \ - /root/rpmbuild/BUILD/etc/systemd/system \ - /root/rpmbuild/BUILD/etc/logrotate.d - -COPY --from=builder /tmp/correlator /root/rpmbuild/BUILD/usr/bin/logcorrelator -COPY services/correlator/config.example.yml /root/rpmbuild/BUILD/etc/logcorrelator/logcorrelator.yml -COPY services/correlator/config.example.yml /root/rpmbuild/BUILD/etc/logcorrelator/logcorrelator.yml.example -COPY services/correlator/logcorrelator.service /root/rpmbuild/BUILD/etc/systemd/system/logcorrelator.service -COPY services/correlator/packaging/rpm/logrotate /root/rpmbuild/BUILD/etc/logrotate.d/logcorrelator - -RUN chmod 755 /root/rpmbuild/BUILD/usr/bin/logcorrelator && \ - chmod 640 /root/rpmbuild/BUILD/etc/logcorrelator/logcorrelator.yml && \ - chmod 640 /root/rpmbuild/BUILD/etc/logcorrelator/logcorrelator.yml.example && \ - chmod 644 /root/rpmbuild/BUILD/etc/systemd/system/logcorrelator.service && \ - chmod 644 /root/rpmbuild/BUILD/etc/logrotate.d/logcorrelator - -COPY services/correlator/packaging/rpm/logcorrelator.spec /root/rpmbuild/SPECS/logcorrelator.spec - -# el8 -RUN rpmbuild --define "_topdir /root/rpmbuild" \ - --define "dist .el8" \ - --define "build_version ${VERSION}" \ - --target x86_64 \ - -bb /root/rpmbuild/SPECS/logcorrelator.spec && \ - cp /root/rpmbuild/RPMS/x86_64/*.el8.x86_64.rpm /packages/rpm/el8/ - -# el9 -RUN rpmbuild --define "_topdir /root/rpmbuild" \ - --define "dist .el9" \ - --define "build_version ${VERSION}" \ - --target x86_64 \ - -bb /root/rpmbuild/SPECS/logcorrelator.spec && \ - cp /root/rpmbuild/RPMS/x86_64/*.el9.x86_64.rpm /packages/rpm/el9/ - -# el10 -RUN rpmbuild --define "_topdir /root/rpmbuild" \ - --define "dist .el10" \ - --define "build_version ${VERSION}" \ - --target x86_64 \ - -bb /root/rpmbuild/SPECS/logcorrelator.spec && \ - cp /root/rpmbuild/RPMS/x86_64/*.el10.x86_64.rpm /packages/rpm/el10/ - -# ============================================================================= -# Stage 3: output — image finale contenant uniquement les RPMs -# ============================================================================= -FROM alpine:latest AS output - -WORKDIR /packages -COPY --from=rpm-builder /packages/rpm/el8/*.rpm /packages/rpm/el8/ -COPY --from=rpm-builder /packages/rpm/el9/*.rpm /packages/rpm/el9/ -COPY --from=rpm-builder /packages/rpm/el10/*.rpm /packages/rpm/el10/ - -CMD ["sh", "-c", \ - "echo '=== RPM el8 ===' && ls -la /packages/rpm/el8/ && \ - echo '' && echo '=== RPM el9 ===' && ls -la /packages/rpm/el9/ && \ - echo '' && echo '=== RPM el10 ===' && ls -la /packages/rpm/el10/"] diff --git a/old/services/correlator/Makefile b/old/services/correlator/Makefile deleted file mode 100644 index bc90d5f..0000000 --- a/old/services/correlator/Makefile +++ /dev/null @@ -1,148 +0,0 @@ -.PHONY: build build-docker test test-docker lint clean help docker-build-dev docker-build-runtime package package-rpm - -# Docker parameters -DOCKER=docker -# Use buildx for better cache management and parallel builds -DOCKER_BUILD=$(DOCKER) build -DOCKER_BUILDX=$(DOCKER) buildx -DOCKER_RUN=$(DOCKER) run - -# Image names -DEV_IMAGE=logcorrelator-dev:latest -RUNTIME_IMAGE=logcorrelator:latest -PACKAGER_IMAGE=logcorrelator-packager:latest -PACKAGER_IMAGE_EL8=logcorrelator-packager-el8:latest -PACKAGER_IMAGE_EL9=logcorrelator-packager-el9:latest -PACKAGER_IMAGE_EL10=logcorrelator-packager-el10:latest - -# Binary name -BINARY_NAME=logcorrelator -DIST_DIR=dist - -# Package version -PKG_VERSION ?= 1.1.22 - -# Enable BuildKit for better performance -export DOCKER_BUILDKIT=1 - -## build: Build the logcorrelator binary locally -build: - mkdir -p $(DIST_DIR) - go build -ldflags="-w -s" -o $(DIST_DIR)/$(BINARY_NAME) ./cmd/$(BINARY_NAME) - -## docker-build-dev: Build the development Docker image (with tests and coverage) -docker-build-dev: - $(DOCKER_BUILD) --target builder -t $(DEV_IMAGE) -f Dockerfile . - -## docker-build-dev-no-test: Build the development Docker image WITHOUT tests (faster) -docker-build-dev-no-test: - $(DOCKER_BUILD) --target builder --no-cache --build-arg SKIP_TESTS=true -t $(DEV_IMAGE) -f Dockerfile . - -## docker-build-runtime: Build the runtime Docker image (fast, no tests) -docker-build-runtime: - $(DOCKER_BUILD) --target runtime -t $(RUNTIME_IMAGE) -f Dockerfile . - -## test: Run unit tests locally -test: - go test -race -coverprofile=coverage.out ./... - -## test-docker: Run unit tests inside Docker container -test-docker: docker-build-dev - @echo "Tests already run in builder stage" - -## lint: Run linters -lint: - go vet ./... - gofmt -l . - -## fmt: Format all Go files -fmt: - gofmt -w . - -## package: Build RPM packages for all target distributions -package: package-rpm - -## package-rpm: Build RPM packages for Rocky Linux 8/9, AlmaLinux 10 (requires Docker) -## Uses buildx for parallel builds (el8, el9, el10 built simultaneously) -package-rpm: - mkdir -p $(DIST_DIR)/rpm/el8 $(DIST_DIR)/rpm/el9 $(DIST_DIR)/rpm/el10 - @echo "Starting parallel RPM builds for el8, el9, el10..." - # Build all three distributions in parallel using buildx - $(DOCKER_BUILDX) build --target output -t $(PACKAGER_IMAGE) \ - --build-arg VERSION=$(PKG_VERSION) \ - -f Dockerfile.package . \ - --load - @echo "Extracting RPM packages from Docker image..." - $(DOCKER_RUN) --rm -v $(PWD)/$(DIST_DIR)/rpm:/output/rpm $(PACKAGER_IMAGE) sh -c \ - "cp -r /packages/rpm/el8 /output/rpm/ && \ - cp -r /packages/rpm/el9 /output/rpm/ && \ - cp -r /packages/rpm/el10 /output/rpm/" - @echo "RPM packages created:" - @echo " Enterprise Linux 8 (el8):" - ls -la $(DIST_DIR)/rpm/el8/ 2>/dev/null || echo " (no packages)" - @echo " Enterprise Linux 9 (el9):" - ls -la $(DIST_DIR)/rpm/el9/ 2>/dev/null || echo " (no packages)" - @echo " Enterprise Linux 10 (el10):" - ls -la $(DIST_DIR)/rpm/el10/ 2>/dev/null || echo " (no packages)" - -## package-rpm-sequential: Build RPM packages sequentially (fallback if parallel fails) -package-rpm-sequential: - mkdir -p $(DIST_DIR)/rpm/el8 $(DIST_DIR)/rpm/el9 $(DIST_DIR)/rpm/el10 - @echo "Building RPM for el8..." - $(DOCKER_BUILD) --target rpm-el8-builder -t $(PACKAGER_IMAGE_EL8) \ - --build-arg VERSION=$(PKG_VERSION) \ - -f Dockerfile.package . - @echo "Building RPM for el9..." - $(DOCKER_BUILD) --target rpm-el9-builder -t $(PACKAGER_IMAGE_EL9) \ - --build-arg VERSION=$(PKG_VERSION) \ - -f Dockerfile.package . - @echo "Building RPM for el10..." - $(DOCKER_BUILD) --target rpm-el10-builder -t $(PACKAGER_IMAGE_EL10) \ - --build-arg VERSION=$(PKG_VERSION) \ - -f Dockerfile.package . - @echo "Extracting RPM packages..." - $(DOCKER_RUN) --rm -v $(PWD)/$(DIST_DIR)/rpm:/output/rpm \ - -v $(PACKAGER_IMAGE_EL8):/el8:ro \ - -v $(PACKAGER_IMAGE_EL9):/el9:ro \ - -v $(PACKAGER_IMAGE_EL10):/el10:ro \ - alpine:latest sh -c \ - "cp -r /el8/packages/rpm/el8 /output/rpm/ && \ - cp -r /el9/packages/rpm/el9 /output/rpm/ && \ - cp -r /el10/packages/rpm/el10 /output/rpm/" - -## test-package-rpm: Test RPM package installation in Docker -test-package-rpm: package-rpm - ./packaging/test/test-rpm.sh - -## test-package: Test RPM package installation -test-package: test-package-rpm - -## ci: Full CI pipeline (tests, build, packages, package tests) -ci: ci-test ci-build ci-package ci-package-test - -## ci-test: Run all tests for CI -ci-test: test lint - -## ci-build: Build for CI (production binary) -ci-build: build - -## ci-package: Build all packages for CI -ci-package: package - -## ci-package-test: Test all packages for CI -ci-package-test: test-package - -## clean: Clean build artifacts and Docker images -clean: - rm -rf $(DIST_DIR)/ - rm -f coverage.out - $(DOCKER) rmi $(DEV_IMAGE) 2>/dev/null || true - $(DOCKER) rmi $(RUNTIME_IMAGE) 2>/dev/null || true - $(DOCKER) rmi $(PACKAGER_IMAGE) 2>/dev/null || true - -## help: Show this help message -help: - @echo "Usage: make [target]" - @echo "" - @echo "Targets:" - @sed -n 's/^##//p' $(MAKEFILE_LIST) | column -t -s ':' | sed -e 's/^/ /' diff --git a/old/services/correlator/README.md b/old/services/correlator/README.md deleted file mode 100644 index a4e2deb..0000000 --- a/old/services/correlator/README.md +++ /dev/null @@ -1,426 +0,0 @@ -# logcorrelator - -Service de corrélation de logs HTTP et réseau écrit en Go. - -## Description - -**logcorrelator** reçoit deux flux de logs JSON via des sockets Unix datagrammes (SOCK_DGRAM) : -- **Source A** : logs HTTP applicatifs (Apache, reverse proxy) -- **Source B** : logs réseau (métadonnées IP/TCP, JA3/JA4, etc.) - -Il corrèle les événements sur la base de `src_ip + src_port` dans une fenêtre temporelle configurable, et produit des logs corrélés vers : -- Un fichier local (JSON lines) -- ClickHouse (pour analyse et archivage) - -Les logs opérationnels du service (démarrage, erreurs, métriques) sont écrits sur **stderr** et collectés par journald. Aucune donnée corrélée n'apparaît sur stdout. - -## Architecture - -``` -┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ -│ Source A │────▶│ │────▶│ File Sink │ -│ HTTP/Apache │ │ Correlation │ │ (JSON lines) │ -│ (Unix DGRAM) │ │ Service │ └─────────────────┘ -└─────────────────┘ │ │ - │ - Buffers │ ┌─────────────────┐ -┌─────────────────┐ │ - Time Window │────▶│ ClickHouse │ -│ Source B │────▶│ - Orphan Policy │ │ Sink │ -│ Réseau/JA4 │ │ - Keep-Alive │ └─────────────────┘ -│ (Unix DGRAM) │ └──────────────────┘ -└─────────────────┘ -``` - -Architecture hexagonale : domaine pur (`internal/domain`), ports abstraits (`internal/ports`), adaptateurs (`internal/adapters`), orchestration (`internal/app`). - -## Build (100% Docker) - -Tout le build, les tests et le packaging RPM s'exécutent dans des conteneurs : - -```bash -# Build complet avec tests (builder stage) -make docker-build-dev - -# Packaging RPM (el8, el9, el10) -make package-rpm - -# Build rapide sans tests -make docker-build-dev-no-test - -# Tests en local (nécessite Go 1.21+) -make test -``` - -### Prérequis - -- Docker 20.10+ - -## Installation - -### Packages RPM - -```bash -# Générer les packages -make package-rpm - -# Installer (Rocky Linux / AlmaLinux) -sudo dnf install -y dist/rpm/el8/logcorrelator-1.1.12-1.el8.x86_64.rpm -sudo dnf install -y dist/rpm/el9/logcorrelator-1.1.12-1.el9.x86_64.rpm -sudo dnf install -y dist/rpm/el10/logcorrelator-1.1.12-1.el10.x86_64.rpm - -# Démarrer -sudo systemctl enable --now logcorrelator -sudo systemctl status logcorrelator -``` - -### Build manuel - -```bash -# Binaire local (nécessite Go 1.21+) -go build -o logcorrelator ./cmd/logcorrelator -./logcorrelator -config config.example.yml -``` - -## Configuration - -Fichier YAML. Voir `config.example.yml` pour un exemple complet. - -```yaml -log: - level: INFO # DEBUG, INFO, WARN, ERROR - -inputs: - unix_sockets: - - name: http - source_type: A # Source HTTP - path: /var/run/logcorrelator/http.socket - format: json - socket_permissions: "0666" - - name: network - source_type: B # Source réseau - path: /var/run/logcorrelator/network.socket - format: json - socket_permissions: "0666" - -outputs: - file: - path: /var/log/logcorrelator/correlated.log - clickhouse: - enabled: false - dsn: clickhouse://user:pass@localhost:9000/db - table: http_logs_raw - batch_size: 500 - flush_interval_ms: 200 - max_buffer_size: 5000 - drop_on_overflow: true - timeout_ms: 1000 - stdout: - enabled: false # no-op pour les données ; logs opérationnels toujours sur stderr - -correlation: - time_window: - value: 10 - unit: s - orphan_policy: - apache_always_emit: true - apache_emit_delay_ms: 500 # délai avant émission orphelin A (ms) - network_emit: false - matching: - mode: one_to_many # Keep-Alive : un B peut corréler plusieurs A successifs - buffers: - max_http_items: 10000 - max_network_items: 20000 - ttl: - network_ttl_s: 120 # TTL remis à zéro à chaque corrélation (Keep-Alive) - # Exclure des IPs source (IPs uniques ou plages CIDR) - exclude_source_ips: - - 10.0.0.1 - - 172.16.0.0/12 - # Restreindre la corrélation à certains ports de destination (optionnel) - # Si la liste est vide, tous les ports sont corrélés - include_dest_ports: - - 80 - - 443 - -metrics: - enabled: false - addr: ":8080" -``` - -### Format du DSN ClickHouse - -``` -clickhouse://username:password@host:port/database -``` - -Ports : `9000` (natif, recommandé) ou `8123` (HTTP). - -## Format des logs - -### Source A (HTTP) - -```json -{ - "src_ip": "192.168.1.1", "src_port": 8080, - "dst_ip": "10.0.0.1", "dst_port": 443, - "timestamp": 1704110400000000000, - "method": "GET", "path": "/api/test" -} -``` - -### Source B (Réseau) - -```json -{ - "src_ip": "192.168.1.1", "src_port": 8080, - "dst_ip": "10.0.0.1", "dst_port": 443, - "ja3": "abc123", "ja4": "xyz789" -} -``` - -### Log corrélé (sortie) - -Structure JSON plate — tous les champs A et B sont fusionnés à la racine : - -```json -{ - "timestamp": "2024-01-01T12:00:00Z", - "src_ip": "192.168.1.1", "src_port": 8080, - "dst_ip": "10.0.0.1", "dst_port": 443, - "correlated": true, - "method": "GET", "path": "/api/test", - "ja3": "abc123", "ja4": "xyz789" -} -``` - -En cas de collision de champ entre A et B, les deux valeurs sont conservées avec préfixes `a_` et `b_`. - -Les orphelins A (sans B correspondant) sont émis avec `"correlated": false, "orphan_side": "A"`. - -## Schema ClickHouse - -Le fichier `sql/init.sql` contient le schéma complet prêt à l'emploi. - -```bash -clickhouse-client --multiquery < sql/init.sql -``` - -### Architecture des tables - -``` -http_logs_raw ← inserts du service (raw_json String) - │ - └─ mv_http_logs ← vue matérialisée (parse JSON → colonnes typées) - │ - ▼ - http_logs ← table requêtable par les analystes -``` - -### Table `http_logs` — colonnes - -| Groupe | Colonnes | -|---|---| -| Temporel | `time` DateTime, `log_date` Date | -| Réseau | `src_ip` IPv4, `src_port` UInt16, `dst_ip` IPv4, `dst_port` UInt16 | -| HTTP | `method`, `scheme`, `host`, `path`, `query`, `http_version` (LowCardinality) | -| Corrélation | `orphan_side`, `correlated` UInt8, `keepalives` UInt16, `a_timestamp`/`b_timestamp` UInt64, `conn_id` | -| IP meta | `ip_meta_df` UInt8, `ip_meta_id` UInt16, `ip_meta_total_length` UInt16, `ip_meta_ttl` UInt8 | -| TCP meta | `tcp_meta_options`, `tcp_meta_window_size` UInt32, `tcp_meta_mss` UInt16, `tcp_meta_window_scale` UInt8, `syn_to_clienthello_ms` Int32 | -| TLS / fingerprint | `tls_version`, `tls_sni`, `tls_alpn` (LowCardinality), `ja3`, `ja3_hash`, `ja4` | -| En-têtes HTTP | `header_user_agent`, `header_accept`, `header_accept_encoding`, `header_accept_language`, `header_x_request_id`, `header_x_trace_id`, `header_x_forwarded_for`, `header_sec_ch_ua*`, `header_sec_fetch_*` | - -### Utilisateurs et permissions - -```sql --- data_writer : INSERT sur http_logs_raw uniquement (compte du service) -GRANT INSERT ON ja4_logs.http_logs_raw TO data_writer; -GRANT SELECT ON ja4_logs.http_logs_raw TO data_writer; - --- analyst : lecture sur la table parsée -GRANT SELECT ON ja4_logs.http_logs TO analyst; -``` - -### Vérification de l'ingestion - -```sql --- Données brutes reçues -SELECT count(*), min(ingest_time), max(ingest_time) FROM ja4_logs.http_logs_raw; - --- Données parsées par la vue matérialisée -SELECT count(*), min(time), max(time) FROM ja4_logs.http_logs; - --- Derniers logs corrélés -SELECT time, src_ip, dst_ip, method, host, path, ja4 -FROM ja4_logs.http_logs -WHERE correlated = 1 -ORDER BY time DESC LIMIT 10; -``` - -## Signaux - -| Signal | Comportement | -|--------|--------------| -| `SIGINT` / `SIGTERM` | Arrêt gracieux (drain buffers, flush sinks) | -| `SIGHUP` | Réouverture des fichiers de sortie (log rotation) | - -## Logs internes - -Les logs opérationnels vont sur **stderr** : - -```bash -# Systemd -journalctl -u logcorrelator -f - -# Docker -docker logs -f logcorrelator -``` - -## Structure du projet - -``` -cmd/logcorrelator/ # Point d'entrée -internal/ - adapters/ - inbound/unixsocket/ # Lecture SOCK_DGRAM → NormalizedEvent - outbound/ - clickhouse/ # Sink ClickHouse (batch, retry, logging complet) - file/ # Sink fichier (JSON lines, SIGHUP reopen) - multi/ # Fan-out vers plusieurs sinks - stdout/ # No-op pour les données (logs opérationnels sur stderr) - app/ # Orchestrator (sources → corrélation → sinks) - config/ # Chargement/validation YAML - domain/ # CorrelationService, NormalizedEvent, CorrelatedLog - observability/ # Logger, métriques, serveur HTTP /metrics /health - ports/ # Interfaces EventSource, CorrelatedLogSink, CorrelationProcessor -config.example.yml # Exemple de configuration -Dockerfile # Build multi-stage (builder, runtime, dev) -Dockerfile.package # Packaging RPM multi-distros (el8, el9, el10) -Makefile # Cibles de build -architecture.yml # Spécification architecture -logcorrelator.service # Unité systemd -``` - -## Débogage - -### Logs DEBUG - -```yaml -log: - level: DEBUG -``` - -Exemples de logs produits : -``` -[unixsocket:http] DEBUG event received: source=A src_ip=192.168.1.1 src_port=8080 -[correlation] DEBUG processing A event: key=192.168.1.1:8080 -[correlation] DEBUG correlation found: A(src_ip=... src_port=... ts=...) + B(...) -[correlation] DEBUG A event has no matching B key in buffer: key=... -[correlation] DEBUG event excluded by IP filter: source=A src_ip=10.0.0.1 src_port=8080 -[correlation] DEBUG event excluded by dest port filter: source=A dst_port=22 -[correlation] DEBUG TTL reset for B event (Keep-Alive): key=... new_ttl=120s -[clickhouse] DEBUG batch sent: rows=42 table=http_logs_raw -``` - -### Serveur de métriques - -```yaml -metrics: - enabled: true - addr: ":8080" -``` - -`GET /health` → `{"status":"healthy"}` - -`GET /metrics` : - -```json -{ - "events_received_a": 1542, "events_received_b": 1498, - "correlations_success": 1450, "correlations_failed": 92, - "failed_no_match_key": 45, "failed_time_window": 23, - "failed_buffer_eviction": 5, "failed_ttl_expired": 12, - "failed_ip_excluded": 7, "failed_dest_port_filtered": 3, - "buffer_a_size": 23, "buffer_b_size": 18, - "orphans_emitted_a": 92, "orphans_pending_a": 4, - "keepalive_resets": 892 -} -``` - -### Diagnostic par métriques - -| Métrique élevée | Cause | Solution | -|---|---|---| -| `failed_no_match_key` | A et B n'ont pas le même `src_ip:src_port` | Vérifier les deux sources | -| `failed_time_window` | Timestamps trop éloignés | Augmenter `time_window.value` ou vérifier NTP | -| `failed_ttl_expired` | B expire avant corrélation | Augmenter `ttl.network_ttl_s` | -| `failed_buffer_eviction` | Buffers trop petits | Augmenter `buffers.max_http_items` / `max_network_items` | -| `failed_ip_excluded` | Traffic depuis IPs exclues | Normal si attendu | -| `failed_dest_port_filtered` | Traffic sur ports non listés | Vérifier `include_dest_ports` | -| `orphans_emitted_a` élevé | Beaucoup de A sans B | Vérifier que la source B envoie des événements | - -### Filtrage par IP source - -```yaml -correlation: - exclude_source_ips: - - 10.0.0.1 # IP unique (health checks) - - 172.16.0.0/12 # Plage CIDR -``` - -Les événements depuis ces IPs sont silencieusement ignorés (non corrélés, non émis en orphelin). La métrique `failed_ip_excluded` comptabilise les exclusions. - -### Filtrage par port de destination - -```yaml -correlation: - include_dest_ports: - - 80 # HTTP - - 443 # HTTPS - - 8080 - - 8443 -``` - -Si la liste est non vide, seuls les événements dont le `dst_port` est dans la liste participent à la corrélation. Les autres sont silencieusement ignorés. Liste vide = tous les ports corrélés (comportement par défaut). La métrique `failed_dest_port_filtered` comptabilise les exclusions. - -### Scripts de test - -```bash -# Script Bash (simple) -./scripts/test-correlation.sh -c 10 -v - -# Script Python (scénarios complets : basic, time window, keepalive, différentes IPs) -pip install requests -python3 scripts/test-correlation-advanced.py --all -``` - -## Troubleshooting - -### ClickHouse : erreurs d'insertion - -- **`No such column`** : vérifier que la table `http_logs_raw` utilise la colonne unique `raw_json` (pas de colonnes séparées) -- **`ACCESS_DENIED`** : `GRANT INSERT ON ja4_logs.http_logs_raw TO data_writer;` -- Les erreurs de flush sont loggées en ERROR dans les logs du service - -### Vue matérialisée vide - -Si `http_logs_raw` a des données mais `http_logs` est vide : -```sql --- Vérifier la vue -SHOW CREATE TABLE ja4_logs.mv_http_logs; --- Vérifier les permissions (la MV s'exécute sous le compte du service) -GRANT SELECT ON ja4_logs.http_logs_raw TO data_writer; -``` - -### Sockets Unix : permission denied - -Vérifier que `socket_permissions: "0666"` est configuré et que le répertoire `/var/run/logcorrelator` appartient à l'utilisateur `logcorrelator`. - -### Service systemd ne démarre pas - -```bash -journalctl -u logcorrelator -n 50 --no-pager -/usr/bin/logcorrelator -config /etc/logcorrelator/logcorrelator.yml -``` - -## License - -MIT diff --git a/old/services/correlator/architecture.yml b/old/services/correlator/architecture.yml deleted file mode 100644 index e3e37e9..0000000 --- a/old/services/correlator/architecture.yml +++ /dev/null @@ -1,974 +0,0 @@ -service: - name: logcorrelator - context: http-network-correlation - language: go - pattern: hexagonal - description: > - logcorrelator est un service système (lancé par systemd) écrit en Go, chargé - de recevoir deux flux de logs JSON via des sockets Unix, de corréler les - événements HTTP applicatifs (source A, typiquement Apache ou reverse proxy) - avec des événements réseau (source B, métadonnées IP/TCP, JA3/JA4, etc.) - sur la base de la combinaison strictement définie src_ip + src_port, avec - une fenêtre temporelle configurable. Le service supporte les connexions - HTTP Keep-Alive : un log réseau peut être corrélé à plusieurs logs HTTP - successifs (stratégie 1‑à‑N). La rétention en mémoire est bornée par des - tailles de caches configurables et un TTL dynamique pour la source B. Le - service émet toujours les événements A même lorsqu'aucun événement B n'est - disponible, n'émet jamais de logs B seuls, et pousse les résultats vers - ClickHouse et/ou un fichier local. - - Fonctionnalités de débogage incluses : - - Serveur de métriques HTTP (/metrics, /health) - - Logs DEBUG détaillés avec raisons des échecs de corrélation - - Filtrage des IPs source (exclude_source_ips) - - Scripts de test (Bash et Python) - - Métriques : événements reçus, corrélations, échecs par raison, buffers, orphelins - -runtime: - deployment: - unit_type: systemd - description: > - logcorrelator est livré sous forme de binaire autonome, exécuté comme un - service systemd. L'unité systemd assure le démarrage automatique au boot, - le redémarrage en cas de crash, et une intégration standard dans l'écosystème - Linux. - binary_path: /usr/bin/logcorrelator - config_path: /etc/logcorrelator/logcorrelator.yml - user: logcorrelator - group: logcorrelator - restart: on-failure - systemd_unit: - path: /etc/systemd/system/logcorrelator.service - content_example: | - [Unit] - Description=logcorrelator service - After=network.target - - [Service] - Type=simple - User=logcorrelator - Group=logcorrelator - ExecStart=/usr/bin/logcorrelator -config /etc/logcorrelator/logcorrelator.yml - ExecReload=/bin/kill -HUP $MAINPID - Restart=on-failure - RestartSec=5 - - # Security hardening - NoNewPrivileges=true - ProtectSystem=strict - ProtectHome=true - ReadWritePaths=/var/log/logcorrelator /var/run/logcorrelator /etc/logcorrelator - - # Resource limits - LimitNOFILE=65536 - - # Systemd timeouts - TimeoutStartSec=10 - TimeoutStopSec=30 - - [Install] - WantedBy=multi-user.target - os: - supported: - - rocky-linux-8 - - rocky-linux-9 - - almalinux-10 - - autres-linux-recentes - logs: - stdout_stderr: journald - structured: true - description: > - Les logs internes du service (erreurs, messages d'information) sont envoyés - vers stdout/stderr et collectés par journald. Ils sont structurés et ne - contiennent pas de données personnelles. - signals: - graceful_shutdown: - - SIGINT - - SIGTERM - reload: - - SIGHUP - description: > - SIGINT/SIGTERM : arrêt propre (arrêt des sockets, vidage des buffers, fermeture - des sinks). SIGHUP : réouverture des fichiers de sortie (utile pour la - rotation des logs via logrotate) sans arrêter le service. - filesystem: - description: > - Permissions et propriété des fichiers et répertoires utilisés par logcorrelator. - directories: - - path: /var/run/logcorrelator - owner: logcorrelator:logcorrelator - permissions: "0755" - purpose: > - Contient les sockets Unix (http.socket, network.socket). - Les sockets sont créés avec des permissions 0666 (world read/write). - - path: /var/log/logcorrelator - owner: logcorrelator:logcorrelator - permissions: "0750" - purpose: > - Contient les logs corrélés (correlated.log). - - path: /var/lib/logcorrelator - owner: logcorrelator:logcorrelator - permissions: "0750" - purpose: > - Répertoire home du service (données internes). - - path: /etc/logcorrelator - owner: logcorrelator:logcorrelator - permissions: "0750" - purpose: > - Contient la configuration (logcorrelator.yml, logcorrelator.yml.example). - files: - - path: /etc/logcorrelator/logcorrelator.yml - owner: logcorrelator:logcorrelator - permissions: "0640" - rpm_directive: "%config(noreplace)" - - path: /etc/logcorrelator/logcorrelator.yml.example - owner: logcorrelator:logcorrelator - permissions: "0640" - - path: /etc/systemd/system/logcorrelator.service - owner: root:root - permissions: "0644" - - path: /etc/logrotate.d/logcorrelator - owner: root:root - permissions: "0644" - rpm_directive: "%config(noreplace)" - sockets: - - path: /var/run/logcorrelator/http.socket - owner: logcorrelator:logcorrelator - permissions: "0666" - type: unix_datagram - purpose: "Source A - logs HTTP applicatifs" - - path: /var/run/logcorrelator/network.socket - owner: logcorrelator:logcorrelator - permissions: "0666" - type: unix_datagram - purpose: "Source B - logs réseau" - -packaging: - description: > - logcorrelator est distribué sous forme de packages .rpm (Rocky Linux, AlmaLinux, - RHEL), construits intégralement dans des conteneurs. Le changelog RPM est mis - à jour à chaque changement de version. - Tous les numéros de version doivent être cohérents entre le spec RPM, le Makefile - (PKG_VERSION), le CHANGELOG.md et les tags git. - - Politique de mise à jour de la configuration : - - Le fichier logcorrelator.yml est marqué %config(noreplace) : il n'est JAMAIS - écrasé lors d'une mise à jour. La configuration existante est préservée. - - Le fichier logcorrelator.yml.example est TOUJOURS mis à jour pour refléter - les nouvelles options de configuration disponibles. - - Lors de la première installation, si logcorrelator.yml n'existe pas, il est - créé à partir de logcorrelator.yml.example. - formats: - - rpm - target_distros: - - rocky-linux-8 - - rocky-linux-9 - - almalinux-10 - - rhel-8 - - rhel-9 - - rhel-10 - rpm: - tool: fpm - changelog: - source: git # ou CHANGELOG.md - description: > - À chaque build, un script génère un fichier de changelog RPM à partir de - l'historique (tags/commits) et le passe à fpm (option --rpm-changelog). - contents: - - path: /usr/bin/logcorrelator - type: binary - - path: /etc/logcorrelator/logcorrelator.yml - type: config - directives: "%config(noreplace)" - behavior: > - Jamais écrasé lors des mises à jour. Préservé automatiquement par RPM. - Créé uniquement lors de la première installation s'il n'existe pas. - - path: /etc/logcorrelator/logcorrelator.yml.example - type: doc - behavior: > - TOUJOURS mis à jour lors des mises à jour. Sert de référence pour les - nouvelles options de configuration disponibles. - - path: /etc/systemd/system/logcorrelator.service - type: systemd_unit - - path: /etc/logrotate.d/logcorrelator - type: logrotate_script - directives: "%config(noreplace)" - logrotate_example: | - /var/log/logcorrelator/correlated.log { - daily - rotate 7 - compress - delaycompress - missingok - notifempty - create 0640 logcorrelator logcorrelator - sharedscripts - postrotate - /bin/systemctl reload logcorrelator > /dev/null 2>&1 || true - endscript - } - -config: - format: yaml - location: /etc/logcorrelator/logcorrelator.yml - reload_strategy: signal_sighup_for_files - description: > - Toute la configuration est centralisée dans un fichier YAML lisible. Le RPM - fournit aussi un fichier d'exemple mis à jour à chaque version. - example: | - # /etc/logcorrelator/logcorrelator.yml - - log: - level: INFO # DEBUG, INFO, WARN, ERROR - - inputs: - unix_sockets: - # Source HTTP (A) : logs applicatifs en JSON, 1 datagramme = 1 log. - - name: http - source_type: A - path: /var/run/logcorrelator/http.socket - format: json - socket_permissions: "0666" - - # Source réseau (B) : logs IP/TCP/JA3... en JSON, 1 datagramme = 1 log. - - name: network - source_type: B - path: /var/run/logcorrelator/network.socket - format: json - socket_permissions: "0666" - - outputs: - file: - enabled: true - path: /var/log/logcorrelator/correlated.log - - clickhouse: - enabled: false - dsn: clickhouse://user:pass@localhost:9000/db - table: correlated_logs_http_network - batch_size: 500 - flush_interval_ms: 200 - max_buffer_size: 5000 - drop_on_overflow: true - async_insert: true - timeout_ms: 1000 - - stdout: - enabled: false - level: INFO # DEBUG: tous les logs (y compris orphelins), INFO: seulement corrélés, WARN: corrélés seulement, ERROR: aucun - - correlation: - # Fenêtre de corrélation : si le log HTTP arrive avant le réseau, il attend - # au plus cette durée (sauf éviction du cache HTTP). - # Augmentée à 10s pour supporter le Keep-Alive HTTP. - time_window: - value: 10 - unit: s - - orphan_policy: - apache_always_emit: true # Toujours émettre les événements A, même sans correspondance B - network_emit: false # Ne jamais émettre les événements B seuls - - matching: - mode: one_to_many # Keep‑Alive : un B peut corréler plusieurs A. - - buffers: - # Tailles max des caches en mémoire (en nombre de logs). - max_http_items: 10000 - max_network_items: 20000 - - ttl: - # Durée de vie standard d'un log réseau (B) en mémoire. Chaque corrélation - # réussie avec un A réinitialise ce TTL. - # Augmenté à 120s pour supporter les sessions HTTP Keep-Alive longues. - network_ttl_s: 120 - - # Filtrage des IPs source à exclure (optionnel) - exclude_source_ips: - - 10.0.0.1 # IP unique - - 172.16.0.0/12 # Plage CIDR - # Les événements depuis ces IPs sont silencieusement ignorés - - # Serveur de métriques HTTP (optionnel, pour débogage et monitoring) - metrics: - enabled: false - addr: ":8080" # Adresse d'écoute du serveur HTTP - # Endpoints: - # GET /metrics - Retourne les métriques de corrélation en JSON - # GET /health - Health check - -inputs: - description: > - Deux flux de logs JSON via sockets Unix datagram (SOCK_DGRAM). Chaque datagramme - contient un JSON complet. Le champ source_type ("A" ou "B") doit être spécifié - pour chaque socket. À défaut, la source est déduite automatiquement (présence de - headers = source A, sinon source B). - unix_sockets: - - name: http - id: A - description: > - Source A, logs HTTP applicatifs (Apache, reverse proxy, etc.). Schéma JSON - variable, champ timestamp (int64, nanosecondes) obligatoire, headers dynamiques (header_*). - path: /var/run/logcorrelator/http.socket - source_type: A - permissions: "0666" - protocol: unix - socket_type: dgram - mode: datagram - format: json - framing: message - max_datagram_bytes: 65535 - retry_on_error: true - - - name: network - id: B - description: > - Source B, logs réseau (métadonnées IP/TCP, JA3/JA4, etc.). Seuls src_ip - et src_port sont requis pour la corrélation. Le champ timestamp est optionnel ; - s'il est absent, l'heure de réception est utilisée. - path: /var/run/logcorrelator/network.socket - source_type: B - permissions: "0666" - protocol: unix - socket_type: dgram - mode: datagram - format: json - framing: message - max_datagram_bytes: 65535 - retry_on_error: true - -outputs: - description: > - Les logs corrélés sont envoyés vers un ou plusieurs sinks (MultiSink). - sinks: - file: - enabled: true - description: > - Sink fichier local. Un JSON par ligne. Rotation gérée par logrotate, - réouverture du fichier sur SIGHUP. Le champ `enabled: false` coupe - completement l'ecriture du fichier (le sink n'est pas cree). - path: /var/log/logcorrelator/correlated.log - format: json_lines - rotate_managed_by: external_logrotate - clickhouse: - enabled: false - description: > - Sink principal pour l'archivage et l'analyse quasi temps réel. Inserts - batch asynchrones, drop en cas de saturation. Le service insère uniquement - dans une table RAW (raw_json String, ingest_time DateTime DEFAULT now()). - La table parsée et la vue matérialisée sont gérées en externe (DDL séparés). - Toutes les erreurs de connexion, de flush et de retry sont loggées : - INFO à la connexion, ERROR sur échec de flush, WARN sur drop/retry, DEBUG sur envoi réussi. - dsn: clickhouse://user:pass@host:9000/db - table: correlated_logs_http_network - batch_size: 500 - flush_interval_ms: 200 - max_buffer_size: 5000 - drop_on_overflow: true - async_insert: true - timeout_ms: 1000 - stdout: - enabled: false - description: > - Sink no-op pour les données. Aucune donnée corrélée ou orpheline n'est - jamais écrite sur stdout. Ce sink existe uniquement pour satisfaire - l'interface CorrelatedLogSink. Les logs opérationnels du service - (démarrage, erreurs, métriques de débogage) sont toujours sur stderr - via observability.Logger, indépendamment de ce sink. - -correlation: - description: > - Corrélation stricte basée sur src_ip + src_port et une fenêtre temporelle - configurable. Aucun autre champ n'est utilisé pour la décision de corrélation. - key: - - src_ip - - src_port - time_window: - value: 10 - unit: s - description: > - Fenêtre de temps appliquée aux timestamps de A et B. Si B n'arrive pas dans - ce délai, A est émis comme orphelin. Augmentée à 10s pour le Keep-Alive. - retention_limits: - max_http_items: 10000 - max_network_items: 20000 - description: > - Limites des caches. Si max_http_items est atteint, le plus ancien A est - évincé et émis orphelin. Si max_network_items est atteint, le plus ancien B - est supprimé silencieusement. - ttl_management: - network_ttl_s: 120 - description: > - TTL des logs réseau. Chaque fois qu'un B est corrélé à un A (Keep-Alive), - son TTL est remis à cette valeur. Augmenté à 120s pour les sessions longues. - timestamp_source: - apache: timestamp (champ int64, nanosecondes) - network: timestamp (champ int64, nanosecondes) si présent, sinon time (RFC3339), - sinon reception_time (time.Now()) - orphan_policy: - apache_always_emit: true - network_emit: false - matching: - mode: one_to_many - description: > - Stratégie 1‑à‑N : un log réseau peut être utilisé pour plusieurs logs HTTP - successifs tant qu'il n'a pas expiré ni été évincé. - ip_filtering: - directive: exclude_source_ips - description: > - Liste d'IPs source (exactes ou plages CIDR) à ignorer silencieusement. - Événements non corrélés, non émis en orphelin. Métrique : failed_ip_excluded. - dest_port_filtering: - directive: include_dest_ports - description: > - Liste blanche de ports de destination. Si non vide, seuls les événements - dont le dst_port est dans la liste participent à la corrélation. Les autres - sont silencieusement ignorés (non corrélés, non émis en orphelin). - Liste vide = tous les ports autorisés (comportement par défaut). - Métrique : failed_dest_port_filtered. - example: - include_dest_ports: [80, 443, 8080, 8443] - -schema: - description: > - Schémas variables pour A et B. Quelques champs seulement sont obligatoires - pour la corrélation, les autres sont acceptés sans modification de code. - source_A: - description: > - Logs HTTP applicatifs au format JSON. - required_fields: - - name: src_ip - type: string - - name: src_port - type: int - - name: timestamp - type: int64 - unit: ns - optional_fields: - - name: dst_ip - type: string - - name: dst_port - type: int - - name: method - type: string - - name: path - type: string - - name: host - type: string - - name: http_version - type: string - dynamic_fields: - - pattern: header_* - target_map: headers - - pattern: "*" - target_map: extra - source_B: - description: Logs réseau JSON (IP/TCP, JA3/JA4...). - required_fields: - - name: src_ip - type: string - - name: src_port - type: int - optional_fields: - - name: dst_ip - type: string - - name: dst_port - type: int - - name: timestamp - type: int64 - unit: ns - - name: time - type: string - format: RFC3339 ou RFC3339Nano - dynamic_fields: - - pattern: "*" - target_map: extra - - normalized_event: - description: > - Représentation interne unifiée des événements A/B. - fields: - - name: source - type: enum("A","B") - - name: timestamp - type: time.Time - - name: src_ip - type: string - - name: src_port - type: int - - name: dst_ip - type: string - optional: true - - name: dst_port - type: int - optional: true - - name: headers - type: map[string]string - optional: true - - name: extra - type: map[string]any - - correlated_log: - description: > - Structure du log corrélé émis vers les sinks. - fields: - - name: timestamp - type: time.Time - - name: src_ip - type: string - - name: src_port - type: int - - name: dst_ip - type: string - optional: true - - name: dst_port - type: int - optional: true - - name: correlated - type: bool - - name: orphan_side - type: string - - name: "*" - type: map[string]any - -clickhouse_schema: - strategy: external_ddls - database: ja4_processing - description: > - La table ClickHouse est gérée en dehors du service. Le service insère dans une - table RAW avec une seule colonne raw_json contenant le log corrélé complet - sérialisé en JSON. La colonne ingest_time utilise DEFAULT now(). - Toute extraction de champs (table parsée, vue matérialisée) est gérée en externe - via des DDL séparés, non implémentés dans le service. - tables: - - name: http_logs_raw - description: > - Table d'ingestion brute. Une seule colonne raw_json contient le log corrélé - complet sérialisé en JSON. La colonne ingest_time est auto-générée avec - DEFAULT now(). Partitionnée par jour pour optimiser le TTL. - engine: MergeTree - partition_by: toDate(ingest_time) - order_by: ingest_time - columns: - - name: raw_json - type: String - - name: ingest_time - type: DateTime - default: now() - insert_format: | - INSERT INTO ja4_processing.http_logs_raw (raw_json) VALUES - ('{...log corrélé sérialisé en JSON...}') - notes: > - Le service utilise l'API native clickhouse-go/v2 (PrepareBatch + Append + Send). - La colonne ingest_time n'est PAS explicitement insérée (DEFAULT now() est utilisé). - - - name: http_logs - description: > - Table parsée (optionnelle, gérée en externe). Le service n'implémente PAS - l'extraction des champs suivants. Si cette table est utilisée, elle doit être - alimentée par une vue matérialisée ou un traitement ETL externe. - engine: MergeTree - partition_by: log_date - order_by: (time, src_ip, dst_ip, ja4) - columns: - - name: time - type: DateTime - - name: log_date - type: Date - default: toDate(time) - - name: src_ip - type: IPv4 - - name: src_port - type: UInt16 - - name: dst_ip - type: IPv4 - - name: dst_port - type: UInt16 - - name: method - type: LowCardinality(String) - - name: scheme - type: LowCardinality(String) - - name: host - type: LowCardinality(String) - - name: path - type: String - - name: query - type: String - - name: http_version - type: LowCardinality(String) - - name: orphan_side - type: LowCardinality(String) - - name: correlated - type: UInt8 - - name: keepalives - type: UInt16 - status: non_implémenté - - name: a_timestamp - type: UInt64 - status: non_implémenté - - name: b_timestamp - type: UInt64 - status: non_implémenté - - name: conn_id - type: String - status: non_implémenté - - name: ip_meta_df - type: UInt8 - status: non_implémenté - - name: ip_meta_id - type: UInt32 - status: non_implémenté - - name: ip_meta_total_length - type: UInt32 - status: non_implémenté - - name: ip_meta_ttl - type: UInt8 - status: non_implémenté - - name: tcp_meta_options - type: LowCardinality(String) - status: non_implémenté - - name: tcp_meta_window_size - type: UInt32 - status: non_implémenté - - name: syn_to_clienthello_ms - type: Int32 - status: non_implémenté - - name: tls_version - type: LowCardinality(String) - status: non_implémenté - - name: tls_sni - type: LowCardinality(String) - status: non_implémenté - - name: ja3 - type: String - status: non_implémenté - - name: ja3_hash - type: String - status: non_implémenté - - name: ja4 - type: String - status: non_implémenté - - name: header_user_agent - type: String - status: non_implémenté - - name: header_accept - type: String - status: non_implémenté - - name: header_accept_encoding - type: String - status: non_implémenté - - name: header_accept_language - type: String - status: non_implémenté - - name: header_x_request_id - type: String - status: non_implémenté - - name: header_x_trace_id - type: String - status: non_implémenté - - name: header_x_forwarded_for - type: String - status: non_implémenté - - name: header_sec_ch_ua - type: String - status: non_implémenté - - name: header_sec_ch_ua_mobile - type: String - status: non_implémenté - - name: header_sec_ch_ua_platform - type: String - status: non_implémenté - - name: header_sec_fetch_dest - type: String - status: non_implémenté - - name: header_sec_fetch_mode - type: String - status: non_implémenté - - name: header_sec_fetch_site - type: String - status: non_implémenté - notes: > - Cette table et la vue matérialisée associée sont gérées en externe (DDL séparés). - Le service se contente d'insérer le JSON brut dans http_logs_raw. - Les champs marqués "non_implémenté" ne sont PAS extraits par le service. - - users: - description: > - La gestion des utilisateurs ClickHouse est externe au service. Le DSN est - configuré dans le fichier de configuration YAML. - notes: > - Cette section est fournie à titre indicatif pour l'administration ClickHouse. - - migration: - description: > - Aucune migration n'est implémentée dans le service. La gestion des schémas - (tables, vues matérialisées) est entièrement externe (DDL séparés). - -architecture: - description: > - Architecture hexagonale : domaine de corrélation indépendant, ports abstraits - pour les sources/sinks, adaptateurs pour sockets Unix, fichier, ClickHouse et - stdout, couche application d'orchestration, et modules infra (config, observabilité). - modules: - - name: cmd/logcorrelator - type: entrypoint - responsibilities: - - Chargement de la configuration YAML. - - Initialisation des adaptateurs d'entrée/sortie. - - Création du CorrelationService. - - Démarrage de l'orchestrateur. - - Gestion des signaux (SIGINT, SIGTERM, SIGHUP). - - Versioning via -ldflags (main.Version). - - name: internal/domain - type: domain - responsibilities: - - Modèles NormalizedEvent et CorrelatedLog. - - CorrelationService (fenêtre, TTL, buffers bornés, one-to-many/Keep-Alive, orphelins). - - Filtrage par IP source (exclude_source_ips, CIDR). - - Filtrage par port destination (include_dest_ports, liste blanche). - - Custom JSON marshaling pour CorrelatedLog (structure plate). - - name: internal/ports - type: ports - responsibilities: - - Interfaces EventSource, CorrelatedLogSink, CorrelationProcessor. - - name: internal/app - type: application - responsibilities: - - Orchestrator : EventSource → CorrelationService → MultiSink. - - Gestion du contexte de shutdown et drain des événements. - - name: internal/adapters/inbound/unixsocket - type: adapter_inbound - responsibilities: - - Lecture Unix datagram (SOCK_DGRAM) et parsing JSON → NormalizedEvent. - - Détection automatique de la source (A/B) via source_type ou headers. - - Gestion des permissions de socket (défaut 0666). - - Cleanup du fichier socket à l'arrêt. - - name: internal/adapters/outbound/file - type: adapter_outbound - responsibilities: - - Écriture JSON lines. - - Réouverture du fichier sur SIGHUP (log rotation). - - Validation des chemins (répertoire autorisé). - - name: internal/adapters/outbound/clickhouse - type: adapter_outbound - responsibilities: - - Bufferisation + inserts batch asynchrones. - - Gestion du drop_on_overflow. - - Retry avec backoff exponentiel (MaxRetries=3). - - API native clickhouse-go/v2 (PrepareBatch + Append + Send). - - Logging complet via observability.Logger (SetLogger) : INFO à la connexion, - DEBUG sur envoi réussi (rows/table), WARN sur drop buffer et retries, - ERROR sur échec de flush (périodique, batch, fermeture). - - name: internal/adapters/outbound/stdout - type: adapter_outbound - responsibilities: - - Sink no-op pour les données corrélées. - - Write/Flush/Close ne font rien : les données ne passent jamais par stdout. - - Les logs opérationnels sont sur stderr via observability.Logger (indépendant de ce sink). - - name: internal/adapters/outbound/multi - type: adapter_outbound - responsibilities: - - Fan-out vers plusieurs sinks. - - Implémentation de Reopen() pour la rotation des logs. - - name: internal/config - type: infrastructure - responsibilities: - - Chargement/validation de la configuration YAML. - - Valeurs par défaut et fallback pour champs dépréciés. - - name: internal/observability - type: infrastructure - responsibilities: - - Logger structuré avec niveaux (DEBUG, INFO, WARN, ERROR). - - CorrelationMetrics : suivi des statistiques de corrélation. - - MetricsServer : serveur HTTP pour exposition des métriques (/metrics, /health). - - Traçage des événements exclus (exclude_source_ips). - - Logs pour : événements reçus, corrélations, orphelins, buffer plein. - -testing: - unit: - description: > - Tests unitaires table‑driven, couverture cible ≥ 80 %. La couverture actuelle - est d'environ 74-80% selon les versions. Les tests se concentrent sur la logique - de corrélation, les caches, les sinks et le parsing des datagrammes. - coverage_minimum: 0.8 - coverage_actual: ~0.74-0.80 - focus: - - CorrelationService (fenêtre, TTL, évictions, one-to-many/Keep-Alive) - - Parsing A/B → NormalizedEvent (datagrammes JSON) - - ClickHouseSink (batching, retry, overflow, logging erreurs/succès) - - FileSink (réouverture sur SIGHUP) - - MultiSink (fan-out) - - StdoutSink (no-op data, test stdout reste vide) - - Config (validation, valeurs par défaut, exclude_source_ips) - - UnixSocketSource (lecture, permissions, cleanup) - - CorrelationMetrics (suivi des statistiques) - - MetricsServer (endpoints /metrics et /health) - integration: - description: > - Tests d'intégration limités. Le flux complet A+B → corrélation → sinks est - testé via des tests unitaires avec mocks. ClickHouse est mocké (pas de tests - avec vrai ClickHouse). Scénarios Keep-Alive testés dans correlation_service_test.go. - Scripts de test fournis : scripts/test-correlation.sh et scripts/test-correlation-advanced.py. - -docker: - description: > - Build, tests et packaging RPM sont exécutés intégralement dans des conteneurs - via un multi‑stage build. Deux Dockerfiles : Dockerfile (build + runtime + dev) - et Dockerfile.package (RPM multi-distros : el8, el9, el10). - build_pipeline: - multi_stage: true - stages: - - name: builder - base: golang:1.21 - description: > - go test -race -coverprofile=coverage.txt ./... avec vérification de couverture - (échec si < 80 %). Compilation d'un binaire statique (CGO_ENABLED=0, - GOOS=linux, GOARCH=amd64). - - name: runtime - base: scratch - description: > - Image minimale contenant uniquement le binaire et la config exemple. - - name: rpm_builder_el8 - base: rockylinux:8 - description: > - Installation de fpm (via Ruby), construction RPM pour Enterprise Linux 8. - - name: rpm_builder_el9 - base: rockylinux:9 - description: > - Installation de fpm (via Ruby), construction RPM pour Enterprise Linux 9. - - name: rpm_builder_el10 - base: almalinux:10 - description: > - Installation de fpm (via Ruby), construction RPM pour Enterprise Linux 10. - - name: output_export - base: alpine:latest - description: > - Export des paquets RPM produits pour les 3 distributions (el8, el9, el10). - files: - - path: Dockerfile - description: Build principal (builder, runtime, dev) et packaging RPM mono-distro. - - path: Dockerfile.package - description: Packaging RPM multi-distros (el8, el9, el10) avec scripts post/preun/postun. - -observability: - description: > - Le service inclut des fonctionnalités complètes de débogage et de monitoring - pour diagnostiquer les problèmes de corrélation et surveiller les performances. - logging: - levels: - - DEBUG: Tous les événements reçus, tentatives de corrélation, raisons des échecs - - INFO: Événements corrélés, démarrage/arrêt du service - - WARN: Orphelins émis, buffer plein, TTL expiré - - ERROR: Erreurs de parsing, échecs de sink, erreurs critiques - debug_logs: - - "event received: source=A src_ip=192.168.1.1 src_port=8080 timestamp=..." - - "processing A event: key=192.168.1.1:8080 timestamp=..." - - "correlation found: A(src_ip=... src_port=... ts=...) + B(src_ip=... src_port=... ts=...)" - - "A event has no matching B key in buffer: key=..." - - "A event has same key as B but outside time window: key=... time_diff=5s window=10s" - - "event excluded by IP filter: source=A src_ip=10.0.0.1 src_port=8080" - - "event excluded by dest port filter: source=A dst_port=22" - - "TTL reset for B event (Keep-Alive): key=... new_ttl=120s" - - "[clickhouse] DEBUG batch sent: rows=42 table=correlated_logs_http_network" - info_logs: - - "[clickhouse] INFO connected to ClickHouse: table=... batch_size=500 flush_interval_ms=200" - warn_logs: - - "[clickhouse] WARN buffer full, dropping log: table=... buffer_size=5000" - - "[clickhouse] WARN retrying batch insert: attempt=2/3 delay=100ms rows=42 err=connection refused" - error_logs: - - "[clickhouse] ERROR periodic flush failed: ..." - - "[clickhouse] ERROR batch flush failed: ..." - - "[clickhouse] ERROR final flush on close failed: ..." - metrics_server: - enabled: true - endpoints: - - path: /metrics - method: GET - description: Retourne les métriques de corrélation au format JSON - response_example: | - { - "events_received_a": 1542, - "events_received_b": 1498, - "correlations_success": 1450, - "correlations_failed": 92, - "failed_no_match_key": 45, - "failed_time_window": 23, - "failed_buffer_eviction": 5, - "failed_ttl_expired": 12, - "failed_ip_excluded": 7, - "failed_dest_port_filtered": 3, - "buffer_a_size": 23, - "buffer_b_size": 18, - "orphans_emitted_a": 92, - "keepalive_resets": 892 - } - - path: /health - method: GET - description: Health check - response_example: | - {"status":"healthy"} - metrics_tracked: - events_received: - - events_received_a: Nombre d'événements HTTP (source A) reçus - - events_received_b: Nombre d'événements réseau (source B) reçus - correlations: - - correlations_success: Corrélations réussies - - correlations_failed: Échecs de corrélation - failure_reasons: - - failed_no_match_key: Clé src_ip:src_port non trouvée dans le buffer - - failed_time_window: Événements hors fenêtre temporelle - - failed_buffer_eviction: Buffer plein, événement évincé - - failed_ttl_expired: TTL du événement B expiré - - failed_ip_excluded: Événement exclu par filtre IP (exclude_source_ips) - - failed_dest_port_filtered: Événement exclu par filtre port destination (include_dest_ports) - buffers: - - buffer_a_size: Taille actuelle du buffer HTTP - - buffer_b_size: Taille actuelle du buffer réseau - orphans: - - orphans_emitted_a: Orphelins A émis (sans correspondance B) - - orphans_emitted_b: Orphelins B émis (toujours 0, policy: network_emit=false) - - orphans_pending_a: Orphelins A en attente (délai avant émission) - - pending_orphan_match: B a corrélé avec un orphelin A en attente - keepalive: - - keepalive_resets: Resets TTL pour mode Keep-Alive (one-to-many) - troubleshooting: - description: > - Guide de diagnostic basé sur les métriques et logs - common_issues: - - symptom: failed_no_match_key élevé - cause: Les logs A et B n'ont pas le même src_ip + src_port - solution: Vérifier que les deux sources utilisent la même combinaison IP/port - - symptom: failed_time_window élevé - cause: Timestamps trop éloignés (> time_window.value) - solution: Augmenter correlation.time_window.value ou synchroniser les horloges (NTP) - - symptom: failed_ttl_expired élevé - cause: Les événements B expirent avant corrélation - solution: Augmenter correlation.ttl.network_ttl_s - - symptom: failed_buffer_eviction élevé - cause: Buffers trop petits pour le volume de logs - solution: Augmenter correlation.buffers.max_http_items et max_network_items - - symptom: failed_ip_excluded élevé - cause: Traffic depuis des IPs configurées dans exclude_source_ips - solution: Vérifier la configuration, c'est normal si attendu - - symptom: failed_dest_port_filtered élevé - cause: Traffic sur des ports non listés dans include_dest_ports - solution: Vérifier la configuration include_dest_ports, ou vider la liste pour tout accepter - - symptom: orphans_emitted_a élevé - cause: Beaucoup de logs A sans correspondance B - solution: Vérifier que la source B envoie bien les événements attendus - test_scripts: - - name: scripts/test-correlation.sh - description: Script Bash pour tester la corrélation avec des événements synthétiques - features: - - Envoi de paires A+B avec mêmes src_ip:src_port - - Vérification des métriques avant/après - - Options: -c (count), -d (delay), -v (verbose), -m (metrics-url) - - name: scripts/test-correlation-advanced.py - description: Script Python avancé avec multiples scénarios de test - features: - - Basic test: corrélations simples - - Time window test: vérifie l'expiration de la fenêtre temporelle - - Different IP test: vérifie non-corrélation avec IPs différentes - - Keep-Alive test: vérifie le mode one-to-many - - Métriques en temps réel - diff --git a/old/services/correlator/cmd/logcorrelator/main.go b/old/services/correlator/cmd/logcorrelator/main.go deleted file mode 100644 index ed507c7..0000000 --- a/old/services/correlator/cmd/logcorrelator/main.go +++ /dev/null @@ -1,204 +0,0 @@ -// Package main initialise et démarre le service logcorrelator. -package main - -import ( - "context" - "flag" - "fmt" - "os" - "os/signal" - "syscall" - "time" - - "github.com/antitbone/ja4/correlator/internal/adapters/inbound/unixsocket" - "github.com/antitbone/ja4/correlator/internal/adapters/outbound/clickhouse" - "github.com/antitbone/ja4/correlator/internal/adapters/outbound/file" - "github.com/antitbone/ja4/correlator/internal/adapters/outbound/multi" - "github.com/antitbone/ja4/correlator/internal/adapters/outbound/stdout" - "github.com/antitbone/ja4/correlator/internal/app" - "github.com/antitbone/ja4/correlator/internal/config" - "github.com/antitbone/ja4/correlator/internal/domain" - "github.com/antitbone/ja4/correlator/internal/observability" - "github.com/antitbone/ja4/correlator/internal/ports" -) - -var Version = "dev" - -// main configure les sources, les puits et le service de corrélation, puis démarre l'orchestrateur. -func main() { - configPath := flag.String("config", "config.yml", "path to configuration file") - version := flag.Bool("version", false, "print version and exit") - flag.Parse() - - if *version { - fmt.Println(Version) - os.Exit(0) - } - - // Load configuration - cfg, err := config.Load(*configPath) - if err != nil { - fmt.Fprintf(os.Stderr, "Error loading configuration: %v\n", err) - os.Exit(1) - } - - // Initialize logger with configured level - logger := observability.NewLoggerWithLevel("logcorrelator", cfg.Log.GetLevel()) - - logger.Info(fmt.Sprintf("Starting logcorrelator version %s (log_level=%s)", Version, cfg.Log.GetLevel())) - - // Create sources - sources := make([]ports.EventSource, 0, len(cfg.Inputs.UnixSockets)) - for _, inputCfg := range cfg.Inputs.UnixSockets { - source := unixsocket.NewUnixSocketSource(unixsocket.Config{ - Name: inputCfg.Name, - Path: inputCfg.Path, - SourceType: inputCfg.SourceType, - SocketPermissions: inputCfg.GetSocketPermissions(), - }) - // Set logger for debug logging - source.SetLogger(logger) - sources = append(sources, source) - logger.Info(fmt.Sprintf("Configured input source: name=%s, path=%s, permissions=%o", inputCfg.Name, inputCfg.Path, inputCfg.GetSocketPermissions())) - } - - // Create sinks - sinks := make([]ports.CorrelatedLogSink, 0) - - if cfg.Outputs.File.Enabled && cfg.Outputs.File.Path != "" { - fileSink, err := file.NewFileSink(file.Config{ - Path: cfg.Outputs.File.Path, - }) - if err != nil { - logger.Error("Failed to create file sink", err) - os.Exit(1) - } - sinks = append(sinks, fileSink) - logger.Info(fmt.Sprintf("Configured file sink: path=%s", cfg.Outputs.File.Path)) - } - - if cfg.Outputs.ClickHouse.Enabled { - clickHouseSink, err := clickhouse.NewClickHouseSink(clickhouse.Config{ - DSN: cfg.Outputs.ClickHouse.DSN, - Table: cfg.Outputs.ClickHouse.Table, - BatchSize: cfg.Outputs.ClickHouse.BatchSize, - FlushIntervalMs: cfg.Outputs.ClickHouse.FlushIntervalMs, - MaxBufferSize: cfg.Outputs.ClickHouse.MaxBufferSize, - DropOnOverflow: cfg.Outputs.ClickHouse.DropOnOverflow, - AsyncInsert: cfg.Outputs.ClickHouse.AsyncInsert, - TimeoutMs: cfg.Outputs.ClickHouse.TimeoutMs, - }) - if err != nil { - logger.Error("Failed to create ClickHouse sink", err) - os.Exit(1) - } - clickHouseSink.SetLogger(logger) - sinks = append(sinks, clickHouseSink) - logger.Info(fmt.Sprintf("Configured ClickHouse sink: table=%s", cfg.Outputs.ClickHouse.Table)) - } - - if cfg.Outputs.Stdout.Enabled { - stdoutSink := stdout.NewStdoutSink(stdout.Config{Enabled: true}) - sinks = append(sinks, stdoutSink) - logger.Info("Configured stdout sink (operational logs on stderr)") - } - - // Create multi-sink wrapper - multiSink := multi.NewMultiSink(sinks...) - - // Create correlation service - correlationSvc := domain.NewCorrelationService(domain.CorrelationConfig{ - TimeWindow: cfg.Correlation.GetTimeWindow(), - ApacheAlwaysEmit: cfg.Correlation.GetApacheAlwaysEmit(), - ApacheEmitDelayMs: cfg.Correlation.GetApacheEmitDelayMs(), - NetworkEmit: false, - MaxHTTPBufferSize: cfg.Correlation.GetMaxHTTPBufferSize(), - MaxNetworkBufferSize: cfg.Correlation.GetMaxNetworkBufferSize(), - NetworkTTLS: cfg.Correlation.GetNetworkTTLS(), - MatchingMode: cfg.Correlation.GetMatchingMode(), - ExcludeSourceIPs: cfg.Correlation.GetExcludeSourceIPs(), - IncludeDestPorts: cfg.Correlation.GetIncludeDestPorts(), - }, &domain.RealTimeProvider{}) - - // Set logger for correlation service - correlationSvc.SetLogger(logger.WithFields(map[string]any{"component": "correlation"})) - - logger.Info(fmt.Sprintf("Correlation service initialized: time_window=%s, emit_orphans=%v, emit_delay_ms=%d", - cfg.Correlation.GetTimeWindow().String(), - cfg.Correlation.GetApacheAlwaysEmit(), - cfg.Correlation.GetApacheEmitDelayMs())) - - // Start metrics server if enabled - var metricsServer *observability.MetricsServer - if cfg.Metrics.Enabled { - addr := cfg.Metrics.Addr - if addr == "" { - addr = ":8080" // Default address - } - var err error - metricsServer, err = observability.NewMetricsServer(addr, correlationSvc.GetMetricsSnapshot) - if err != nil { - logger.Error("Failed to create metrics server", err) - os.Exit(1) - } - if err := metricsServer.Start(); err != nil { - logger.Error("Failed to start metrics server", err) - os.Exit(1) - } - logger.Info(fmt.Sprintf("Metrics server started: addr=%s", metricsServer.Addr())) - logger.Info("Metrics endpoints: /metrics (JSON), /health") - } - - // Create orchestrator - orchestrator := app.NewOrchestrator(app.OrchestratorConfig{ - Sources: sources, - Sink: multiSink, - }, correlationSvc) - - // Start the application - if err := orchestrator.Start(); err != nil { - logger.Error("Failed to start orchestrator", err) - os.Exit(1) - } - - logger.Info("logcorrelator started successfully") - - // Wait for shutdown signal - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) - - for { - sig := <-sigChan - - if sig == syscall.SIGHUP { - // Reopen file sinks for log rotation - logger.Info("SIGHUP received, reopening file sinks...") - if err := multiSink.Reopen(); err != nil { - logger.Error("Error reopening file sinks", err) - } else { - logger.Info("File sinks reopened successfully") - } - continue - } - - // Shutdown signal received - logger.Info(fmt.Sprintf("Shutdown signal received: %v", sig)) - break - } - - // Graceful shutdown - if err := orchestrator.Stop(); err != nil { - logger.Error("Error during shutdown", err) - } - - // Stop metrics server - if metricsServer != nil { - shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - if err := metricsServer.Stop(shutdownCtx); err != nil { - logger.Error("Error stopping metrics server", err) - } - } - - logger.Info("logcorrelator stopped") -} diff --git a/old/services/correlator/config.example.yml b/old/services/correlator/config.example.yml deleted file mode 100644 index 6457555..0000000 --- a/old/services/correlator/config.example.yml +++ /dev/null @@ -1,92 +0,0 @@ -# logcorrelator configuration file -# Format: YAML - -# Logging configuration -log: - level: INFO # DEBUG, INFO, WARN, ERROR - -inputs: - unix_sockets: - - name: http - source_type: A - path: /var/run/logcorrelator/http.socket - format: json - socket_permissions: "0666" # world read/write - - name: network - source_type: B - path: /var/run/logcorrelator/network.socket - format: json - socket_permissions: "0666" - -outputs: - file: - enabled: true - path: /var/log/logcorrelator/correlated.log - - clickhouse: - enabled: false - dsn: clickhouse://user:pass@localhost:9000/ja4_logs - table: http_logs_raw - batch_size: 500 - flush_interval_ms: 200 - max_buffer_size: 5000 - drop_on_overflow: true - async_insert: true - timeout_ms: 1000 - - stdout: - enabled: false - -correlation: - # Time window for correlation (A and B must be within this window) - # Increased to 10s to support HTTP Keep-Alive scenarios - time_window: - value: 10 - unit: s - - # Orphan policy: what to do when no match is found - orphan_policy: - apache_always_emit: true # Always emit A events, even without B match - apache_emit_delay_ms: 500 # Wait 500ms before emitting as orphan (allows B to arrive) - network_emit: false # Never emit B events alone - - # Matching mode: one_to_one or one_to_many (Keep-Alive) - matching: - mode: one_to_many - - # Buffer limits (max events in memory) - buffers: - max_http_items: 10000 - max_network_items: 20000 - - # TTL for network events (source B) - # Increased to 120s to support long-lived HTTP Keep-Alive sessions - ttl: - network_ttl_s: 120 - - # Exclude specific source IPs or CIDR ranges from correlation - # Events from these IPs will be silently dropped (not correlated, not emitted) - # Useful for excluding health checks, internal traffic, or known bad actors - exclude_source_ips: - - 10.0.0.1 # Single IP - - 192.168.1.100 # Another single IP - - 172.16.0.0/12 # CIDR range (private network) - - 10.10.10.0/24 # Another CIDR range - - # Restrict correlation to specific destination ports (optional) - # If non-empty, only events whose dst_port matches one of these values will be correlated - # Events on other ports are silently ignored (not correlated, not emitted as orphans) - # Useful to focus on HTTP/HTTPS traffic only and ignore unrelated connections - # include_dest_ports: - # - 80 # HTTP - # - 443 # HTTPS - # - 8080 # HTTP alt - # - 8443 # HTTPS alt - -# Metrics server configuration (optional, for debugging/monitoring) -metrics: - enabled: false - addr: ":8080" # Address to listen on (e.g., ":8080", "localhost:8080") - # Endpoints: - # GET /metrics - Returns correlation metrics as JSON - # GET /health - Health check endpoint diff --git a/old/services/correlator/docs/detection.md b/old/services/correlator/docs/detection.md deleted file mode 100644 index 971dc59..0000000 --- a/old/services/correlator/docs/detection.md +++ /dev/null @@ -1,224 +0,0 @@ -# Architecture de détection — logcorrelator - -## Vue d'ensemble - -Le système de détection est composé de **trois couches** qui s'enchaînent en pipeline : - -``` -Trafic HTTP/TLS capturé - │ - ▼ -┌───────────────────┐ -│ ClickHouse │ Stockage, agrégation, vues heuristiques -│ (SQL pipeline) │ -└────────┬──────────┘ - │ - ▼ -┌───────────────────┐ -│ bot_detector.py │ Modèle IA (Isolation Forest, cycle 5 min) -│ (Python / ML) │ -└────────┬──────────┘ - │ - ▼ -┌───────────────────┐ -│ ml_detected_ │ Table de résultats (ReplacingMergeTree) -│ anomalies │ -└───────────────────┘ -``` - ---- - -## 1. Ingestion des logs (`http_logs_raw` → `http_logs`) - -Les logs bruts arrivent en JSON dans la table `http_logs_raw`. Une **vue matérialisée** (`mv_http_logs`) les parse en temps réel et alimente la table `http_logs`, qui contient les champs structurés suivants : - -| Catégorie | Champs clés | -|---|---| -| Réseau | `src_ip`, `src_port`, `dst_ip`, `dst_port` | -| Enrichissement | `src_asn`, `src_country_code`, `src_as_name` (via dictionnaire IPLocate) | -| HTTP | `method`, `host`, `path`, `query`, `http_version` | -| Corrélation | `correlated`, `orphan_side`, `conn_id`, `keepalives` | -| Métadonnées IP | `ip_meta_ttl`, `ip_meta_id`, `ip_meta_df`, `ip_meta_total_length` | -| Métadonnées TCP | `tcp_meta_window_size`, `tcp_meta_mss`, `tcp_meta_window_scale`, `tcp_meta_options` | -| TLS / Fingerprint | `tls_version`, `tls_sni`, `tls_alpn`, `ja3`, `ja3_hash`, `ja4` | -| En-têtes HTTP | `header_user_agent`, `header_sec_ch_ua*`, `header_sec_fetch_*`, … | - -L'enrichissement IP est réalisé via le dictionnaire `dict_iplocate_asn` (fichier CSV chargé en mémoire, rechargé toutes les 1-2 heures). - ---- - -## 2. Agrégation comportementale (fenêtre horaire) - -Deux tables d'agrégation `AggregatingMergeTree` sont alimentées en continu par des vues matérialisées. - -### 2.1 `agg_host_ip_ja4_1h` — Comportement réseau & applicatif - -Agrège par triplet **(window_start, src_ip, ja4, host)** toutes les heures : - -| Métrique agrégée | Signification | -|---|---| -| `hits` | Nombre total de requêtes | -| `count_post` | Requêtes POST | -| `uniq_paths` | Chemins distincts visités | -| `uniq_query_params` | Paramètres de query distincts | -| `unique_src_ports` | Ports sources distincts | -| `unique_conn_id` | Connexions TCP distinctes | -| `max_keepalives` | Réutilisation maximale d'une connexion | -| `orphan_count` | Requêtes sans corrélation TCP complète | -| `ip_id_zero_count` | Paquets avec IP ID = 0 (spoofing potentiel) | -| `tcp_fp_raw` | Hash de l'empreinte TCP (window, MSS, scale, options) | -| `tcp_jitter_variance` | Variance du délai SYN→ClientHello (jitter TLS) | -| `total_ip_length_var` | Variance de la taille des paquets IP | -| `mss_1460_count` | Requêtes avec MSS = 1460 (signature Ethernet/desktop) | - -### 2.2 `agg_header_fingerprint_1h` — Empreinte des en-têtes HTTP - -Agrège par **(window_start, src_ip)** : - -| Métrique | Signification | -|---|---| -| `header_order_hash` | Hash de l'ordre des en-têtes (fingerprint JA4H) | -| `header_count` | Nombre d'en-têtes distincts | -| `has_accept_language` | Présence de `Accept-Language` | -| `has_cookie` | Présence de `Cookie` | -| `has_referer` | Présence de `Referer` | -| `modern_browser_score` | Score 0/50/100 selon présence UA et `Sec-CH-UA` | -| `ua_ch_mismatch` | Incohérence entre `User-Agent` et `Sec-CH-UA-Platform` | -| `sec_fetch_mode/dest` | Contexte de navigation déclaré | - ---- - -## 3. Exclusions (listes blanches) - -Avant toute analyse, deux tables permettent d'**exclure les robots légitimes** connus : - -- `bot_ip` (fichier `bot_ip.csv`) — IPs à ignorer (crawlers, monitoring…) -- `bot_ja4` (fichier `bot_ja4.csv`) — Fingerprints JA4 à ignorer -- `ref_bot_networks` — Réseaux CIDR IPv4/IPv6 catégorisés (légitimes ou malveillants) - -Ces exclusions sont appliquées dans la vue `view_ai_features_1h`. - ---- - -## 4. Vue IA : `view_ai_features_1h` - -Cette vue consolidée **sur 24 heures glissantes** calcule les **28 features** passées au modèle ML. Elle joint les deux tables d'agrégation et dérive les métriques suivantes : - -| Feature | Calcul | Signal détecté | -|---|---|---| -| `hit_velocity` | `hits / durée_en_secondes` | Volume de requêtes anormalement élevé | -| `fuzzing_index` | `uniq_query_params / uniq_paths` | Exploration paramétrique (fuzzing) | -| `post_ratio` | `count_post / hits` | Soumission de formulaires en masse | -| `port_exhaustion_ratio` | `unique_src_ports / hits` | Rotation de ports (scan) | -| `orphan_ratio` | `orphan_count / hits` | Requêtes sans handshake complet | -| `ip_id_zero_ratio` | `ip_id_zero_count / hits` | Spoofing d'adresse IP | -| `multiplexing_efficiency` | `hits / unique_conn_id` | Réutilisation des connexions (H2/H3) | -| `true_window_size` | `tcp_win * 2^tcp_scale` | Taille réelle de la fenêtre TCP | -| `window_mss_ratio` | `tcp_win / tcp_mss` | Cohérence TCP stack | -| `tcp_jitter_variance` | Variance SYN→ClientHello | Irrégularité du timing TLS | -| `alpn_http_mismatch` | ALPN=h2 mais HTTP/1.1 | Négociation TLS mensongère | -| `is_alpn_missing` | ALPN absent ou `00` | Client non-standard | -| `sni_host_mismatch` | SNI ≠ Host header | Proxy transparent / bot | -| `mss_mobile_mismatch` | MSS=1460 + score navigateur élevé | Client mobile simulé depuis desktop | -| `is_fake_navigation` | `sec_fetch_mode=navigate` mais `sec_fetch_dest≠document` | Navigation simulée | -| `tcp_shared_count` | Nb d'IPs partageant la même empreinte TCP | Infrastructure partagée / botnet | -| `header_order_shared_count` | Nb d'IPs partageant le même ordre d'en-têtes | Outil automatisé commun | - ---- - -## 5. Modèle IA : Isolation Forest (`bot_detector.py`) - -### Cycle d'exécution - -Le service tourne en boucle avec un **cycle de 5 minutes** : - -``` -fetch_and_analyze() - │ - ├─ Requête SELECT * FROM view_ai_features_1h - │ - ├─ Nettoyage des données (fillna) - │ - ├─ Dual-Model routing : - │ ├─ [Complet] correlated=1 → 23 features (réseau + TLS + headers) - │ └─ [Applicatif] correlated=0 → 19 features (headers + comportement) - │ - └─ INSERT INTO ml_detected_anomalies -``` - -### Paramétrage du modèle - -| Paramètre | Valeur | Signification | -|---|---|---| -| `n_estimators` | 200 | Nombre d'arbres d'isolation | -| `contamination` | 0.2% | Proportion de bots attendue dans le trafic | -| `seuil de score` | < -0.05 | Score en dessous duquel une session est marquée anomalie | -| `volume minimum` | 500 sessions | En dessous, le modèle est ignoré (trop peu de données) | - -### Dual-Model routing - -Le trafic est **séparé en deux populations** selon le champ `correlated` : - -- **Modèle Complet** (`correlated=1`) : la corrélation TCP↔HTTP est disponible → les features réseau (TTL, jitter TLS, ALPN, SNI) sont fiables et ajoutées à l'analyse. -- **Modèle Applicatif** (`correlated=0`) : seule la couche HTTP est disponible → l'analyse se concentre sur le comportement applicatif (headers, paths, POST ratio…). - ---- - -## 6. Vues heuristiques statiques - -En parallèle du modèle IA, cinq vues SQL fournissent des **détections déterministes** sans ML, sur fenêtre 24h : - -| Vue | Règle de détection | -|---|---| -| `view_host_ip_ja4_rotation` | IP avec ≥ 5 fingerprints JA4 distincts et > 100 requêtes → rotation d'identité | -| `view_host_ja4_anomalies` | Fingerprint JA4 vu depuis ≥ 20 IPs sur ≥ 3 hôtes → outil de scan distribué | -| `view_form_bruteforce_detected` | ≥ 10 query params distincts et ≥ 20 hits → brute-force de formulaire | -| `view_alpn_mismatch_detected` | HTTP/1.1 avec ALPN h2 ou h3 et ≥ 10 hits → négociation TLS frauduleuse | -| `view_tcp_spoofing_detected` | TTL ≤ 64 avec User-Agent Windows ou iPhone → empreinte OS incohérente | - ---- - -## 7. Résultats : `ml_detected_anomalies` - -Les anomalies détectées sont stockées dans une table `ReplacingMergeTree(detected_at)` avec **TTL 30 jours**. La clé d'ordre `(src_ip, ja4, host)` garantit que chaque triplet ne conserve que la **détection la plus récente** (dédoublonnage automatique). - -Chaque enregistrement contient : -- Les scores et features ayant conduit à la détection -- Le champ `reason` : texte lisible avec score, vélocité, et indice de fuzzing -- Le champ `is_headless` : déduit de l'incohérence `sec_fetch_mode` - ---- - -## 8. Schéma de flux complet - -``` - ┌─────────────────────────────────────┐ - │ http_logs_raw (JSON) │ - └──────────────┬──────────────────────┘ - │ mv_http_logs (MV) - ▼ - ┌─────────────────────────────────────┐ - │ http_logs (parsée) │ - └────────┬──────────────┬─────────────┘ - │ │ - mv_agg_host_ip_ja4 │ │ mv_agg_header_fingerprint - ▼ ▼ - ┌──────────────────┐ ┌──────────────────────────┐ - │ agg_host_ip_ja4 │ │ agg_header_fingerprint │ - │ _1h │ │ _1h │ - └────────┬─────────┘ └──────────┬──────────────┘ - │ │ - └──────────┬─────────────┘ - │ view_ai_features_1h (JOIN + calculs) - ▼ - ┌─────────────────────────────────────┐ - │ bot_detector.py (Isolation Forest) │ - │ Cycle : 5 min | Fenêtre : 24h │ - └──────────────┬──────────────────────┘ - │ - ▼ - ┌─────────────────────────────────────┐ - │ ml_detected_anomalies │ - │ (ReplacingMergeTree, TTL 30j) │ - └─────────────────────────────────────┘ -``` diff --git a/old/services/correlator/go.mod b/old/services/correlator/go.mod deleted file mode 100644 index 0272f58..0000000 --- a/old/services/correlator/go.mod +++ /dev/null @@ -1,29 +0,0 @@ -module github.com/antitbone/ja4/correlator - -go 1.21 - -require ( - github.com/ClickHouse/clickhouse-go/v2 v2.23.0 - gopkg.in/yaml.v3 v3.0.1 -) - -require ( - github.com/ClickHouse/ch-go v0.61.5 // indirect - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/go-faster/city v1.0.1 // indirect - github.com/go-faster/errors v0.7.1 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect - github.com/paulmach/orb v0.11.1 // indirect - github.com/pierrec/lz4/v4 v4.1.21 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/segmentio/asm v1.2.0 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect - golang.org/x/sys v0.18.0 // indirect -) - -require github.com/antitbone/ja4/ja4common v0.1.0 - -replace github.com/antitbone/ja4/ja4common => ../../shared/go/ja4common diff --git a/old/services/correlator/go.sum b/old/services/correlator/go.sum deleted file mode 100644 index c03066c..0000000 --- a/old/services/correlator/go.sum +++ /dev/null @@ -1,110 +0,0 @@ -github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4= -github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg= -github.com/ClickHouse/clickhouse-go/v2 v2.23.0 h1:srmRrkS0BR8gEut87u8jpcZ7geOob6nGj9ifrb+aKmg= -github.com/ClickHouse/clickhouse-go/v2 v2.23.0/go.mod h1:tBhdF3f3RdP7sS59+oBAtTyhWpy0024ZxDMhgxra0QE= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= -github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= -github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= -github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= -github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= -github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= -github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= -github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= -github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/old/services/correlator/idees/champs.md b/old/services/correlator/idees/champs.md deleted file mode 100644 index e772fc7..0000000 --- a/old/services/correlator/idees/champs.md +++ /dev/null @@ -1,111 +0,0 @@ -time -log_date - -src_ip -- ip source de la connexion -src_port -- port source de la connexion -dst_ip -- ip de destination de la connexion -dst_port -- port de destination de la connexion - -src_asn -- Numero d'AS de l'ip source -src_country_code -- Code Pays de l'ip source -src_as_name -- Nom de l'AS de l ip source -src_org -- Organisation de l AS source -src_domain -- domaine de l'AS de l ip source - -method -- Methode HTTP [GET, POST, ... ] -scheme -- Type de connexion http [http, https] -host -- Hostname demandé dans l'url -path -- Path demandé dans l'url -query -- Query demandé dans l'url -http_version -- Version du protocol http utilisé - -orphan_side -- Indique si le log HTTP a pu etre enrichi avec les informations ip_, tcp, ja3_ et ja4_ -- "A" indique que seul le log HTTP est present, sans enrichissement -correlated -- l'algorithm de correlation log http + parametres tcp a il réussi (tcp + ja4/3) -keepalives -- Numero de desquance dans une connexion http avec keepalive. -a_timestamp -b_timestamp -conn_id - -ip_meta_df -- Flag dont fragement -ip_meta_id -- id du packet ip -ip_meta_total_length -- Taille des metadata dans pe packet ip -ip_meta_ttl -- TTL du packet ip vu par le serveur destinataire du packet - -tcp_meta_options -- options du packet TCP vu par le serveur destinataire du packet -tcp_meta_window_size -- TCP window size vu par le serveur destinataire du packet -tcp_meta_mss -- TCP mss vu par le serveur destinataire du packet -tcp_meta_window_scale -- TCP windows scale vu par le serveur destinataire du packet -syn_to_clienthello_ms -- durée en ms entre le 1er packet SYN et le ClienHello du TLS - -tls_version -- Version de TLS negocié avec le serveur destinataire du packet -tls_sni -- SNI, nom de domaine demandé pour le cerificat TLS -tls_alpn -- ALPN annoncé lors du TLS -ja3 -- liste des agos utiliés pour la signature ja3 -ja3_hash -- hash ja3 -ja4 -- hash ja4 - -client_headers -- liste des headers envoyés par le client http sous forme de liste Header,Header2,Header3,... - -header_user_agent -- Header HTTP User-Agent -header_accept -- Header HTTP Accept -header_accept_encoding -- Header HTTP Accept-Encoding -header_accept_language -- Header HTTP Accept-Language -header_content_type -- Header Content-Type -header_x_request_id -- Header X-Request-ID -header_x_trace_id -- Header X-Trace-ID -header_x_forwarded_for -- Header X-Forwarded-For -header_sec_ch_ua -- Header Sec-Ch-UA -header_sec_ch_ua_mobile -- Header -Sec-Ch-UA-Mobile -header_sec_ch_ua_platform -- Header Sec-Ch-UA-Plateform -header_sec_fetch_dest -- Header -Sec-Fetch-Dest -header_sec_fetch_mode -- Header Sec-Fetch-Mode -header_sec_fetch_site -- Header Sec-Fetch-Site diff --git a/old/services/correlator/idees/idees.txt b/old/services/correlator/idees/idees.txt deleted file mode 100644 index cd41361..0000000 --- a/old/services/correlator/idees/idees.txt +++ /dev/null @@ -1,30 +0,0 @@ -1. Incohérences de Signatures (Spoofing) - -User-Agent vs TLS : Le header_user_agent prétend être un navigateur (Chrome/Safari) mais le ja3/ja4 correspond à un outil de script. -User-Agent vs Headers modernes : Le header_user_agent indique un navigateur récent, mais les headers header_sec_ch_ua_* sont vides ou absents de client_headers. -User-Agent vs ALPN : Le navigateur déclaré ne correspond pas au protocole négocié dans tls_alpn (ex: Chrome sans h2). -OS vs TTL TCP : L'OS déclaré dans le header_user_agent (ex: Windows) contredit la valeur de ip_meta_ttl (ex: 64, typique de Linux). -Host vs SNI : Le nom de domaine dans le header host ne correspond pas au tls_sni demandé lors du handshake TLS. - -2. Anomalies de Headers (HTTP Fingerprinting) - -Empreinte d'ordre (Fingerprint) : Apparition soudaine d'une disposition de client_headers (ordre exact) très rare, générant beaucoup de trafic. -Pauvreté des headers : Le nombre total de headers dans client_headers est anormalement bas (ex: < 5), typique des scripts basiques. -Absence de headers vitaux : Le trafic prétend être humain mais n'envoie pas header_accept_language ou header_accept_encoding. -Combinaison fatale : Le croisement d'un ja4 spécifique avec un ordre de client_headers inédit (détection de bots modifiant leur TLS mais trahis par l'applicatif). - -3. Anomalies Réseau et TCP (Couche 3 & 4) - -Mécanique TCP de masse : Une même combinaison (tcp_meta_window_size, tcp_meta_window_scale, tcp_meta_mss) vue sur des milliers d'IP différentes. -Handshake robotique : Un délai syn_to_clienthello_ms anormalement constant (variance quasi nulle) sur un grand nombre de connexions, typique d'un bot en datacenter. -Options TCP atypiques : Des paramètres tcp_meta_options inhabituels pour le trafic web classique de tes vrais utilisateurs. - -4. Anomalies Comportementales et Volumétriques (Côté Requête) - -Rafale de requêtes (Spike) : Volume d'appels (count) par src_ip ou par ja4 dépassant drastiquement le 99ème percentile historique sur 5 minutes. -Scraping furtif distribué : Un même ja4 (non standard) utilisé par des centaines de src_ip différentes, chacune faisant très peu de requêtes. -Balayage aveugle (Scanner) : Un volume anormal de path uniques (ou path + query) visités par une même IP ou un même ja4 en quelques minutes (remplace la détection des erreurs 404). -Acharnement sur cible (Brute force aveugle) : Une concentration extrême de requêtes ciblant uniquement les path sensibles (login, API, password-reset) sans navigation normale sur le reste du site (remplace la détection des 401/403). -Méthodes suspectes : Utilisation massive ou inhabituelle de method non standards (PUT, DELETE, OPTIONS, TRACE) par rapport à la baseline. -Payloads suspects : Présence de patterns d'injection ou de caractères très inhabituels dans query ou path (longueur extrême, encodages multiples). -Bot "Low and Slow" : IP ou ja4 qui passe sous les radars sur 5 minutes, mais dont le volume cumulé sur 24h ou 7 jours est mathématiquement improbable pour un humain. diff --git a/old/services/correlator/idees/views.md b/old/services/correlator/idees/views.md deleted file mode 100644 index bb219b9..0000000 --- a/old/services/correlator/idees/views.md +++ /dev/null @@ -1,521 +0,0 @@ -# 🛡️ Manuel de Référence Technique : Moteur de Détection Antispam & Bot - -Ce document détaille les algorithmes de détection implémentés dans les vues ClickHouse pour la plateforme. - ---- - -## 1. Analyse de la Couche Transport (L4) : La "Trace Physique" -Avant même d'analyser l'URL, le moteur inspecte la manière dont la connexion a été établie. C'est la couche la plus difficile à falsifier pour un attaquant. - -### A. Fingerprint de la Pile TCP (`tcp_fingerprint`) -* **Fonctionnement :** Nous utilisons `cityHash64` pour créer un identifiant unique basé sur trois paramètres immuables du handshake : le **MSS** (Maximum Segment Size), la **Window Size** et le **Window Scale**. -* **Ce que ça détecte :** L'unicité logicielle. Un bot tournant sur une image Alpine Linux aura une signature TCP différente d'un utilisateur sur iOS 17 ou Windows 11. -* **Détection de botnet :** Si 500 IPs différentes partagent exactement le même `tcp_fingerprint` ET le même `ja4`, il y a une probabilité de 99% qu'il s'agisse d'un cluster de bots clonés. - - - -### B. Analyse de la gigue (Jitter) et Handshake -* **Fonctionnement :** On calcule la variance (`varPop`) du délai entre le `SYN` et le `ClientHello` TLS. -* **Ce que ça détecte :** La stabilité robotique. - * **Humain :** Latence variable (4G, Wi-Fi, mouvements). La variance est élevée. - * **Bot Datacenter :** Latence ultra-stable (fibre optique dédiée). Une variance proche de 0 indique une connexion automatisée depuis une infrastructure cloud. - ---- - -## 2. Analyse de la Session (L5) : Le "Passeport TLS" -Le handshake TLS est une mine d'or pour identifier la bibliothèque logicielle (OpenSSL, Go-TLS, etc.). - -### A. Incohérence UA vs JA4 -* **Fonctionnement :** Le moteur croise le `header_user_agent` (déclaratif) avec le `ja4` (structurel). -* **Ce que ça détecte :** Le **Spoofing de Browser**. Un script Python peut facilement écrire `User-Agent: Mozilla/5.0...Chrome/120`, mais il ne peut pas simuler l'ordre exact des extensions TLS et des algorithmes de chiffrement d'un vrai Chrome sans une ingénierie complexe (comme `utls`). -* **Logique de score :** Si UA = Chrome mais JA4 != Signature_Chrome -> **+50 points de risque**. - -### B. Discordance Host vs SNI -* **Fonctionnement :** Comparaison entre le champ `tls_sni` (négocié en clair lors du handshake) et le header `Host` (envoyé plus tard dans la requête chiffrée). -* **Ce que ça détecte :** Le **Domain Fronting** ou les attaques par tunnel. Un bot peut demander un certificat pour `domaine-innocent.com` (SNI) mais tenter d'attaquer `api-critique.com` (Host). - - - ---- - -## 3. Analyse Applicative (L7) : Le "Comportement HTTP" -Une fois le tunnel établi, on analyse la structure de la requête HTTP. - -### A. Empreinte d'ordre des Headers (`http_fp`) -* **Fonctionnement :** Nous hashons la liste ordonnée des clés de headers (`Accept`, `User-Agent`, `Connection`, etc.). -* **Ce que ça détecte :** La signature du moteur de rendu. Chaque navigateur (Firefox, Safari, Chromium) a un ordre immuable pour envoyer ses headers. -* **Détection :** Si un client envoie les headers dans un ordre inhabituel ou minimaliste (pauvreté des headers < 6), il est marqué comme suspect. - -### B. Analyse des Payloads et Entropie -* **Fonctionnement :** Recherche de patterns via regex dans `query` et `path` (détection SQLi, XSS, Path Traversal). -* **Complexité :** Nous détectons les encodages multiples (ex: `%2520`) qui tentent de tromper les pare-feux simples. - ---- - -## 4. Corrélation Temporelle & Baseline : Le "Voisinage Statistique" -Le score final dépend du passé de la signature TLS. - -### A. Le Malus de Nouveauté (`agg_novelty`) -* **Logique :** Une signature (JA4 + FP) vue pour la première fois aujourd'hui est "froide". -* **Traitement :** On applique un malus si `first_seen` date de moins de 2 heures. Un botnet qui vient de lancer une campagne de rotation de signatures sera immédiatement pénalisé par son manque d'historique. - -### B. Le Dépassement de Baseline (`tbl_baseline_ja4_7d`) -* **Fonctionnement :** On compare les `hits` actuels au 99ème percentile (`p99`) historique de cette signature précise. -* **Exemple :** Si le JA4 de "Chrome 122" fait habituellement 10 requêtes/min/IP sur votre site, et qu'une IP en fait soudainement 300, le score explose même si la requête est techniquement parfaite. - ---- - -## 5. Synthèse du Scoring (Le Verdict) - -| Algorithme | Signal | Impact Score | -| :--- | :--- | :--- | -| **Fingerprint Mismatch** | UA vs TLS (Spoofing) | **Haut (50)** | -| **L4 Anomaly** | Variance latence < 0.5ms | **Moyen (30)** | -| **Path Sensitivity** | Hit sur `/admin` ou `/config` | **Haut (40)** | -| **Payload Security** | Caractères d'injection (SQL/XSS) | **Critique (60)** | -| **Mass Distribution** | 1 JA4 sur > 50 IPs différentes | **Moyen (30)** | - - - ---- - -## 6. Identification des Hosts par IP et JA4 (sql/hosts.sql) - -Cette section détaille les vues d'agrégation et de détection pour identifier quels hosts sont associés à quelles signatures (IP + JA4). - -### A. Agrégats de Base - -| Table | Granularité | Description | -|-------|-------------|-------------| -| `agg_host_ip_ja4_1h` | heure | Hits, paths uniques, query params, méthodes par (IP, JA4, host) | -| `agg_host_ip_ja4_24h` | jour | Rollup quotidien pour historique long terme | - -### B. Vues d'Identification - -**`view_host_identification`** - Top hosts par signature -```sql --- Quel host est associé à cette IP/JA4 ? -SELECT src_ip, ja4, host, total_hits, unique_paths, user_agent -FROM ja4_processing.view_host_identification -WHERE src_ip = '1.2.3.4' -ORDER BY total_hits DESC; -``` - -**`view_host_ja4_anomalies`** - JA4 partagé par plusieurs hosts (botnet) -```sql --- Ce JA4 est-il utilisé par plusieurs hosts différents ? -SELECT ja4, hosts, unique_hosts, unique_ips -FROM ja4_processing.view_host_ja4_anomalies -HAVING unique_hosts >= 3; --- Interprétation : 1 JA4 sur 3+ hosts = botnet cloné probable -``` - -**`view_host_ip_ja4_rotation`** - IP avec rotation de fingerprints -```sql --- Cette IP change-t-elle de JA4 fréquemment ? -SELECT src_ip, ja4s, unique_ja4s -FROM ja4_processing.view_host_ip_ja4_rotation -HAVING unique_ja4s >= 5; --- Interprétation : 1 IP avec 5+ JA4 différents = fingerprint spoofing -``` - ---- - -## 7. Détection de Brute Force (sql/hosts.sql) - -### A. Brute Force sur POST (endpoints sensibles) - -**Table :** `agg_bruteforce_post_5m` - Fenêtres de 5 minutes - -**Vue :** `view_bruteforce_post_detected` -```sql --- Détecter les tentatives de brute force sur les login -SELECT window, src_ip, ja4, host, path, attempts, attempts_per_minute -FROM ja4_processing.view_bruteforce_post_detected -WHERE host = 'api.example.com' -ORDER BY attempts DESC; - --- Threshold : ≥10 POST en 5 minutes sur endpoints sensibles --- Endpoints ciblés : login, auth, signin, password, admin, wp-login, etc. -``` - -### B. Brute Force sur Formulaire (Query params variables) - -**Table :** `agg_form_bruteforce_5m` - -**Vue :** `view_form_bruteforce_detected` -```sql --- Détecter les requêtes avec query params hautement variables -SELECT window, src_ip, ja4, host, path, requests, unique_query_patterns -FROM ja4_processing.view_form_bruteforce_detected -HAVING requests >= 20 AND unique_query_patterns >= 10; - --- Interprétation : 20+ requêtes avec 10+ patterns query différents --- = tentative de fuzzing ou brute force sur paramètres -``` - ---- - -## 8. Header Fingerprinting (sql/hosts.sql) - -Le champ `client_headers` contient la liste comma-separated des headers présents. -Exemple : `"Accept,Accept-Encoding,Sec-CH-UA,Sec-Fetch-Dest,User-Agent"` - -### A. Signature par Ordre de Headers - -**Table :** `agg_header_fingerprint_1h` - -| Champ | Description | -|-------|-------------| -| `header_count` | Nombre total de headers (virgules + 1) | -| `has_*` | Flags pour chaque header moderne (Sec-CH-UA, Sec-Fetch-*, etc.) | -| `header_order_hash` | MD5(client_headers) = signature unique de l'ordre | -| `modern_browser_score` | Score 0-100 basé sur les headers modernes présents | - -### B. Vues de Détection - -**`view_header_missing_modern_headers`** - Headers modernes manquants -```sql --- Navigateurs "modernes" avec headers manquants -SELECT src_ip, ja4, header_user_agent, modern_browser_score, header_count -FROM ja4_processing.view_header_missing_modern_headers -WHERE header_user_agent ILIKE '%Chrome%'; - --- Threshold : score < 70 pour Chrome/Firefox = suspect --- Un vrai Chrome envoie automatiquement Sec-CH-UA, Sec-Fetch-*, etc. -``` - -**`view_header_ua_order_mismatch`** - Spoofing détecté -```sql --- Même User-Agent avec ordre de headers différent -SELECT header_user_agent, ja4, unique_hashes, unique_ips -FROM ja4_processing.view_header_ua_order_mismatch -HAVING unique_hashes > 1; - --- Interprétation : 1 UA avec 2+ ordres de headers = spoofing ou outil custom -``` - -**`view_header_minimalist_count`** - Bot minimaliste -```sql --- Clients avec trop peu de headers -SELECT src_ip, ja4, header_count, header_user_agent -FROM ja4_processing.view_header_minimalist_count -WHERE header_count < 6; - --- Threshold : < 6 headers = bot scripté (curl, Python requests, etc.) -``` - -**`view_header_sec_ch_missing`** - Incohérence Chrome -```sql --- Chrome sans Sec-CH-UA (impossible pour un vrai Chrome) -SELECT src_ip, ja4, header_user_agent -FROM ja4_processing.view_header_sec_ch_missing -WHERE header_user_agent ILIKE '%Chrome/%'; -``` - -**`view_header_known_bot_signature`** - Signature botnet -```sql --- Même ordre de headers sur 10+ IPs différentes -SELECT header_order_hash, header_user_agent, unique_ips, total_hits -FROM ja4_processing.view_header_known_bot_signature -HAVING unique_ips >= 10; - --- Interprétation : 1 signature sur 10+ IPs = cluster de bots clonés -``` - ---- - -## 9. ALPN Mismatch Detection (sql/hosts.sql) - -### Principe - -ALPN (Application-Layer Protocol Negotiation) est une extension TLS qui négocie le protocole HTTP **avant** la requête. - -| ALPN déclaré | HTTP réel | Interprétation | -|--------------|-----------|----------------| -| `h2` | `HTTP/2` | ✅ Normal | -| `h2` | `HTTP/1.1` | ❌ Bot mal configuré | -| `http/1.1` | `HTTP/1.1` | ✅ Normal | - -### Vue de Détection - -**`view_alpn_mismatch_detected`** -```sql --- Clients déclarant h2 mais parlant HTTP/1.1 -SELECT src_ip, ja4, declared_alpn, actual_http_version, mismatches, mismatch_pct -FROM ja4_processing.view_alpn_mismatch_detected -HAVING mismatch_pct >= 80; - --- Threshold : ≥5 requêtes avec ≥80% d'incohérence --- Cause : curl mal configuré, Python requests, bots spoofant ALPN -``` - ---- - -## 10. Rate Limiting & Burst Detection (sql/hosts.sql) - -### A. Rate Limiting (1 minute) - -**Table :** `agg_rate_limit_1m` - -**Vue :** `view_rate_limit_exceeded` -```sql --- IPs dépassant 50 requêtes/minute -SELECT minute, src_ip, ja4, requests_per_min, unique_paths -FROM ja4_processing.view_rate_limit_exceeded -ORDER BY requests_per_min DESC; - --- Threshold : > 50 req/min = trafic automatisé --- Un humain ne peut pas soutenir 50+ req/min de manière cohérente -``` - -### B. Burst Detection (10 secondes) - -**Table :** `agg_burst_10s` - -**Vue :** `view_burst_detected` -```sql --- Pics soudains de trafic -SELECT window, src_ip, ja4, burst_count -FROM ja4_processing.view_burst_detected -HAVING burst_count > 20; - --- Threshold : > 20 requêtes en 10 secondes = burst suspect --- Utile pour détecter les attaques par vagues -``` - ---- - -## 11. Path Enumeration / Scanning (sql/hosts.sql) - -### Vue de Détection - -**`view_path_scan_detected`** -```sql --- Détection de scanning de paths sensibles -SELECT window, src_ip, ja4, host, sensitive_hits, sensitive_ratio -FROM ja4_processing.view_path_scan_detected -HAVING sensitive_hits >= 5; - --- Paths surveillés : admin, backup, config, .env, .git, wp-admin, --- phpinfo, test, debug, log, sql, dump, passwd, shadow, htaccess, etc. - --- Threshold : ≥5 paths sensibles en 5 minutes = scanning -``` - -### Exemple de Résultat - -| src_ip | ja4 | host | sensitive_hits | sensitive_ratio | -|--------|-----|------|----------------|-----------------| -| 1.2.3.4 | t13d... | api.example.com | 47 | 94.00 | -| 5.6.7.8 | t13d... | www.example.com | 12 | 80.00 | - -**Interprétation :** Ces IPs testent systématiquement les paths sensibles = outils comme Nikto, Dirb, Gobuster. - ---- - -## 12. Payload Attack Detection (sql/hosts.sql) - -### A. Types d'Attaques Détectées - -| Type | Patterns Détectés | -|------|-------------------| -| **SQL Injection** | `UNION SELECT`, `OR 1=1`, `DROP TABLE`, `; --`, `/* */`, `WAITFOR DELAY`, `SLEEP()` | -| **XSS** | `