事件与输出流水线
相关源文件
以下文件被用作生成此维基页面的上下文:
- docs/agent/output-pipeline-refactor-taskbook.md
- docs/agent/output-pipeline.md
- internal/output/writers/factory.go
- internal/output/writers/pipeline_test.go
- internal/probe/base/handlers/keylog_handler.go
- internal/probe/base/handlers/keylog_handler_test.go
- internal/probe/gnutls/config.go
- internal/probe/gnutls/config_test.go
- internal/probe/gnutls/event.go
- internal/probe/gnutls/event_masterkey.go
- internal/probe/gnutls/event_packet.go
- pkg/event_processor/base_event.go
- pkg/event_processor/http_request.go
- pkg/event_processor/http_response.go
- pkg/event_processor/iparser.go
- pkg/event_processor/iworker.go
- pkg/event_processor/processor.go
- pkg/event_processor/processor_test.go
- test/e2e/fixtures/ecaptureq_assert/main.go
目的与范围
本页面提供了 eCapture 核心 TLS 事件与输出流水线的深度架构与实现级追踪。它涵盖了捕获的 OpenSSL/BoringSSL、GoTLS 和 GnuTLS 事件的完整生命周期——从内核态 eBPF ring buffer 提取开始,经过用户态解码 (BaseEvent.Decode) pkg/event_processor/base_event.go:89-120,通过 EventProcessor 进行异步分发 pkg/event_processor/processor.go:70-93,在 eventWorker 中进行工作线程聚合 pkg/event_processor/iworker.go:69-88,由处理器(Handler)进行处理(Text、Keylog 和 Pcapng 模式),通过 ByteSink 进行原始传输路由 docs/agent/output-pipeline.md:33-42,以及向类型化的 eCaptureQ 通道进行附加发布 docs/agent/output-pipeline.md:57-59。
1. 事件解码与异步分发
当 eBPF 探针捕获 TLS 明文或主密钥(master secrets)时,原始字节缓冲区通过 Perf/Ring 缓冲区从内核态推送到用户态。事件处理流水线将这些原始字节数组转换为结构化的领域事件,并将其路由到适当的工作协程。
关键组件与数据结构
BaseEvent:实现原始 ring buffer 负载的基础解码逻辑,通过二进制小端读取 pkg/event_processor/base_event.go:89-120 提取DataType、Timestamp、Pid、Tid、DataLen、Comm、Fd和Version等字段 pkg/event_processor/base_event.go:76-87。EventProcessor:管理传入事件、工作路由队列 (workerQueue) 和清理任务 (destroyConn) pkg/event_processor/processor.go:27-53。Serve()循环持续从incoming读取数据,分发事件,并通过drain()管理退出时的排空操作 pkg/event_processor/processor.go:70-115。eventWorker:每个唯一的连接或流(由 UUID 标识)都会被分配一个eventWorker协程 pkg/event_processor/iworker.go:69-99。它负责聚合负载直至达到截断限制或空闲超时,并应用格式解析器,如 HTTP 请求/响应检测器 pkg/event_processor/iparser.go:85-115。
Sources: pkg/event_processor/base_event.go:76-120, pkg/event_processor/processor.go:27-115, pkg/event_processor/iworker.go:69-99, pkg/event_processor/iparser.go:85-115
2. 表现形式处理器与路由
一旦事件被工作线程处理,它们将根据当前激活的捕获模式(Text、Keylog 或 Pcapng)被分类并路由到相应的表现形式处理器(Representation Handlers)。
处理器机制
- 文本处理器与解析器 (Text Handler & Parsers):将原始负载缓冲区格式化为可读的 UTF-8 字符串或十六进制转储 (
BaseEvent.String()/StringHex()) pkg/event_processor/base_event.go:134-167,并使用注册的解析器(HTTPRequest、HTTPResponse)检查更高层协议 pkg/event_processor/http_request.go:28-45, pkg/event_processor/http_response.go:28-37。 KeylogHandler:拦截 TLS 主密钥、客户端随机数(client randoms)和流量密钥(MasterSecretEvent、GoTLSMasterSecretEvent、DirectTrafficSecretEvent)internal/probe/base/handlers/keylog_handler.go:37-79。它使用已见密钥缓存进行去重,并以标准 NSS Key Log 格式格式化记录 internal/probe/base/handlers/keylog_handler.go:84-106。- Pcapng 会话与处理器:在同步的会话流水线中管理数据包块以及嵌入的解密密钥块 (DSB) docs/agent/output-pipeline.md:33-55。
Sources: pkg/event_processor/base_event.go:134-167, pkg/event_processor/iparser.go:117-162, pkg/event_processor/http_request.go:28-45, pkg/event_processor/http_response.go:28-37, internal/probe/base/handlers/keylog_handler.go:37-106, docs/agent/output-pipeline.md:33-55
3. ByteSink 目标与传输路由
原始传输通过 ByteSink 接口与格式表现形式解耦 docs/agent/output-pipeline.md:33-42。这使得文本、密钥日志和 pcapng 编码器能够通过统一的工厂无缝地写入各种底层目标 docs/agent/output-pipeline.md:95-114。
ByteSink 契约
type ByteSink interface {
io.Writer
Name() string
Flush() error
Close() error
}Sources: docs/agent/output-pipeline.md:33-42
支持的传输目标
- 标准输出 / 文件 (Stdout / File):直接流或文件支持的存储(支持文件 URI,并为文本/密钥日志流提供可选的日志轮转功能)docs/agent/output-pipeline.md:79-83。
- TCP 接收端 (TCP Sinks):通过网络套接字传输的有序原始字节流 (
tcp://host:port) docs/agent/output-pipeline.md:44-48。 - WebSocket 接收端 (WebSocket Sinks):有序的二进制帧 WebSocket 流 (
ws://或wss://),接收者按到达顺序拼接帧负载 docs/agent/output-pipeline.md:44-48。
Sources: docs/agent/output-pipeline.md:33-55, internal/output/writers/pipeline_test.go:31-104
4. 附加的 eCaptureQ 发布
除了向主要的 ByteSink 目标写入原始字节流外,eCaptureQ 还作为一个附加的、类型化的事件发布者运行 docs/agent/output-pipeline.md:57-65。
关注点分离
- 隔离性:捕获的负载和敏感的 TLS 密钥与操作日志严格分区,永远不会进入
--logaddr或PROCESS_LOG通道 docs/agent/output-pipeline.md:27-30。 - 协议:eCaptureQ 消息被序列化为二进制 protobuf
LogEntry结构,包含元数据、时间戳、进程信息和网络元组,而不会对原始接收端字节进行反向解析 docs/agent/output-pipeline.md:105-118。
Sources: docs/agent/output-pipeline.md:27-30, docs/agent/output-pipeline.md:105-118