# Version macro must be defined BEFORE it's used in Version: field # Override from command line: rpmbuild --define "build_version X.Y.Z" %if %{defined build_version} %define spec_version %{build_version} %else %define spec_version 1.1.7 %endif Name: ja4sentinel Version: %{spec_version} Release: 1%{?dist} Summary: JA4 TLS fingerprinting daemon for network monitoring License: MIT URL: https://github.com/your-repo/ja4sentinel BuildArch: x86_64 # Distribution-agnostic dependencies # systemd is available on all target distros (Rocky 8/9/10, AlmaLinux) Requires: systemd # libpcap is required for packet capture (dynamically linked) # Version varies by distro: Rocky 8/9/10 (1.9.0+) Requires: libpcap >= 1.9.0 %description JA4Sentinel is a Go-based tool for capturing network traffic on Linux servers, extracting client-side TLS handshakes, generating JA4 signatures, enriching with IP/TCP metadata, and logging results to configurable outputs. Features: - Network packet capture with BPF filters - TLS ClientHello extraction - JA4/JA3 fingerprint generation - IP/TCP metadata enrichment - Multiple output formats (UNIX socket by default, stdout, file) - Structured JSON logging for systemd/journald - Compatible with Rocky Linux 8/9/10, RHEL, AlmaLinux %prep # No source to unpack, binary is pre-built %build # No build needed, binary is pre-built %install mkdir -p %{buildroot}/usr/bin mkdir -p %{buildroot}/etc/ja4sentinel mkdir -p %{buildroot}/etc/logrotate.d mkdir -p %{buildroot}/var/lib/ja4sentinel mkdir -p %{buildroot}/var/log/ja4sentinel mkdir -p %{buildroot}/var/run/logcorrelator mkdir -p %{buildroot}/usr/lib/systemd/system mkdir -p %{buildroot}/usr/share/ja4sentinel # Install binary install -m 755 %{_sourcedir}/ja4sentinel %{buildroot}/usr/bin/ja4sentinel # Install systemd service install -m 644 %{_sourcedir}/ja4sentinel.service %{buildroot}/usr/lib/systemd/system/ja4sentinel.service # Install logrotate configuration install -m 644 %{_sourcedir}/logrotate/ja4sentinel %{buildroot}/etc/logrotate.d/ja4sentinel # Install default config install -m 640 %{_sourcedir}/config.yml %{buildroot}/etc/ja4sentinel/config.yml.default install -m 640 %{_sourcedir}/config.yml %{buildroot}/usr/share/ja4sentinel/config.yml %pre # No user creation needed - service runs as root for packet capture exit 0 %post # Set proper ownership (root:root for packet capture) chown -R root:root /var/lib/ja4sentinel 2>/dev/null || true chown -R root:root /var/run/logcorrelator 2>/dev/null || true chown -R root:root /var/log/ja4sentinel 2>/dev/null || true chown -R root:root /etc/ja4sentinel 2>/dev/null || true # Set proper permissions chmod 750 /var/lib/ja4sentinel 2>/dev/null || true chmod 750 /var/log/ja4sentinel 2>/dev/null || true chmod 750 /etc/ja4sentinel 2>/dev/null || true # Install config if not exists if [ ! -f /etc/ja4sentinel/config.yml ]; then cp /usr/share/ja4sentinel/config.yml /etc/ja4sentinel/config.yml chmod 640 /etc/ja4sentinel/config.yml fi # Reload systemd and enable service (only if systemd is running) if [ -x /bin/systemctl ] && [ -d /run/systemd/system ]; then /bin/systemctl daemon-reload /bin/systemctl enable ja4sentinel.service 2>/dev/null || : /bin/systemctl start ja4sentinel.service 2>/dev/null || : fi %preun if [ $1 -eq 0 ]; then # Package removal, stop and disable service if [ -x /bin/systemctl ]; then /bin/systemctl stop ja4sentinel.service >/dev/null 2>&1 || : /bin/systemctl disable ja4sentinel.service >/dev/null 2>&1 || : fi fi %postun if [ $1 -eq 0 ]; then # Package removal, reload systemd if [ -x /bin/systemctl ]; then /bin/systemctl daemon-reload fi fi %files /usr/bin/ja4sentinel /usr/lib/systemd/system/ja4sentinel.service /etc/logrotate.d/ja4sentinel /usr/share/ja4sentinel/config.yml %config(noreplace) /etc/ja4sentinel/config.yml.default %dir /etc/ja4sentinel %dir /var/lib/ja4sentinel %dir /var/log/ja4sentinel %dir /var/run/logcorrelator %changelog * Mon Mar 02 2026 Jacquin Antoine - 1.1.5-1 - Fix: Use unixgram (DGRAM) instead of unix (STREAM) for socket output - Fixes \"protocol wrong type for socket\" error - DGRAM sockets are connectionless, better suited for log shipping * Mon Mar 02 2026 Jacquin Antoine - 1.1.4-1 - Add error callback for file output writer - File write errors (permission, disk space, rotation) now logged - Same error reporting mechanism as UNIX socket writer * Mon Mar 02 2026 Jacquin Antoine - 1.1.2-1 - Add error callback mechanism for UNIX socket connection failures - Add ErrorCallback type and WithErrorCallback option for UnixSocketWriter - Add BuilderImpl.WithErrorCallback() for propagating error callbacks - Add processQueue error reporting with consecutive failure tracking - Add 50+ new unit tests across all modules (capture, config, fingerprint, tlsparse, output, cmd) - Add integration tests for full pipeline (TLS ClientHello → fingerprint → output) - Add tests for FileWriter.rotate() and FileWriter.Reopen() log rotation - Add tests for cleanupExpiredFlows() and cleanupLoop() in TLS parser - Add tests for extractSNIFromPayload() and extractJA4Hash() helpers - Add tests for config load error paths (invalid YAML, permission denied) - Update architecture.yml with new fields (LogLevel, TLSClientHello extensions) - Update architecture.yml with Close() methods for Capture and Parser interfaces - Remove empty internal/api/ directory * Mon Mar 02 2026 Jacquin Antoine - 1.1.0-1 - Add logrotate configuration for automatic log file rotation - Add SIGHUP signal handling for log file reopening (systemctl reload) - Add ExecReload to systemd service for graceful log rotation - Add Reopenable interface for output writers supporting log rotation - Add FileWriter.Reopen() method for log file rotation support - Add MultiWriter.Reopen() method to propagate rotation to all writers - Update main.go to handle SIGHUP signal for log rotation - Add packaging/logrotate/ja4sentinel configuration file - Update architecture.yml with logrotate and reload documentation - Update Dockerfile.package to include logrotate file in RPM build * Mon Mar 02 2026 Jacquin Antoine - 1.0.9-1 - Add SNI (Server Name Indication) extraction from TLS ClientHello - Add ALPN (Application-Layer Protocol Negotiation) extraction - Add TLS version detection from ClientHello - Add ConnID field for flow correlation - Add SensorID field for multi-sensor deployments - Add SynToCHMs timing field for behavioral detection - Add AsyncBuffer configuration for output queue sizing - Remove JA4Hash from LogRecord (JA4 format includes its own hash) - Use tlsfingerprint library for ALPN and TLS version parsing - Update architecture.yml compliance for all new fields - Add unit tests for TLS extension extraction * Sun Mar 01 2026 Jacquin Antoine - 1.0.8-1 - Add configurable log level (debug, info, warn, error) via config.yml - Add JA4SENTINEL_LOG_LEVEL environment variable support - Set TimeoutStopSec=2 for immediate service stop on restart/stop - Consolidate config files into single example (config.yml.example) %changelog * Wed Mar 04 2026 Jacquin Antoine - 1.1.7-1 - FIX: Improve error logging with source/destination details - Add src_ip, src_port, dst_ip, dst_port to tlsparse error logs - Add connection details to fingerprint error logs (conn_id, payload_len) - Include 'unknown' placeholders for packets that fail before parsing - Helps debug truncated ClientHello payloads and identify problematic connections * Wed Mar 04 2026 Jacquin Antoine - 1.1.6-1 - FEATURE: Add support for capturing traffic to local machine IPs only - Add local_ips configuration option (auto-detect or manual list) - Auto-detection excludes loopback addresses (127.x.x.x, ::1) - Support interface "any" for capturing on all network interfaces - Add Linux SLL (cooked capture) support for interface "any" - Generate BPF filter with "dst host" for local IP filtering - Add LinkType field to RawPacket for proper packet parsing - Add unit tests for local IP detection and SLL packet parsing - Update version to 1.1.6 * Sat Feb 28 2026 Jacquin Antoine - 1.0.4-1 - Add systemd sdnotify support (READY, WATCHDOG, STOPPING signals) - Enable systemd watchdog with 30s timeout - Update service unit to Type=notify - Document sdnotify integration in architecture.yml * Sat Feb 28 2026 JA4Sentinel Team - 1.0.2-1 - BREAKING: Drop CentOS 7 support (EOL June 2024), minimum Rocky Linux 8 - Fix race condition in TLS parser with per-ConnectionFlow mutex - Fix memory leak in fragmented ClientHello buffer accumulation - Add log file rotation (100MB, 3 backups) - Improve UNIX socket reconnection with async queue and exponential backoff - Add BPF filter validation (characters, length, balanced parentheses) - Secure file permissions (0600 instead of 0644) - Add 46 unit tests (capture, output, logging) - Enable race detection in test pipeline (go test -race) - Increase pcap snaplen from 1600 to 65535 bytes for large TLS handshakes - Increase socket timeouts (2s to 5s) with configurable backoff - Add named constants for configuration values * Sat Feb 28 2026 JA4Sentinel Team - 1.0.1-1 - Add configurable packet channel buffer size for high-throughput capture - Add timestamp field to LogRecord for precise event tracking - Fix race condition: close packetChan after capture goroutine finishes - Strengthen TLS limits and socket timeouts for robustness - Improve configuration validation with stricter checks - Include systemd service file in RPM packages - Unified Docker-based packaging for CentOS 7, Rocky Linux 8/9/10 - Add comprehensive unit tests for API and cmd packages - Add Godoc documentation for all public interfaces * Wed Feb 25 2026 JA4Sentinel Team - 1.0.0-1 - Initial package release for CentOS 7, Rocky Linux 8/9/10