add baseline and sqlite

This commit is contained in:
larssand
2026-06-21 15:04:23 +02:00
parent 395a86e157
commit d41d318134
8 changed files with 144 additions and 5 deletions

View File

@@ -74,7 +74,10 @@ def _rate_per_minute(events: list[LogEvent]) -> tuple[float | None, float]:
return len(timestamps) * 60 / max(1.0, duration_seconds), duration_seconds
def detect_source_anomalies(events: list[LogEvent], *, limit: int = 20) -> list[AnomalyFinding]:
def detect_source_anomalies(
events: list[LogEvent], *, limit: int = 20, baselines: dict[str, dict[str, float | int]] | None = None
) -> list[AnomalyFinding]:
baselines = baselines or {}
by_src: dict[str, list[LogEvent]] = defaultdict(list)
for event in events:
if event.src_ip:
@@ -137,6 +140,12 @@ def detect_source_anomalies(events: list[LogEvent], *, limit: int = 20) -> list[
points = min(25, 10 + int(rate_z * 5))
score += points
reasons.append(f"unusually high log rate ({event_rate:.1f} events/min, z={rate_z:.1f})")
baseline = baselines.get(src_ip)
if baseline:
historical_z = (event_rate - float(baseline["event_rate_mean"])) / float(baseline["event_rate_stddev"])
if historical_z >= 3:
score += min(25, 10 + int(historical_z * 3))
reasons.append(f"log rate exceeds its {baseline['samples']}-window baseline (z={historical_z:.1f})")
dst_z = (distinct_dst - avg_dst) / std_dst
if distinct_dst >= 10 and dst_z >= 2:
@@ -155,6 +164,13 @@ def detect_source_anomalies(events: list[LogEvent], *, limit: int = 20) -> list[
points = min(15, 5 + int(hitcount_z * 3))
score += points
reasons.append(f"unusually high policy hitcount ({total_hitcount}, max event value {max_hitcount})")
if event_rate is not None and observed_duration > 0 and src_ip in baselines:
hit_rate = total_hitcount * 60 / max(1.0, observed_duration)
baseline = baselines[src_ip]
historical_z = (hit_rate - float(baseline["hitcount_rate_mean"])) / float(baseline["hitcount_rate_stddev"])
if total_hitcount >= 10 and historical_z >= 3:
score += min(15, 5 + int(historical_z * 2))
reasons.append(f"hitcount rate exceeds its historical baseline (z={historical_z:.1f})")
if event_count >= 5:
deny_rate = deny_count / event_count