tc test
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 10s

This commit is contained in:
2026-03-07 16:36:24 +01:00
parent f55e899fc5
commit 0c69daf229
13 changed files with 459 additions and 609 deletions

View File

@@ -1,7 +1,8 @@
"""Manage the eBPF telemetry subprocess used for bridge direction and verdict events."""
"""Manage the eBPF/tc telemetry subprocess used for bridge packet capture and verdict events."""
from __future__ import annotations
import base64
import json
import logging
import os
@@ -19,7 +20,7 @@ logger = logging.getLogger("bridge_telemetry")
class BridgeTelemetryManager:
"""Run a single eBPF collector process for the active sniffed interfaces."""
"""Run one tc/eBPF collector for the currently sniffed bridge interfaces."""
def __init__(self) -> None:
self._interfaces: set[str] = set()
@@ -28,7 +29,7 @@ class BridgeTelemetryManager:
self._lock = threading.Lock()
def update_interfaces(self, interfaces: Iterable[str]) -> None:
"""Restart the collector when the active interface set changes."""
"""Restart the collector when the active bridge interface set changes."""
normalized = {iface.strip() for iface in interfaces if iface and iface.strip()}
with self._lock:
if normalized == self._interfaces:
@@ -58,7 +59,14 @@ class BridgeTelemetryManager:
existing_pythonpath = env.get("PYTHONPATH", "")
env["PYTHONPATH"] = backend_root if not existing_pythonpath else f"{backend_root}:{existing_pythonpath}"
cmd = [python_bin, str(helper), "--ifaces", ",".join(sorted(self._interfaces))]
cmd = [
python_bin,
str(helper),
"--ifaces",
",".join(sorted(self._interfaces)),
"--build-dir",
settings.bridge_bpf_build_dir,
]
logger.info("Starting bridge telemetry collector for interfaces=%s", sorted(self._interfaces))
try:
self._process = subprocess.Popen(
@@ -100,6 +108,31 @@ class BridgeTelemetryManager:
if reader is not None and reader.is_alive():
reader.join(timeout=settings.telemetry_reader_join_timeout_seconds)
def _handle_ingress_packet(self, event: dict[str, object]) -> None:
raw_b64 = event.pop("raw_b64", None)
if not isinstance(raw_b64, str) or not raw_b64:
return
try:
packet_bytes = base64.b64decode(raw_b64)
except Exception:
logger.exception("Failed to decode ingress raw packet")
return
capture_metadata = {
"capture_source": "tc_ingress_raw",
"packet_id": event.get("packet_id"),
"skb_mark": event.get("skb_mark"),
"capture_mode": "tc_ingress",
}
try:
from src.network_sniffer import parse_packet_bytes
parse_packet_bytes(packet_bytes, str(event.get("iface")), capture_metadata=capture_metadata)
except Exception:
logger.exception("Failed to process ingress raw packet event")
def _read_loop(self, process: subprocess.Popen[str]) -> None:
stdout = process.stdout
if stdout is None:
@@ -119,6 +152,9 @@ class BridgeTelemetryManager:
logger.info("bridge-telemetry: %s", event)
continue
if event.get("event_type") == "ingress":
self._handle_ingress_packet(event)
try:
packet_tracker.observe_telemetry(event)
except Exception: