# =============================================================================
# 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
