你的 Agent 是个黑箱:eBPF 如何看透它真正在做什么
近期曝出的TrapDoor攻击手法显示,攻击者将零宽Unicode字符植入.cursorrules文件中,Agent在读取后便会自动遍历文件系统并外发密钥。紧随其后的Miasma Wave 2攻击则更进一步,它将后门配置文件直接放入项目目录,当用户克隆仓库并打开项目时,后门即被激活。整个过程既无弹窗提醒,也没有任何告警信息,甚至连沙箱环境也无法触发检测。
所有攻击行为都严格发生在授权边界之内,Agent仅仅是“按照配置工作”。
现有的防御措施大多聚焦于解决“安装前”的问题,例如扫描依赖、审核注册表以及提醒用户仅安装可信来源。然而,一旦恶意配置成功进入你的环境并开始运行,Agent实际在做什么,便无人知晓。

一、三层观测:从“它说了什么”到“它做了什么”
为了清晰地理解Agent的可观测性,可以将其划分为一个分层模型,具体包含三个层次:
复制代码L1: Agent 日志层 —— "它打算做什么"
L2: OTel 链路层 —— "它调了什么 API"
L3: eBPF 内核层 —— "它实际做了什么"
L1 日志层是你最熟悉的层面,包括Claude Code的标准输出、LangChain的回调函数以及你自己添加的日志。然而,这一层的核心问题是不可信。一旦Agent被注入控制指令,它可能选择性地报告甚至伪造日志内容。
L2 链路层借助OpenTelemetry追踪Agent、LLM与Tool之间的调用链,并记录Token用量、耗时和成本。该层比L1更为客观,但它的视野仅限于“应用层约定好的交互”,无法窥见进程内部实际读取了哪些文件或连接了哪些IP地址。
L3 eBPF 内核层是本文探讨的重点。eBPF是Linux内核的一个沙盒运行时环境,它允许用户在不修改内核代码、不安装内核模块的前提下,在内核态执行自定义程序。它主要通过以下三种钩子接入系统:
| 类型 | 用途 | 稳定性 |
|---|---|---|
| kprobes/kretprobes | 动态探针,可挂载到任意内核函数(例如tcp_connect、do_sys_open) | 非稳定ABI,内核升级可能导致失效 |
| tracepoints | 稳定的检测点(例如sched_process_exec、sys_enter_*),永不过期 | 稳定,适合长期部署 |
| LSM hooks | 强制访问控制层,可在操作完成前拒绝(例如bpf_lsm_file_open) | 稳定,适合执行策略 |
前两种钩子让你能够“看见”系统行为,第三种钩子则允许你“拦住”潜在风险。针对Agent的可观测性,tracepoints适合长期监控,kprobes用于按需审计,而LSM hooks则提供实时阻断能力。三者配合,你就能在系统边界建立起完整的控制面。
eBPF能够观测到每一个关键系统调用:
openat2—— 读取了什么文件connect—— 连接了哪个IP地址execve—— 启动了哪个子进程sendto/recvfrom—— 网络流量的具体细节
重要的是,这一切操作Agent完全无感知。你无需修改Agent的一行代码,也无需安装任何sidecar,而性能开销仅为1-3%的CPU。
二、实操:用 bpftrace 看 Claude Code 在干什么
理论讲解完毕,现在我们直接进行实践。
1. 安装 bpftrace
复制代码sudo apt-get install -y bpftrace
以下这段脚本可以在kernel 5.8+版本上实时打印出Claude Code进程所打开的文件:
复制代码sudo bpftrace -e '
tracepoint:syscalls:sys_enter_openat {
if (comm == "claude") {
printf("OPEN: pid=%d, file=%sn", pid, str(args->filename));
}
}'
脚本运行后,你可以在另一个终端中正常使用Claude Code,此时该终端将实时输出类似以下的信息:
复制代码OPEN: pid=8842, file=/home/user/.claude/settings.json
OPEN: pid=8842, file=/home/user/project/src/main.rs
OPEN: pid=8842, file=/home/user/project/.env
关键的要点在于,这些信息是由内核直接报告的,不经过Claude Code自身的日志系统。即便Claude Code被注入了“不要记录文件访问”的指令,内核依然会如实上报。
网络监控为什么不在这里展示?
在实际测试中发现,使用bpftrace抓取网络连接存在两个问题:
- 现代Agent大多采用长连接或连接池技术,连接在启动时便已建立,因此
connect()系统调用很少被触发。 - 若要抓取数据传输(例如
send或recv),需要进行更复杂的内核结构体解析,仅靠一行脚本无法完成。
对于生产环境的网络监控,推荐使用下文介绍的Tetragon配合TracePolicy,或者直接使用ss -tunap | grep <进程名>命令来查看已建立的连接。
2. 生产环境:Tetragon
bpftrace更适合临时审计。如果你需要长期监控,特别是在Kubernetes环境中运行的Agent,那么Tetragon是更合适的选择。它通过eBPF实现内核级追踪,原生支持Pod、Namespace和Label的关联,并可通过TracePolicy实现进程级阻断。
这里需要澄清一个容易混淆的点:bpftrace只能用于观测,无法进行阻断。它适用于临时审计和快速验证,但在生产环境中进行执行策略拦截时,则需要Tetragon的TracePolicy(支持进程级阻断)或KubeArmor的LSM策略。Falco则仅提供检测功能,不进行拦截。
三、语义鸿沟:eBPF 知道“它做了什么”,但不知道“为什么做”
假设你的客服Agent收到一个包含间接提示注入的工单。这个注入指令覆盖了任务上下文,导致Agent从PII表中拉取数据,并将其POST到一个外部端点。
让我们用这个实际的攻击场景来说明不同检测层的能力边界:
不同检测层的能力边界对比
| 检测层 | 能看到什么 | 漏掉什么 |
|---|---|---|
| eBPF/kernel | 检测到新的TCP连接至未知IP地址,DNS解析到不明域名,数据库socket读取量出现异常。 | 无法知晓建立这个连接的原因,无法判断数据库查询是否合法,更无法确认这是否由提示注入触发。 |
| 容器运行时 | 未发现镜像漂移,未发现意外进程,可能观察到网络出口流量峰值。 | 无法区分出口流量是合法数据传输还是数据外泄,缺乏完整的因果链。 |
| K8s 控制面 | 无异常发现。RBAC未变、SA未变、API Server也未变。 | 一切异常都被遗漏。因为攻击完全在授权边界内完成。 |
| 应用层 L7 + tool | 能够看到输入流中的注入提示,检测到针对新表的未授权数据库Tool调用,发现包含PII数据的POST请求发往未知域名,并能构建完整的因果链:工单导致数据外泄。 | 几乎没有遗漏。这是唯一拥有完整上下文信息的层面。 |
这个表格说明了两件事:第一,K8s和容器运行时在这个场景下几乎失效,因为攻击无需逃逸和提权,完全在授权边界内进行。第二,eBPF虽然能捕捉到异常信号,但它无法区分“合法的新行为”和“恶意攻击行为”。
这就是看到不等于理解的根本原因。eBPF知道Agent在14:23:05连接了一个陌生IP,并读取了一块数据库区域,但它无法知晓:
- 这个连接是因为提示注入触发的
- 数据库查询读取的是PII数据还是普通数据
- Agent的“意图”到底是什么
这正是UC Berkeley的AgentSight论文(arXiv:2508.02736)中提出的“语义鸿沟”概念:
- 意图流(Intent stream):Agent在与LLM通信中表达的意图。即使流量是TLS加密的,也可以在
SSL_read或SSL_write函数上挂载uprobe来截获解密后的内容。 - 动作流(Action stream):Agent实际执行的一系列系统调用。
- 两者之间的断层:内核知道动作,但不知道意图;LLM通信中包含意图,但如果没有关联机制,这些意图就是孤立的文本。
AgentSight的核心创新在于构建了一个因果关联引擎,它将“某个时间点LLM输出了什么意图”与“之后N秒内发生了哪些系统调用”实时关联起来,并利用一个副LLM进行语义分析,从而判断行为是否偏离了预期。
该论文报告的开销低于3%,其代码已在GitHub上开源,包含Rust 6000行和TypeScript 3000行前端代码。
四、为什么通用安全工具不够:AI Agent 没有稳定行为基线
你可能会问:既然eBPF能监控进程行为,那为什么不直接使用Falco、Tetragon这些成熟的工具呢?为什么还需要专门搞一套“AI-aware”的方案?
原因在于,AI Agent的行为模式是不确定的。
一个Web服务器的行为是可预测的:它监听80/443端口,读写特定的目录,连接特定的数据库和缓存。你可以为Falco编写一条规则:“除了连接redis:6379和postgres:5432之外的网络连接都告警”,这完全可行。
然而,Agent的行为由提示词决定。同一个Agent,上午的任务可能是“分析销售数据”,下午的任务就变成了“爬取竞品信息”。前者可能只读取本地CSV文件,而后者则可能需要连接几十个外部域名。静态白名单要么设置得太宽松起不到作用,要么设置得太严格导致频繁误报,从而打断Agent的正常工作。
我们先来看一下截止2026年6月,一些开源工具的适用性:
| 工具 | 类型 | Agent 场景适用性 | Overhead |
|---|---|---|---|
| Cilium Tetragon (v1.7+) | 运行时安全 + 执行策略 | 中等——该工具支持K8s,并通过TracePolicy CRD实现阻断。 | 最低(采用内核过滤) |
| Falco (v0.40+) | 运行时安全(仅检测) | 低——该工具仅能检测,无法阻断,且规则是静态的。 | 中低 |
| Tracee (v0.23+) | 深度系统调用追踪 | 低——其开销较高,是Tetragon的2到4倍,适合调试环境而非生产环境。 | 高 |
| KubeArmor (v1.4+) | 强制访问控制 | 中等——该工具基于LSM,支持文件、网络和进程策略。 | 中低 |
Tetragon适合用于建立Agent行为基线以及进行异常检测,Falco适用于安全审计与合规场景但无法实时阻断,Tracee的深度足够但开销太高不适合生产环境。它们对于确定性工作负载很有效,但Agent并没有一个稳定的系统调用配置文件。
这些工具本身不连接LLM。Tetragon和KubeArmor是规则驱动的:你编写YAML文件来定义“检测到X就拦截”,其执行是确定性的,没有LLM参与。这与AgentSight那种“使用副LLM进行语义分析”的方案是两条完全不同的路线。
那么,LLM在阻断链路中能做什么呢?目前来看,有三类方案,但没有任何一种方案是“由LLM实时推理并拦截系统调用”的:
| 方案类型 | 代表项目 | LLM 角色 | 实时性 |
|---|---|---|---|
| LLM 生成规则,规则引擎执行 | AgentSpec (ICSE 2026)、SafeClaw-R | LLM离线生成安全策略或DSL规则。 | 毫秒级执行 |
| LLM 分析异常,人工/异步响应 | AgentSight、ARMO | LLM关联意图流和动作流,判断行为是否偏离。 | 告警后响应 |
| 权限框架,deny-by-default | SkillGuard | 基于技能清单预定义权限边界。 | 实时 |
AgentSpec论文的关键结论是:“LLM作为判断者缺乏可靠的实时执行能力”——LLM做判断的速度太慢且结果不一致,系统调用级别的拦截无法承受几百毫秒的推理延迟。因此,现实的架构是LLM离线生成规则,再由轻量级引擎实时执行。
ARMO在2026年3月的一篇博客中提出了一个名为Application Profile DNA的概念。这不是记录“Agent通常做什么”的静态快照,而是记录“Agent在不同任务下的行为分布”,并且会随时间演化。
通过对比可以更清晰地理解这一点:
| 维度 | 通用 eBPF(Tetragon/Falco) | AI-aware eBPF(ARMO) |
|---|---|---|
| 策略模型 | 静态白名单加规则。 | 动态策略,基于行为基线进行演化。 |
| 检测上下文 | 系统调用级别的异常。 | 结合系统调用、应用层Tool调用以及L7流量内容。 |
| 策略粒度 | 按Pod或Namespace划分。 | 按单个Agent划分,反映各自的行为画像。 |
另一个值得关注的方案是groundcover(2026年)。他们在K8s集群中运行eBPF传感器,自动识别OpenAI、Anthropic等提供商的流量,并将LLM调用转换为OTel Trace。提示词、响应、Token用量和延迟等信息都被记录为Span,无需SDK埋点。该方案甚至还提供了一个MCP Server,让Agent可以自己查询观测数据。
这个思路的本质是:不要试图用规则去预测Agent会做什么,而是去观察它实际做了什么,然后评估“这偏离正常模式有多远”。
五、eBPF 不是银弹
写到此处必须坦诚地说:eBPF解决的是“看见”的问题,而不是“理解”的问题。
它能告诉你Agent在14:23:05连接了104.18.32.47:443,但它无法告诉你这个连接是正常的API调用还是数据外泄。要做出这个判断,你需要:
- 应用层上下文:这个连接的HTTP请求体里包含什么内容?这需要L7探针或像AgentSight那样的TLS截获功能。
- 业务语义:这个IP地址是否在白名单中?这次数据读取是否符合当前的任务目标?这需要对接你的业务系统。
- 因果链:这个行为是由哪个用户请求或哪条提示词触发的?这需要OTel链路追踪。
因此,正确的架构是三层叠加,而不是单层替代:
复制代码┌─────────────────────────────────────────┐
│ L1: Agent 日志(自报告,不可信) │
├─────────────────────────────────────────┤
│ L2: OTel 链路(API 调用链,不完整) │
├─────────────────────────────────────────┤
│ L3: eBPF 内核(内核视角,无上下文) │
└─────────────────────────────────────────┘
L1提供业务语义,L2提供调用链,L3提供不可抵赖的系统行为证据。三者交叉验证,才能回答那个真正重要的问题:Agent有没有做它不该做的事?
值得一提的是,Futurum在2026年初的调研显示,AI Agent可观测性已进入企业采购优先级的Top 10。这并不是因为CFO们突然关心新技术,而是因为第一批在生产环境中运行Agent的团队,已经遇到了实际的问题。
如果你想现在就开始动手:
- 快速验证:安装一个bpftrace,运行上面的脚本,观察你的Agent实际在做什么。
- 建立基线:在测试环境中使用Tetragon运行1-2周,记录Agent的行为分布。
- 打通三层:将L1日志、L2 OTel和L3 eBPF三层数据联动起来,交叉验证异常行为。
eBPF虽然不是银弹,但它至少能让你看见以前看不见的东西。
参考资料
- AgentSight(UC Berkeley,arXiv:2508.02736): arxiv.org/html/2508.0…
- ARMO:eBPF for AI Agent Enforcement: www.armosec.io/blog/ebpf-b…
- groundcover:AI Agent Observability: www.groundcover.com/learn/obser…
- Tetragon: tetragon.io
- Futurum 2026调研:AI Agent可观测性进入企业采购优先级Top 10