Three-layer Architecture
Relevant source files
The following files were used as context for generating this wiki page:
- CHANGELOG.md
- README.md
- builder/Dockerfile
- builder/init_env.sh
- functions.mk
- internal/config/base_config.go
- internal/domain/configuration.go
- internal/probe/base/base_probe.go
- internal/probe/gotls/gotls_probe.go
- internal/probe/openssl/config.go
- internal/probe/openssl/config_test.go
- kern/boringssl_masterkey.h
- kern/bpf/arm64/vmlinux.h
- kern/bpf/arm64/vmlinux_614.h
- kern/bpf/bpf_core_read.h
- kern/bpf/bpf_helper_defs.h
- kern/bpf/bpf_helpers.h
- kern/bpf/bpf_tracing.h
- kern/bpf/x86/vmlinux.h
- kern/bpf/x86/vmlinux_614.h
- kern/common.h
- kern/core_fixes.bpf.h
- kern/ecapture.h
- kern/openssl.h
- kern/openssl_masterkey.h
- kern/openssl_masterkey_3.0.h
- kern/tc.h
- main.go
- variables.mk
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_readandSSL_writekern/openssl.h:163-190. - TC (Traffic Control): Used for
pcapmode to capture raw network packets kern/tc.h:136-150. - Kprobes: Used for system-level auditing, such as shell command execution.
- Uprobes: Used for capturing plaintext from libraries like OpenSSL, GnuTLS, and GoTLS by hooking functions like
- Maps: Shared memory structures used to communicate with userspace and store temporary state.
perf_event_array: Used for high-speed event streaming to userspace kern/openssl.h:79-92.hash_maps: Used to track context between function entry and exit (e.g.,active_ssl_read_args_map) kern/openssl.h:97-102.percpu_array: Used as a "heap" to bypass the 512-byte stack limit kern/openssl.h:113-118.
CO-RE vs. Non-CO-RE Loading
eCapture supports two loading mechanisms to ensure compatibility across different kernel versions:
| Feature | CO-RE (Compile Once – Run Everywhere) | Non-CO-RE (Legacy) |
|---|---|---|
| Requirement | Kernel with BTF (/sys/kernel/btf/vmlinux) | Kernel Headers for specific version |
| Implementation | Uses vmlinux.h and bpf_core_read kern/ecapture.h:18-26 | Uses system headers and fixed offsets kern/ecapture.h:27-88 |
| Build Target | make (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:
- Configuration Validation: Ensuring paths and filters are correct.
- eBPF Loading: Selecting the correct
.obytecode based on the kernel's BTF support. - Attachment: Linking uprobes to the correct library offsets (e.g., finding
libssl.soand hookingSSL_write). - Event Dispatching: Reading from the
perfbuffer and sending raw bytes to theEventProcessor.
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 aConfigurationobject main.go:6-11. - Writers: Located in
internal/output/, these handle the destination of the data, such asStdoutWriter,FileWriter, or theeCaptureQWebSocket 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
- Hook:
SSL_writeis called in a target process. - Kernel: The eBPF uprobe kern/openssl.h:163 triggers, reads the buffer via
bpf_probe_read_user, and pushes assl_data_event_tkern/openssl.h:28-39 to thetls_eventsmap. - Userspace: The
Probemodule's dispatcher reads the event from the perf buffer. - Processor: The
EventProcessoridentifies the protocol (e.g., HTTP/2) and associates it with a connection UUID. - Output: The
Writersends the formatted string (Text/JSON) to the user's terminal or a file.
Sources: