资讯动态

逐步测试 eCapture ecaptureq WebSocket 客户端:从构建、连接到实时 SSL/TLS 事件送达验证

发布时间:2026/9/14 16:13:55 来源:尧图企业网站定制
逐步测试 eCapture ecaptureq WebSocket 客户端从构建、连接到实时 SSL/TLS 事件送达验证【免费下载链接】ecaptureCapturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64.项目地址: https://gitcode.com/GitHub_Trending/ec/ecapture本文以仓库中的 ecaptureq 客户端测试指南 为主体完整给出 eCapture 事件转发服务ecaptureq WebSocket 服务器的端到端测试流程构建客户端、启动带--ecaptureq参数的 eCapture 服务器、验证端口监听、连接客户端并生成 HTTPS 流量、观察捕获事件并配套四类典型测试场景、故障排查方法与自动化 e2e 测试脚本。读完后你可以独立验证 eCapture 的 WebSocket 事件流是否正常工作并能把该协议集成进自己的系统。测试环境与前置条件按测试指南要求完整的测试环境需要满足Linux 系统内核 5.10eCapture 运行要求Root/sudo 权限Go 1.24 已安装客户端示例模块 go.mod 中声明go 1.24.3eCapture 二进制已构建完成。客户端示例是一个独立的 Go 模块其 go.mod 通过replace github.com/gojue/ecapture ../../指向仓库根目录因此构建客户端必须位于本仓库内以便复用 protobuf/gen/v1 中的 protobuf 生成代码。依赖的第三方库为golang.org/x/netwebsocket与google.golang.org/protobuf。测试涉及两个端口先分清它们的角色端口用途说明28257ecaptureq WebSocket 服务端口由--ecaptureqws://IP:28257/指定客户端连接此端口28256默认管理端口localhost测试指南提示Default management port is also started onlocalhost:28256用于运行时配置更新与事件转发无关第一步构建客户端进入客户端目录执行构建cd examples/ecaptureq_client go build -o ecaptureq_client main.go也可以在仓库根目录直接构建见 examples/ecaptureq_client/README.mdgo build -o ecaptureq_client ./examples/ecaptureq_client客户端源码 main.go 仅暴露两个命令行参数定义于 main.go#L40-L42-serverWebSocket 服务器 URL默认ws://127.0.0.1:28257/-verbose开启详细日志输出心跳heartbeat消息。第二步启动带 --ecaptureq 参数的 eCapture 服务器在第一个终端中用--ecaptureq参数启动 eCapture# Option A: 监听本机测试时最安全 sudo ./ecapture tls --ecaptureqws://127.0.0.1:28257/ # Option B: 监听指定网卡 IP sudo ./ecapture tls --ecaptureqws://192.168.1.100:28257/URL 格式有三条硬性注意事项原指南原文强调URL必须以/结尾trailing slashHOST 必须使用具体 IP如127.0.0.1或本机网卡 IP不要使用0.0.0.0它不生效。启动成功后eCapture 终端应出现类似输出2025-01-15T10:30:45Z INF AppNameeCapture(旁观者) 2025-01-15T10:30:45Z INF Listen for eCaptureQws://127.0.0.1:28257源码视角--ecaptureq 是如何生效的从源码结构看--ecaptureq是根命令的持久参数定义在 cli/cmd/root.go#L170rootCmd.PersistentFlags().StringVar(globalConf.EcaptureQ, ecaptureq, , listening server, waiting for clients to connect before sending events and logs; false: send directly to the remote server.)在runProbecli/cmd/root.go#L252-L296中当该参数非空时用url.Parse解析 URL取parsedURL.Host即IP:PORT创建ecaptureq.NewServer并异步Start()监听失败会打印eCaptureQ addr listen failed并以退出码 1 终止创建ecaptureQLogWritercli/cmd/ecaptureq.go#L22-L28与 zerolog 控制台输出组成MultiLevelWriter使 eCapture 自身的运行日志同时写入本地终端并推送到 WebSocket 服务创建ecaptureQEventWritercli/cmd/ecaptureq.go#L30-L36并通过probeConfig.SetEventWriter挂载到探针配置使捕获到的事件经该 Writer 进入 WebSocket 广播通道。底层的 HTTP/WS 服务在 pkg/util/ws/server.go#L38-L46通过http.NewServeMux把 WebSocket 处理器注册在根路径/上然后http.ListenAndServe(addr, mux)监听。这也解释了 URL 必须以/结尾、且 HOST 必须可被ListenAndServe解析为具体地址的原因。第三步验证服务端口已监听在另一个终端确认 28257 端口处于监听状态netstat -tlnp | grep 28257 # 期望看到 # tcp 0 0 127.0.0.1:28257 0.0.0.0:* LISTEN pid/ecapture如果没有该输出按指南依次检查eCapture 是否无报错启动URL 格式是否正确带尾部/是否误用了0.0.0.0。第四步连接客户端在第三个终端运行客户端cd examples/ecaptureq_client # 基本连接 ./ecaptureq_client -server ws://127.0.0.1:28257/ # 开启 verbose可看到心跳消息 ./ecaptureq_client -server ws://127.0.0.1:28257/ -verbose连接成功后会立即看到Connecting to eCapture WebSocket server at ws://127.0.0.1:28257/ Connected successfully! 2025-01-15T10:30:45Z INF AppNameeCapture(旁观者) 2025-01-15T10:30:45Z INF HomePagehttps://v2.ecapture.cc ...这段连接即见日志的行为由服务端实现保证pkg/ecaptureq/server.go 中的Server维护一个容量为LogBuffLen 128的日志环形缓冲见 server.go#L29。WriteLog在启动早期阶段只把日志追加进缓冲区客户端连接时handleWebSocket会先调用sendLogBuff把这些预存日志推给新客户端server.go#L65-L88因此即便 eCapture 先于客户端启动你也能在客户端终端看到启动时的 AppName、HomePage 等日志。客户端收到字节流后的处理流程在 main.go 中websocket.Message.Receive持续读包 →proto.Unmarshal解码为pb.LogEntry→ 按logEntry.LogType分派main.go#L77-L110。协议共有三类消息详见 pkg/ecaptureq/README.md 与 protobuf/proto/v1/ecaptureq.protolog_type枚举含义客户端处理0LOG_TYPE_HEARTBEAT心跳包仅在-verbose下打印Count、Timestamp、Message1LOG_TYPE_PROCESS_LOGeCapture 进程运行日志直接原样打印2LOG_TYPE_EVENT捕获的 SSL/TLS 事件格式化输出事件元数据 Payload第五步生成测试流量在第四个终端制造一些 HTTPS 流量curl https://www.baidu.com curl https://www.google.com wget https://www.github.com第六步观察捕获事件客户端终端应出现形如下的捕获事件事件字段对应pb.Event结构中的 uuid、pid、pname、src/dst ip:port、type、length、payload━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Captured Event ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ UUID: 12345_12345_curl_5_1_192.168.1.100:54870-180.101.49.44:443 PID: 12345 Process: curl Source: 192.168.1.100:54870 Destination: 180.101.49.44:443 Type: 1 Length: 104 bytes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Payload: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET / HTTP/1.1 Host: www.baidu.com Accept: */* User-Agent: curl/7.81.0 Base64 encoded: R0VUIC8gSFRUUC8xLjENCkhvc3Q6IHd3dy5iYWlkdS5jb20NCkFjY2VwdDogKi8qDQpVc2VyLUFnZW50OiBjdXJsLzcuODEuMA0KDQo ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━Payload 的展示策略值得注意main.go#L168-L198客户端先调用isPrintable判断字节中可打印字符32–126 及\n\r\t占比是否超过printableThreshold 0.9是则直接按文本输出否则调用printHexDump以每行 16 字节的十六进制 ASCII 格式输出最后统一附送 Base64 编码每 80 字符换行。因此上例中的GET / HTTP/1.1 ...是明文 HTTP 请求说明 eCapture 已在 SSL 库层拿到解密后的明文。事件在服务端的封装路径捕获层把原始数据交给ecaptureQEventWriter其Write最终调用Server.WriteEventpkg/ecaptureq/server.go#L107-L124将其包装为LogType LOG_TYPE_EVENT的LogEntryEvent payload 中填入原始字节与 Lengthprotobuf 编码后经 Hub 广播UUID、PID、源/目的地址等元数据则由上游事件分发链路在事件产生阶段填充客户端仅负责解码展示。四类典型测试场景原指南给出四个可复制的测试场景逐一继承如下。场景 1本机localhost连接# Terminal 1 sudo ./ecapture tls --ecaptureqws://127.0.0.1:28257/ # Terminal 2 ./ecaptureq_client -server ws://127.0.0.1:28257/ # Terminal 3 curl https://www.baidu.com场景 2跨机器网络连接# Terminal 1服务端机器IP 为 192.168.1.100 sudo ./ecapture tls --ecaptureqws://192.168.1.100:28257/ # Terminal 2客户端机器或同一台机器 ./ecaptureq_client -server ws://192.168.1.100:28257/ # Terminal 3 curl https://www.github.com该场景验证parsedURL.Host使用真实网卡 IP 时远端客户端可跨网络连入防火墙需放行 28257 端口。场景 3verbose 模式观察心跳# Terminal 1 sudo ./ecapture tls --ecaptureqws://127.0.0.1:28257/ # Terminal 2 ./ecaptureq_client -server ws://127.0.0.1:28257/ -verbose # 应周期性看到 heartbeat 消息场景 4多客户端并发# Terminal 1 sudo ./ecapture tls --ecaptureqws://127.0.0.1:28257/ # Terminal 2 ./ecaptureq_client -server ws://127.0.0.1:28257/ # Terminal 3 ./ecaptureq_client -server ws://127.0.0.1:28257/ # 两个客户端都能收到相同的事件broadcast源码视角为什么多客户端能收到相同事件服务端采用经典的 Hub-Client 广播模型pkg/ecaptureq/hub.go每个连接在handleWebSocket中注册为一个Client其发送通道send容量为 256见 server.go#L71Hub.run的broadcast分支遍历所有已注册客户端逐一下发hub.go#L42-L63。因此场景 4 中两个客户端必然收到同一事件流broadcastMessage是非阻塞写入通道满则丢弃hub.go#L65-L70保证事件流不会被慢消费者卡住。预期行为与关键参数测试指南给出的预期行为清单均可在源码中找到对应实现连接与日志回放客户端连接后立即收到缓冲日志最多 128 条——对应LogBuffLen 128与sendLogBuffserver.go#L29、server.go#L84-L88。WriteLog的逻辑是缓冲区未满时仅缓存超过 128 条后新日志改为直接广播server.go#L91-L105所以先启动 eCapture、后连接的客户端拿到的是最后一段启动日志。心跳保活服务端为每个客户端启动writePump连接建立即发送一次心跳随后由time.Ticker周期性发送心跳消息带自增count、Unix 时间戳与heartbeat:N文本pkg/ecaptureq/client.go#L82-L117、client.go#L119-L135。原指南描述心跳间隔为 60 秒需要注意当前源码中 Ticker 设定为 15 秒client.go#L83文档与代码存在版本差异实际间隔请以-verbose下的真实观测为准。事件广播所有捕获的 SSL/TLS 事件实时广播给全部已连接客户端Hub 的 broadcast 路径见上文场景 4 分析。日志随产生随发进程日志经ecaptureQLogWriter进入WriteLog缓冲区满后即时广播。性能方面指南给出的结论与源码一致多客户端可同时连接且收到相同事件事件实时发送、不做二次缓冲首次连接回放最后 128 条日志心跳负责保持连接存活。故障排查以下四条按原指南完整保留并附源码定位线索。Failed to connect to WebSocket server原因服务端未运行或 URL 错误。处理检查 eCapture 是否在运行ps aux | grep ecapture检查端口是否在监听netstat -tlnp | grep 28257确认 URL 带尾部/确认客户端使用的 IP/端口与 eCapture 启动参数完全一致。websocket: bad handshake原因URL 格式问题或服务端尚未就绪。处理URL 必须以/结尾ws://127.0.0.1:28257/✅ws://127.0.0.1:28257❌eCapture 启动后等待约 1 秒再连接检查防火墙是否拦截端口。补充握手发生在 HTTP 层服务端把 WebSocket 处理器挂在根路径/上pkg/util/ws/server.go#L43-L45握手失败基本都指向地址/路径/端口不匹配。已连接但收不到事件原因没有可捕获的流量或过滤条件不匹配。处理制造流量curl https://www.baidu.com在 eCapture 终端确认其本身有捕获输出用-verbose查看心跳确认链路存活确认 eCapture 启动过程无报错。Connection closed: EOF原因eCapture 进程被终止或网络异常。处理检查 eCapture 进程是否仍在运行同时重启 eCapture 与客户端查看系统日志中的错误。从源码看客户端侧收到读取错误会打印Connection closed: %v并退出main.go#L77-L97服务端侧readPump出错则注销客户端并关闭连接pkg/ecaptureq/client.go#L55-L75两侧行为互相对应。自动化验证e2e 测试脚本除手动流程外仓库自带了端到端自动化测试 test/e2e/ecaptureq_e2e_test.sh可作为回归验证手段。脚本要点前置检查root 权限、内核版本check_kernel_version 4 18、curl与go可用依次构建bin/ecapture与examples/ecaptureq_client下的客户端二进制连通性测试以--ecaptureqws://127.0.0.1:28257/启动 eCapture等待 3 秒后连接客户端通过进程存活与日志中的Connected successfully判定通过事件捕获测试客户端连接后对https://api.github.com发起两次 HTTPS 请求随后校验客户端日志——Connected successfully连接成功、Captured Event收到事件、GET|POST|HTTP|GitHubTLS 明文内容确实出现在事件中三层校验全部命中才算完整通过脚本对连接成功但未捕获到事件给出了宽容处理部分环境下 curl 使用的 SSL 库版本或符号未被当前探针 hook属于环境相关现象不代表 WebSocket 管道故障。运行方式在仓库根目录需 rootbash test/e2e/ecaptureq_e2e_test.sh集成到你自己的应用如果要基于该协议开发自己的接收端可直接参考客户端主流程原指南给出的最小示例// 完整示例见 examples/ecaptureq_client/main.go import ( pb github.com/gojue/ecapture/protobuf/gen/v1 golang.org/x/net/websocket google.golang.org/protobuf/proto ) ws, _ : websocket.Dial(ws://127.0.0.1:28257/, , http://localhost/) defer ws.Close() for { var msgData []byte websocket.Message.Receive(ws, msgData) var logEntry pb.LogEntry proto.Unmarshal(msgData, logEntry) // 按 logEntry.LogType 分派处理 // 0 心跳(HeartbeatPayload)、1 进程日志(RunLog)、2 事件(EventPayload) }要点所有消息均为 protobuf 编码解码类型统一为pb.LogEntry字段定义见 protobuf/proto/v1/ecaptureq.proto事件消息的event_payload.payload是原始字节数组即 SSL 明文自行做 HTTP/二进制解析心跳仅用于链路保活业务处理可忽略更完整的协议说明见 docs/event-forward-api.md 与 pkg/ecaptureq/README.md。测试收尾测试结束后客户端按CtrlC停止客户端已注册SIGINT/SIGTERM信号处理见 main.go#L59-L74在 eCapture 终端按CtrlC停止服务端如需清理构建产物rm examples/ecaptureq_client/ecaptureq_client相关文件索引路径内容examples/ecaptureq_client/TESTING.md本文主体客户端测试指南examples/ecaptureq_client/main.go客户端完整实现连接、解码、展示examples/ecaptureq_client/README.md客户端使用说明与协议摘要pkg/ecaptureq/server.goWebSocket 服务端日志缓冲、WriteLog/WriteEventpkg/ecaptureq/client.go每连接 readPump/writePump 与心跳pkg/ecaptureq/hub.goHub 广播模型cli/cmd/root.go--ecaptureq/--listen参数定义与服务启动逻辑pkg/util/ws/server.go底层 HTTP WebSocket 监听protobuf/proto/v1/ecaptureq.proto协议定义LogEntry/Event/Heartbeattest/e2e/ecaptureq_e2e_test.sh自动化端到端测试脚本【免费下载链接】ecaptureCapturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64.项目地址: https://gitcode.com/GitHub_Trending/ec/ecapture创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价