diff --git a/api/types.go b/api/types.go index a9dde0d..7ae85bc 100644 --- a/api/types.go +++ b/api/types.go @@ -13,10 +13,11 @@ type ServiceLog struct { // Config holds basic network and TLS configuration type Config struct { - Interface string `json:"interface"` - ListenPorts []uint16 `json:"listen_ports"` - BPFFilter string `json:"bpf_filter,omitempty"` - FlowTimeoutSec int `json:"flow_timeout_sec,omitempty"` // Timeout for TLS handshake extraction (default: 30) + Interface string `json:"interface"` + ListenPorts []uint16 `json:"listen_ports"` + BPFFilter string `json:"bpf_filter,omitempty"` + FlowTimeoutSec int `json:"flow_timeout_sec,omitempty"` // Timeout for TLS handshake extraction (default: 30) + PacketBufferSize int `json:"packet_buffer_size,omitempty"` // Buffer size for packet channel (default: 1000) } // IPMeta contains IP metadata for stack fingerprinting @@ -238,10 +239,11 @@ func joinStringSlice(slice []string, sep string) string { // Default values and constants const ( - DefaultInterface = "eth0" - DefaultPort = 443 - DefaultBPFFilter = "" - DefaultFlowTimeout = 30 // seconds + DefaultInterface = "eth0" + DefaultPort = 443 + DefaultBPFFilter = "" + DefaultFlowTimeout = 30 // seconds + DefaultPacketBuffer = 1000 // packet channel buffer size // Logging levels LogLevelDebug = "DEBUG" @@ -252,15 +254,17 @@ const ( // DefaultConfig returns an AppConfig with sensible default values. // Uses eth0 as the default interface, port 443 for monitoring, -// no BPF filter, and a 30-second flow timeout. Returns an empty -// outputs slice (caller must configure outputs explicitly). +// no BPF filter, a 30-second flow timeout, and a 1000-packet +// channel buffer. Returns an empty outputs slice (caller must +// configure outputs explicitly). func DefaultConfig() AppConfig { return AppConfig{ Core: Config{ - Interface: DefaultInterface, - ListenPorts: []uint16{DefaultPort}, - BPFFilter: DefaultBPFFilter, - FlowTimeoutSec: DefaultFlowTimeout, + Interface: DefaultInterface, + ListenPorts: []uint16{DefaultPort}, + BPFFilter: DefaultBPFFilter, + FlowTimeoutSec: DefaultFlowTimeout, + PacketBufferSize: DefaultPacketBuffer, }, Outputs: []OutputConfig{}, } diff --git a/cmd/ja4sentinel/main.go b/cmd/ja4sentinel/main.go index a8565ec..a50f707 100644 --- a/cmd/ja4sentinel/main.go +++ b/cmd/ja4sentinel/main.go @@ -84,8 +84,12 @@ func main() { os.Exit(1) } - // Create channel for raw packets - packetChan := make(chan api.RawPacket, 1000) + // Create channel for raw packets (configurable buffer size) + bufferSize := appConfig.Core.PacketBufferSize + if bufferSize <= 0 { + bufferSize = 1000 // Default fallback + } + packetChan := make(chan api.RawPacket, bufferSize) // Start capture goroutine captureErrChan := make(chan error, 1) diff --git a/config.yml.example b/config.yml.example index ee609df..2de3198 100644 --- a/config.yml.example +++ b/config.yml.example @@ -4,27 +4,33 @@ core: # Network interface to capture traffic from interface: eth0 - + # TCP ports to monitor for TLS handshakes listen_ports: - 443 - 8443 - + # Optional BPF filter (leave empty for auto-generated filter based on listen_ports) bpf_filter: "" + # Timeout in seconds for TLS handshake extraction (default: 30) + flow_timeout_sec: 30 + + # Buffer size for packet channel (default: 1000, increase for high-traffic environments) + packet_buffer_size: 1000 + outputs: # Output to stdout (JSON lines) - type: stdout enabled: true params: {} - + # Output to file # - type: file # enabled: false # params: # path: /var/log/ja4sentinel/ja4.log - + # Output to UNIX socket (for systemd/journald or other consumers) # - type: unix_socket # enabled: false diff --git a/internal/config/loader.go b/internal/config/loader.go index f27b2b8..51d6ac7 100644 --- a/internal/config/loader.go +++ b/internal/config/loader.go @@ -97,6 +97,13 @@ func (l *LoaderImpl) loadFromEnv(config api.AppConfig) api.AppConfig { } } + // JA4SENTINEL_PACKET_BUFFER_SIZE + if val := os.Getenv("JA4SENTINEL_PACKET_BUFFER_SIZE"); val != "" { + if size, err := strconv.Atoi(val); err == nil && size > 0 { + config.Core.PacketBufferSize = size + } + } + return config } @@ -144,6 +151,10 @@ func mergeConfigs(base, override api.AppConfig) api.AppConfig { result.Core.FlowTimeoutSec = override.Core.FlowTimeoutSec } + if override.Core.PacketBufferSize > 0 { + result.Core.PacketBufferSize = override.Core.PacketBufferSize + } + if len(override.Outputs) > 0 { result.Outputs = override.Outputs }