feat: add persistence and audit trails

This commit is contained in:
truetype committed 2026-02-05 11:07:20 +01:00
1 parent d381c02946
commit 2f2e9ab3e3
9 files changed
+633 -151

No files matched your search

+30 -2
View File
@@ -4,11 +4,14 @@ import shlex
import socket
import subprocess
import time
from dataclasses import dataclass
from dataclasses import asdict, dataclass
from typing import Iterable, List, Optional
import psutil
from app.policy import TunnelPolicy
from app.storage import Storage
@dataclass
class ServiceRecord:
@@ -20,13 +23,22 @@ class ServiceRecord:
command: Optional[str]
container: Optional[str]
local_address: str
allowed: bool = True
policy_reason: Optional[str] = None
class PortScanner:
def __init__(self, cache_ttl: float = 2.0) -> None:
def __init__(
self,
cache_ttl: float = 2.0,
policy: TunnelPolicy | None = None,
storage: Storage | None = None,
) -> None:
self._cache_ttl = cache_ttl
self._last_scan = 0.0
self._cache: List[ServiceRecord] = []
self._policy = policy
self._storage = storage
def scan(self) -> List[ServiceRecord]:
now = time.monotonic()
@@ -68,6 +80,10 @@ class PortScanner:
process_command = _format_commandline(raw_command)
local_address = f"{conn.laddr.ip}:{conn.laddr.port}"
container = _container_name_for_pid(pid, container_names) if pid else None
allowed = True
reason: Optional[str] = None
if self._policy:
allowed, reason = self._policy.is_port_allowed(port)
results.append(
ServiceRecord(
@@ -79,11 +95,23 @@ class PortScanner:
command=process_command,
container=container,
local_address=local_address,
allowed=allowed,
policy_reason=reason,
)
)
self._persist_services(results)
return results
def _persist_services(self, records: List[ServiceRecord]) -> None:
if not self._storage:
return
payload = [asdict(record) for record in records]
try:
self._storage.record_services(payload)
except Exception:
pass
def _protocol_for_conn(sock_type: int) -> str:
if sock_type == socket.SOCK_STREAM: