Refactor monolith utils into domain modules and update docs

This commit is contained in:
zwitschi committed 2026-08-03 17:01:36 +02:00
1 parent 970e1b5eed
commit bbf07dec5a
11 files changed
+972 -54

No files matched your search

+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env python3
"""Flagging rules for the intrusion-detection system.
Detection functions that identify hostile IPs based on aggregated stats.
"""
from __future__ import annotations
import bad_patterns
from models import IPStats
def flag_scanners(stats: dict[str, IPStats], min_errors: int = 5,
min_ratio: float = 0.5) -> dict[str, IPStats]:
"""IPs with many errors AND a high error ratio."""
return {
ip: s for ip, s in stats.items()
if s.errors >= min_errors and s.error_ratio >= min_ratio
}
def flag_denied_only(stats: dict[str, IPStats],
min_denied: int = 1) -> dict[str, IPStats]:
"""IPs that only ever hit denied paths and never authenticated."""
return {
ip: s for ip, s in stats.items()
if s.denied >= min_denied and not s.authenticated
}
def flag_malicious_patterns(stats: dict[str, IPStats],
min_severity: int = 2,
min_hits: int = 1) -> dict[str, IPStats]:
"""IPs with hits against malicious path patterns at or above severity threshold."""
return {
ip: s for ip, s in stats.items()
if s.malicious_hits >= min_hits and any(
bad_patterns.PATTERNS_BY_NAME[name].severity >= min_severity
for name in s.malicious_patterns
)
}
def by_total(stats: dict[str, IPStats]) -> list[IPStats]:
"""Stats sorted by request count, descending."""
return sorted(stats.values(), key=lambda s: (-s.total, s.ip))