Some checks failed
Build RPM Package / Build RPM Packages (CentOS 7, Rocky 8/9/10) (push) Has been cancelled
+- FEATURE: Add comprehensive metrics for capture and TLS parser monitoring +- Capture metrics: packets_received, packets_sent, packets_dropped (atomic counters) +- Parser metrics: retransmit_count, gap_detected_count, buffer_exceeded_count, segment_exceeded_count +- New GetStats() method on Capture interface for capture statistics +- New GetMetrics() method on Parser interface for parser statistics +- Add DefaultMaxHelloSegments constant (100) to prevent memory leaks from fragmented handshakes +- Add Segments field to ConnectionFlow for per-flow segment tracking +- Increase DefaultMaxTrackedFlows from 50000 to 100000 for high-traffic scenarios +- Improve TCP reassembly: better handling of retransmissions and sequence gaps +- Memory leak prevention: limit segments per flow and buffer size +- Aggressive flow cleanup: clean up JA4_DONE flows when approaching flow limit +- Lock ordering fix: release flow.mu before acquiring p.mu to avoid deadlocks +- Exclude IPv6 link-local addresses (fe80::) from local IP detection +- Improve error logging with detailed connection and TLS extension information +- Add capture diagnostics logging (interface, link_type, local_ips, bpf_filter) +- Fix false positive retransmission counter when SYN packet is missed +- Fix gap handling: reset sequence tracking instead of dropping flow +- Fix extractTLSExtensions: return error details with basic TLS info for debugging
JA4Sentinel
Outil Go pour capturer le trafic réseau sur un serveur Linux, extraire les handshakes TLS côté client, générer les signatures JA4, enrichir avec des métadonnées IP/TCP, et loguer les résultats vers une ou plusieurs sorties configurables.
Fonctionnalités
- Capture réseau : Écoute sur une interface réseau avec filtres BPF configurables
- Parsing TLS : Extraction des ClientHello TLS depuis les flux TCP
- Fingerprinting : Génération des empreintes JA4 et JA3 pour chaque client
- Métadonnées : Enrichissement avec IPMeta (TTL, IP ID, DF) et TCPMeta (window, MSS, options)
- Sorties multiples : stdout, fichier JSON, socket UNIX (combinables via MultiWriter)
- Logging structuré : Logs JSON sur stdout/stderr pour intégration avec systemd/journald
Architecture
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Capture │ ──▶ │ TLSParse │ ──▶ │ Fingerprint │ ──▶ │ Output │
│ (pcap) │ │ (ClientHello)│ │ (JA4) │ │ (JSON logs) │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
▼ ▼ ▼ ▼
api.RawPacket api.TLSClientHello api.Fingerprints api.LogRecord
Modules
| Module | Responsabilités |
|---|---|
config |
Chargement et validation de la configuration (YAML, env, CLI) |
capture |
Capture des paquets réseau via libpcap |
tlsparse |
Extraction des ClientHello TLS avec suivi d'état de flux |
fingerprint |
Génération JA4/JA3 via psanford/tlsfingerprint |
output |
Écriture des logs vers stdout, fichier, socket UNIX |
logging |
Logs structurés JSON pour le diagnostic du service |
Installation
Prérequis
- Go 1.24+
- libpcap-dev (pour la compilation)
- Docker (pour les tests et le déploiement)
Note sur libpcap
Le binaire est compilé sur Rocky Linux 9 pour une compatibilité maximale avec toutes les distributions RHEL/Rocky/AlmaLinux. libpcap est requis à l'exécution et sera installé automatiquement par le gestionnaire de packages.
Packages système
Rocky Linux / RHEL / AlmaLinux (.rpm)
# Télécharger le package
wget https://github.com/your-repo/ja4sentinel/releases/latest/download/ja4sentinel.rpm
# Installer
sudo dnf install ./ja4sentinel.rpm
# Activer le service
sudo systemctl enable ja4sentinel
sudo systemctl start ja4sentinel
# Vérifier le statut
sudo systemctl status ja4sentinel
Distributions supportées
- Rocky Linux 8, 9, 10
- AlmaLinux 8, 9, 10
- RHEL 8, 9, 10
Configuration
Fichier de configuration (YAML)
core:
interface: eth0
listen_ports: [443, 8443]
bpf_filter: ""
flow_timeout_sec: 30
outputs:
- type: stdout
enabled: true
- type: file
enabled: true
params:
path: /var/log/ja4sentinel/ja4.log
- type: unix_socket
enabled: true
params:
socket_path: /var/run/logcorrelator/network.socket
Variables d'environnement
| Variable | Description |
|---|---|
JA4SENTINEL_INTERFACE |
Interface réseau (ex: eth0) |
JA4SENTINEL_PORTS |
Ports à surveiller (ex: 443,8443) |
JA4SENTINEL_BPF_FILTER |
Filtre BPF personnalisé |
JA4SENTINEL_FLOW_TIMEOUT |
Timeout de flux en secondes (défaut: 30) |
Ligne de commande
ja4sentinel --config /etc/ja4sentinel/config.yml
ja4sentinel --version
Format des logs
Logs de service (stdout/stderr)
{
"timestamp": 1708876543210000000,
"level": "INFO",
"component": "capture",
"message": "Starting packet capture",
"interface": "eth0"
}
Logs métier (JA4)
{
"src_ip": "192.168.1.100",
"src_port": 54321,
"dst_ip": "10.0.0.1",
"dst_port": 443,
"ip_meta_ttl": 64,
"ip_meta_total_length": 512,
"ip_meta_id": 12345,
"ip_meta_df": true,
"tcp_meta_window_size": 65535,
"tcp_meta_mss": 1460,
"tcp_meta_window_scale": 7,
"tcp_meta_options": "MSS,WS,SACK,TS",
"ja4": "t13d1516h2_8daaf6152771_02cb136f2775",
"ja4_hash": "8daaf6152771_02cb136f2775",
"ja3": "771,4865-4866-4867,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0",
"ja3_hash": "a0e6f06c7a6d15e5e3f0f0e6f06c7a6d"
}
Tests
Tests unitaires
# En local
make test
# Dans Docker
make test-docker
# Avec détection de race conditions
make test-race
# Avec rapport de couverture
make test-coverage
Tests d'intégration
# Lance les tests bout-à-bout dans Docker
make test-integration
# Nettoyage après tests
make test-integration-clean
Déploiement systemd
Exemple de fichier de service /etc/systemd/system/ja4sentinel.service :
[Unit]
Description=JA4 client fingerprinting daemon
After=network.target
[Service]
Type=simple
User=ja4sentinel
Group=ja4sentinel
ExecStart=/usr/local/bin/ja4sentinel --config /etc/ja4sentinel/config.yml
Restart=on-failure
RestartSec=5
Environment=JA4SENTINEL_LOG_LEVEL=info
# Security
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target
Exemples d'utilisation
Surveillance du trafic HTTPS
core:
interface: eth0
listen_ports: [443]
outputs:
- type: stdout
enabled: true
Export vers socket UNIX pour traitement externe
core:
interface: eth0
listen_ports: [443, 8443]
outputs:
- type: unix_socket
enabled: true
params:
socket_path: /var/run/logcorrelator/network.socket
# log_level: debug # debug, info, warn, error (défaut: error)
Logging fichier + stdout
core:
interface: ens192
listen_ports: [443]
flow_timeout_sec: 60
outputs:
- type: stdout
enabled: true
- type: file
enabled: true
params:
path: /var/log/ja4sentinel/ja4.json
Développement
Linting
make lint
Formatage
make fmt
Nettoyage
# Supprime les binaires et images Docker
make clean
# Supprime aussi les conteneurs et volumes
make clean-all
Licence
À définir.
Contribuer
- Fork le projet
- Créer une branche de feature (
git checkout -b feature/amélioration) - Commit les changements (
git commit -am 'Ajout fonctionnalité') - Push (
git push origin feature/amélioration) - Ouvrir une Pull Request
Voir architecture.yml pour la documentation complète de l'architecture.
Description
Languages
Go
97.3%
Makefile
2.1%
Dockerfile
0.6%