Skip to content

Three-layer Architecture

Relevant source files

The following files were used as context for generating this wiki page:

eCapture is designed with a clear separation of concerns, organized into a three-layer architecture. This structure ensures high performance in the kernel, a robust and extensible control plane in userspace, and a flexible user interface for configuration and data consumption.

Architectural Overview

The following diagram illustrates the relationship between the three layers and the data flow from a kernel hook to the final output.

System Architecture and Data Flow

Sources:


1. eBPF Kernel Layer

The kernel layer consists of C programs compiled into eBPF bytecode. These programs are the "eyes" of eCapture, executing within the Linux kernel context to intercept data at the source.

Key Components

  • Probes: Programs attached to specific kernel or userspace symbols.
    • Uprobes: Used for capturing plaintext from libraries like OpenSSL, GnuTLS, and GoTLS by hooking functions like SSL_read and SSL_write kern/openssl.h:163-190.
    • TC (Traffic Control): Used for pcap mode to capture raw network packets kern/tc.h:136-150.
    • Kprobes: Used for system-level auditing, such as shell command execution.
  • Maps: Shared memory structures used to communicate with userspace and store temporary state.

CO-RE vs. Non-CO-RE Loading

eCapture supports two loading mechanisms to ensure compatibility across different kernel versions:

FeatureCO-RE (Compile Once – Run Everywhere)Non-CO-RE (Legacy)
RequirementKernel with BTF (/sys/kernel/btf/vmlinux)Kernel Headers for specific version
ImplementationUses vmlinux.h and bpf_core_read kern/ecapture.h:18-26Uses system headers and fixed offsets kern/ecapture.h:27-88
Build Targetmake (Default)make nocore variables.mk:241-250

Sources:


2. Userspace Probe Layer

The Userspace Probe Layer acts as the control plane. It is responsible for loading eBPF programs, managing their lifecycle, and processing the raw data received from the kernel.

Code Entity Mapping

The following diagram maps the logical components of the probe layer to their specific implementations in the Go codebase.

Lifecycle Management

The BaseProbe provides a template-method pattern for all modules. It handles:

  1. Configuration Validation: Ensuring paths and filters are correct.
  2. eBPF Loading: Selecting the correct .o bytecode based on the kernel's BTF support.
  3. Attachment: Linking uprobes to the correct library offsets (e.g., finding libssl.so and hooking SSL_write).
  4. Event Dispatching: Reading from the perf buffer and sending raw bytes to the EventProcessor.

Sources:


3. CLI and Output Layer

The top layer manages user interaction and data formatting. It translates CLI flags into probe configurations and formats intercepted data for consumption.

Components

  • Cobra CLI: Located in cli/cmd/, it defines the subcommands (e.g., tls, gotls, mysqld) and parses flags into a Configuration object main.go:6-11.
  • Writers: Located in internal/output/, these handle the destination of the data, such as StdoutWriter, FileWriter, or the eCaptureQ WebSocket pusher CHANGELOG.md:116-119.
  • Encoders: Transform internal event structures into specific formats:
    • Text: Human-readable console output.
    • JSON: Structured data for integration.
    • Pcapng: Wireshark-compatible packet captures CHANGELOG.md:117-118.

Data Path Trace

  1. Hook: SSL_write is called in a target process.
  2. Kernel: The eBPF uprobe kern/openssl.h:163 triggers, reads the buffer via bpf_probe_read_user, and pushes a ssl_data_event_t kern/openssl.h:28-39 to the tls_events map.
  3. Userspace: The Probe module's dispatcher reads the event from the perf buffer.
  4. Processor: The EventProcessor identifies the protocol (e.g., HTTP/2) and associates it with a connection UUID.
  5. Output: The Writer sends the formatted string (Text/JSON) to the user's terminal or a file.

Sources:

Three-layer Architecture has loaded