Categorize audit log by threat level with filtering UI
This commit is contained in:
@@ -60,11 +60,44 @@ def system_stats():
|
||||
def audit_log(lines: int = Query(100, le=500)):
|
||||
log_path = os.path.join(VOLUME_ROOT, "docker/nas-dashboard/audit.log")
|
||||
if not os.path.exists(log_path):
|
||||
return {"lines": []}
|
||||
return {"entries": []}
|
||||
with open(log_path, "rb") as f:
|
||||
f.seek(0, 2)
|
||||
size = f.tell()
|
||||
buf = min(size, lines * 200)
|
||||
f.seek(max(0, size - buf))
|
||||
data = f.read().decode(errors="replace").splitlines()
|
||||
return {"lines": data[-lines:]}
|
||||
raw = f.read().decode(errors="replace").splitlines()[-lines:]
|
||||
|
||||
entries = []
|
||||
for line in raw:
|
||||
parts = line.split(" ", 6)
|
||||
if len(parts) < 7:
|
||||
continue
|
||||
ts, ip, user, method, path, status_str, dur = parts
|
||||
status = int(status_str) if status_str.isdigit() else 0
|
||||
level = _classify(method, path, status, user)
|
||||
if level == "noise":
|
||||
continue
|
||||
entries.append({"ts": ts, "ip": ip, "user": user, "method": method, "path": path, "status": status, "duration": dur, "level": level})
|
||||
return {"entries": entries}
|
||||
|
||||
|
||||
def _classify(method, path, status, user):
|
||||
# High — failed auth attempts
|
||||
if "/auth/login" in path and status in (401, 403):
|
||||
return "high"
|
||||
if "/auth/passkey/login/verify" in path and status == 400:
|
||||
return "high"
|
||||
# Medium — 403/404 on sensitive paths, or any 5xx
|
||||
if status >= 500:
|
||||
return "medium"
|
||||
if status == 403 and "/files/" in path:
|
||||
return "medium"
|
||||
# Low — normal auth activity
|
||||
if "/auth/" in path and status == 200:
|
||||
return "low"
|
||||
# Noise — health checks, static assets
|
||||
if path in ("/api/health",) or path.startswith("/assets/") or path == "/favicon.ico" or path == "/":
|
||||
return "noise"
|
||||
# Info — everything else
|
||||
return "info"
|
||||
|
||||
Reference in New Issue
Block a user