v1.1.11: Fix exclude_source_ips config loading and debug logging

Major fixes:
- Add exclude_source_ips to mergeConfigs() - config file values now properly loaded
- Add validation for exclude_source_ips (IP/CIDR format validation)
- Remove JA4SENTINEL_LOG_LEVEL env var from systemd service
- Config file log_level now respected without env override

Debug logging improvements:
- Log IP filter entries at startup (debug mode)
- Track filtered packet count with atomic counter
- Display filter statistics at shutdown via GetFilterStats()
- New debug logs in tlsparse component

Testing:
- Add 6 new unit tests for exclude_source_ips and log_level config loading
- Test mergeConfigs() behavior with empty/override values
- Test validation of invalid IPs and CIDR ranges

Documentation:
- Update architecture.yml with ipfilter module
- Document config loading priority and notes
- Update api.Config fields (LocalIPs, ExcludeSourceIPs, LogLevel)

Files changed:
- internal/config/loader.go (merge, validation, helpers)
- internal/config/loader_test.go (6 new tests)
- internal/tlsparse/parser.go (GetFilterStats, counter)
- cmd/ja4sentinel/main.go (debug logging)
- packaging/systemd/ja4sentinel.service (remove env var)
- architecture.yml (ipfilter module, config_loading section)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
toto
2026-03-04 15:55:00 +01:00
parent 952701d4da
commit bd45344d19
7 changed files with 426 additions and 7 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt"
"strings"
"sync"
"sync/atomic"
"time"
"ja4sentinel/api"
@ -65,6 +66,7 @@ type ParserImpl struct {
maxTrackedFlows int
maxHelloBufferBytes int
sourceIPFilter *ipfilter.Filter
filteredCount uint64 // Counter for filtered packets (debug)
}
// NewParser creates a new TLS parser with connection state tracking
@ -98,9 +100,11 @@ func NewParserWithTimeoutAndFilter(timeout time.Duration, excludeSourceIPs []str
flowTimeout: timeout,
cleanupDone: make(chan struct{}),
cleanupClose: make(chan struct{}),
closeOnce: sync.Once{},
maxTrackedFlows: DefaultMaxTrackedFlows,
maxHelloBufferBytes: DefaultMaxHelloBufferBytes,
sourceIPFilter: filter,
filteredCount: 0,
}
go p.cleanupLoop()
return p
@ -243,6 +247,7 @@ func (p *ParserImpl) Process(pkt api.RawPacket) (*api.TLSClientHello, error) {
// Check if source IP should be excluded
if p.sourceIPFilter != nil && p.sourceIPFilter.ShouldExclude(srcIP) {
atomic.AddUint64(&p.filteredCount, 1)
return nil, nil // Source IP is excluded
}
@ -406,6 +411,14 @@ func (p *ParserImpl) getOrCreateFlow(key string, srcIP string, srcPort uint16, d
return flow
}
// GetFilterStats returns statistics about the IP filter (for debug/monitoring)
func (p *ParserImpl) GetFilterStats() (filteredCount uint64, hasFilter bool) {
if p.sourceIPFilter == nil {
return 0, false
}
return atomic.LoadUint64(&p.filteredCount), true
}
// Close cleans up the parser and stops background goroutines
func (p *ParserImpl) Close() error {
p.closeOnce.Do(func() {