Skip to main content

Architecture

Netra has two workloads: a controller (netrad) that serves the API/UI and holds desired configuration, and a node agent (netra-agent) that owns the eBPF programs and maps on each Linux node.

Browser / netractl / netra-mcp
|
v
+---------------------+
| netrad |
| API + UI + state |
+----------+----------+
|
desired config | node reports
v
+------------------------------------------------+
| netra-agent on every Linux node |
| |
| cgroup skb + socket hooks optional TCX |
| | optional XDP |
| +------ Netra maps/ring buffer -------+ |
| /sys/fs/bpf/netra |
+------------------------------------------------+

optional optional
+-------------------+ +-------------------+
| Kubernetes Cilium | | Hubble Relay |
| NetworkPolicy API | | Observer.GetFlows |
+-------------------+ +-------------------+

The agent owns its own programs and maps below /sys/fs/bpf/netra and attaches to Linux cgroup v2 for CNI-independent workload coverage — it does not touch cilium_host, Cilium's own maps, or assume any particular CNI is present. Cilium and Hubble are read as optional data sources, never a dependency.

Operators inspect desired map contents (deny/allow/rate/policy) with netractl ebpf maps / GET /api/v1/ebpf/maps — see the repo doc ebpf-maps.md. That is the control-plane inventory agents reconcile; it is not a raw kernel bpftool dump.

Netra’s place next to PacketWolf (suite counterparts, not a wired pipeline) is documented in Suite placement (PacketWolf).

Repository layout​

cmd/netrad/ controller/API/UI server
cmd/netractl/ operator CLI
cmd/netra-agent/ standalone privileged node agent
cmd/netra-doctor/ read-only host readiness preflight
cmd/netra-mcp/ MCP server: controller API as stdio tools + prompts + resources for AI agents
cmd/netra-ci-*/ CI helpers: capture client (the browser's side of a capture), AF_PACKET feeder, fake OIDC provider
internal/agent/ BPF loading, hook attachment and reporting
internal/doctor/ host readiness checks used by netra-doctor
internal/observability/ standalone eBPF summaries and workload topology
internal/health/ TCP/DNS/connect health scoring and anomaly signals
internal/alert/ anomaly poller, notify fan-out, opt-in auto-capture
internal/capture/ frame encode + auto-capture PCAP artifact store
internal/ai/ heuristic briefs + optional OpenAI-compatible rewrite
internal/tcpevents/ TCP retransmit / reset / state-change tracepoints
internal/dropinfo/ per-connection kernel drop attribution (needs BTF)
internal/listenq/ accept-queue depth per listener through inet_diag
internal/l7sample/ sampled protocol observation (Redis, SQL, Kafka, HTTP/2, gRPC)
internal/sslprobe/ opt-in TLS plaintext sampling through OpenSSL uprobes
internal/mapscan/ cheap batched scans of BPF hash maps
internal/mtls/ optional agent-to-controller mutual TLS
internal/oidcauth/ OIDC login and roles
internal/otlppush/, internal/lokipush/ OTLP and Loki push sinks
bpf/netra_tc.c the core eBPF datapath
bpf/netra_*.c optional sensors, each its own object (capture, tlsfp, edge_intel, tcpevents, dropinfo, l7sample, ssl)
scripts/ci-*.sh one script per CI job; see How Netra is tested

Hook model​

HookDefaultPurpose
cgroup_skb/ingress✅CNI-independent descendant workload ingress observation/control
cgroup_skb/egress✅CNI-independent descendant workload egress observation/control
cgroup/connect4, connect6✅new TCP socket process/UID context and deny
cgroup/sendmsg4, sendmsg6✅UDP send process/UID context and deny
sockops✅TCP connection lifecycle, RTT, retransmit/RTO and connection counters
raw kfree_skb tracepointoptionalnode-level kernel skb drop-reason counters when the host exposes a reason field
kfree_skb tracepoint (BTF)optional, autoper-connection drop attribution: tuple, reason, dropping function
TCP tracepointsoptional, autoretransmit, reset and state-change events with the flow tuple
cgroup_skb sampleroptional, offfirst bytes of packets on configured ports, parsed in the agent into protocol operation counts
OpenSSL uprobesoptional, offTLS plaintext sampling for HTTPS, limited to allowlisted processes
TCX ingress/egressoptionalinterface-level visibility/control on selected interfaces
XDP ingressoptionalearliest ingress CIDR/port drop on selected interfaces

The default agent runs cgroup-only, plus the auto sensors that need nothing you have not already granted. TCX and XDP are opt-in, attached only to interfaces you explicitly list. See Optional kernel sensors for what each optional sensor needs and what it can and cannot see.

:::caution Scope warning scopeMode=all attaches enforcement broadly to descendant root-cgroup traffic and can affect Kubernetes workloads plus host/system services. Use scopeMode=selected to enforce only resolved workload cgroups after previewing the matching Pods — traffic whose workload identity can't be resolved fails open in selected mode, and TCX/XDP remain observe-only there. :::

Observe-first, and the enforcement lease​

Every custom enforcement rule in Netra — deny lists, the DDoS shield, NetPol allow/default-deny — is gated by a time-limited lease, not a permanent switch. The datapath returns to observe automatically when:

  • the lease expires,
  • the agent can't refresh state from the controller,
  • the controller restarts, or
  • HA leadership changes.

A leader transition or controller restart never resurrects an old enforcement lease. This is the single property every other safety guarantee in the product builds on: enforcement is something you deliberately, temporarily opt into for an incident, not a standing configuration that can silently persist past its intended window. See Security for the full threat model.