- TC ingress hook captures TCP SYN (L3/L4) and TLS ClientHello - Uprobes on SSL_read/SSL_set_fd capture decrypted TLS data - Kprobes on accept4 correlate socket FDs to client IP:port - JA4 fingerprint computed from parsed TLS ClientHello - HTTP/2 SETTINGS and WINDOW_UPDATE extracted from decrypted streams - Session manager with sharded map (256 shards) and GC goroutine - Slowloris detection: sessions with no requests after 10s threshold - ClickHouse batch writer to ja4_logs.http_logs_raw (raw_json) - All tests pass: 17 parser + 10 correlation tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
81 lines
3.6 KiB
Desktop File
81 lines
3.6 KiB
Desktop File
# =============================================================================
|
|
# ja4ebpf.service — Unité systemd pour l'agent eBPF ja4ebpf
|
|
#
|
|
# Installation :
|
|
# install -m 644 ja4ebpf.service /usr/lib/systemd/system/
|
|
# systemctl daemon-reload
|
|
# systemctl enable --now ja4ebpf
|
|
#
|
|
# Sécurité :
|
|
# L'agent fonctionne sous un compte dédié "ja4ebpf" sans shell ni home.
|
|
# Les capabilities Linux strictement nécessaires sont accordées via
|
|
# AmbientCapabilities + CapabilityBoundingSet (sans User=root).
|
|
# Cible : RHEL/CentOS/Rocky/Alma 8+ (kernel ≥ 4.18, BTF natif disponible).
|
|
# =============================================================================
|
|
[Unit]
|
|
Description=JA4 eBPF Network Fingerprint Agent
|
|
Documentation=https://github.com/antitbone/ja4-platform
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=ja4ebpf
|
|
Group=ja4ebpf
|
|
|
|
ExecStart=/usr/sbin/ja4ebpf -config /etc/ja4ebpf/config.yml
|
|
ExecReload=/bin/kill -HUP $MAINPID
|
|
Restart=on-failure
|
|
RestartSec=5s
|
|
TimeoutStopSec=30s
|
|
|
|
# ── Capabilities Linux ─────────────────────────────────────────────────────
|
|
# CAP_BPF : charger/créer des programmes et maps eBPF (kernel ≥ 5.8)
|
|
# Sur RHEL 8 (4.18), cilium/ebpf retombe sur CAP_SYS_ADMIN.
|
|
# CAP_NET_ADMIN : attacher un programme TC sur une interface réseau
|
|
# CAP_NET_RAW : accès raw socket (fallback sur kernels sans TCX)
|
|
# CAP_PERFMON : attacher des perf_events / uprobes (kernel ≥ 5.8)
|
|
# CAP_SYS_ADMIN : requis sur RHEL 8 / kernel < 5.8 pour charger eBPF
|
|
# CAP_SYS_PTRACE : résoudre les offsets de fonctions pour les uprobes
|
|
# CAP_DAC_READ_SEARCH : lire /proc/<pid>/maps pour localiser libssl.so
|
|
CapabilityBoundingSet=CAP_BPF CAP_NET_ADMIN CAP_NET_RAW CAP_PERFMON CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
|
|
AmbientCapabilities=CAP_BPF CAP_NET_ADMIN CAP_NET_RAW CAP_PERFMON CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
|
|
|
|
# Ne jamais acquérir de nouveaux privilèges via setuid/setgid
|
|
NoNewPrivileges=yes
|
|
|
|
# ── Isolation du système de fichiers ───────────────────────────────────────
|
|
ProtectSystem=strict
|
|
ProtectHome=yes
|
|
ReadWritePaths=/var/lib/ja4ebpf /var/log/ja4ebpf /run/ja4ebpf
|
|
PrivateTmp=yes
|
|
PrivateDevices=no
|
|
|
|
# ── Isolation réseau ───────────────────────────────────────────────────────
|
|
PrivateNetwork=no
|
|
|
|
# ── Divers ─────────────────────────────────────────────────────────────────
|
|
ProtectKernelTunables=no
|
|
ProtectKernelModules=yes
|
|
ProtectKernelLogs=no
|
|
ProtectControlGroups=yes
|
|
RestrictNamespaces=yes
|
|
LockPersonality=yes
|
|
MemoryDenyWriteExecute=no # JIT eBPF requiert des mappings exécutables kernel-side
|
|
|
|
# ── Limites de ressources ──────────────────────────────────────────────────
|
|
LimitMEMLOCK=infinity
|
|
LimitNOFILE=65536
|
|
|
|
# ── Journalisation ─────────────────────────────────────────────────────────
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=ja4ebpf
|
|
|
|
WorkingDirectory=/var/lib/ja4ebpf
|
|
RuntimeDirectory=ja4ebpf
|
|
RuntimeDirectoryMode=0750
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|