feature: add source IP exclusion with CIDR support
Features:
- Add exclude_source_ips configuration option
- Support single IPs (192.168.1.1) and CIDR ranges (10.0.0.0/8)
- Filter packets in parser before TLS processing
- Log exclusion configuration at startup
- New ipfilter package with IP/CIDR matching
- Unit tests for ipfilter package
Configuration example:
exclude_source_ips:
- "10.0.0.0/8" # Exclude private network
- "192.168.1.1" # Exclude specific IP
- "172.16.0.0/12" # Exclude another range
- "2001:db8::/32" # IPv6 support
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"ja4sentinel/api"
|
||||
"ja4sentinel/internal/ipfilter"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
@ -63,15 +64,35 @@ type ParserImpl struct {
|
||||
closeOnce sync.Once
|
||||
maxTrackedFlows int
|
||||
maxHelloBufferBytes int
|
||||
sourceIPFilter *ipfilter.Filter
|
||||
}
|
||||
|
||||
// NewParser creates a new TLS parser with connection state tracking
|
||||
func NewParser() *ParserImpl {
|
||||
return NewParserWithTimeout(30 * time.Second)
|
||||
return NewParserWithTimeoutAndFilter(30*time.Second, nil)
|
||||
}
|
||||
|
||||
// NewParserWithTimeout creates a new TLS parser with a custom flow timeout
|
||||
func NewParserWithTimeout(timeout time.Duration) *ParserImpl {
|
||||
return NewParserWithTimeoutAndFilter(timeout, nil)
|
||||
}
|
||||
|
||||
// NewParserWithTimeoutAndFilter creates a new TLS parser with timeout and source IP filter
|
||||
func NewParserWithTimeoutAndFilter(timeout time.Duration, excludeSourceIPs []string) *ParserImpl {
|
||||
var filter *ipfilter.Filter
|
||||
if len(excludeSourceIPs) > 0 {
|
||||
f, err := ipfilter.New(excludeSourceIPs)
|
||||
if err != nil {
|
||||
// Log error but continue without filter
|
||||
filter = nil
|
||||
} else {
|
||||
filter = f
|
||||
ips, networks := filter.Count()
|
||||
_ = ips
|
||||
_ = networks
|
||||
}
|
||||
}
|
||||
|
||||
p := &ParserImpl{
|
||||
flows: make(map[string]*ConnectionFlow),
|
||||
flowTimeout: timeout,
|
||||
@ -79,6 +100,7 @@ func NewParserWithTimeout(timeout time.Duration) *ParserImpl {
|
||||
cleanupClose: make(chan struct{}),
|
||||
maxTrackedFlows: DefaultMaxTrackedFlows,
|
||||
maxHelloBufferBytes: DefaultMaxHelloBufferBytes,
|
||||
sourceIPFilter: filter,
|
||||
}
|
||||
go p.cleanupLoop()
|
||||
return p
|
||||
@ -219,6 +241,11 @@ func (p *ParserImpl) Process(pkt api.RawPacket) (*api.TLSClientHello, error) {
|
||||
srcPort = uint16(tcp.SrcPort)
|
||||
dstPort = uint16(tcp.DstPort)
|
||||
|
||||
// Check if source IP should be excluded
|
||||
if p.sourceIPFilter != nil && p.sourceIPFilter.ShouldExclude(srcIP) {
|
||||
return nil, nil // Source IP is excluded
|
||||
}
|
||||
|
||||
// Get TCP payload (TLS data)
|
||||
payload := tcp.Payload
|
||||
if len(payload) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user