写在前面
沙箱防逃逸,审批防越权,但 Agent 拿到合法权限后的行为——没人看得见。
上个月披露的 TrapDoor 攻击,攻击者在 .cursorrules 里埋零宽 Unicode 字符,Agent 读取后自动遍历文件系统外发密钥。这个月 Miasma Wave 2 更进一步——后门配置文件直接丢进项目目录,你克隆仓库、打开项目,后门就激活了。没有弹窗,没有告警,沙箱也不触发。攻击完全发生在授权边界内,Agent 只是”按配置工作”。
所有传统防御措施都在解决”安装前”的问题:扫描依赖、审核 registry、提醒用户只装可信来源。但一旦恶意配置进了你的环境,Agent 开始运行之后——它实际在做什么,没人知道。
这就是 eBPF 登场的背景。
一、eBPF 是什么?
1.1 从 BPF 到 eBPF:三十年演进
1992 年,Steven McCanne 和 Van Jacobson 在 USENIX 发表《The BSD Packet Filter》,提出 Berkeley Packet Filter(BPF)——一个运行在内核的虚拟机,用于高效过滤网络数据包。cBPF 只有 2 个寄存器,32 位设计,功能局限在网络过滤。
2014 年,Alexei Starovoitov 向 Linux 内核提交了 eBPF(extended BPF)补丁集,在 Linux 3.18 中合入。核心改进:
- 寄存器从 2 个增加到 10 个 64 位寄存器
- 引入
BPF_CALL指令,可调用内核 Helper 函数 - 引入 JIT 编译器,将字节码翻译为本机指令
- 引入 验证器(Verifier),确保程序安全
- 支持 eBPF Maps,实现内核态与用户态的数据交换
此后里程碑:
- 2016:XDP(eXpress Data Path)引入——网卡驱动层直接处理包
- 2017:Brendan Gregg 称 eBPF 为”Linux 的超级力量”
- 2020:可休眠 BPF 程序(Sleepable BPF)
- 2021:Windows 开始实现 eBPF
- 至今:eBPF 成为 Linux 内核最活跃的子系统之一
1.2 核心架构:沙箱中的安全内核编程
eBPF 的本质是:在不修改内核、不加载内核模块的前提下,在内核态安全执行自定义程序。
验证器(Verifier)——安全性的基石
每个 eBPF 程序在加载前必须通过严格的静态分析:
| 检查项 | 说明 |
|---|---|
| CFG 无环 | 控制流图深度优先搜索,确保程序必然终止 |
| 有界循环 | Linux 5.3+ 支持,需运行时检查上限 |
| 指令上限 | 单程序最多 1,000,000 条指令 |
| 指针追踪 | 跟踪寄存器存的是普通值还是指针,有类型/对齐/边界检查 |
| 未初始化检测 | 从未写过的寄存器不可读 |
| 状态剪枝 | 已检查路径的子集自动跳过,提升验证效率 |
结论:eBPF 程序崩溃不会影响内核稳定性——验证器保证。
JIT 编译器
将 eBPF 字节码翻译为 x86-64、ARM64、RISC-V、s390 等硬件架构的原生机器码。性能接近原生编译的内核代码。无 JIT 时回退到解释器模式。
eBPF Maps——数据交换中枢
Maps 是 eBPF 程序与用户态共享数据的核心数据结构:
| Map 类型 | 用途 | 性能特征 |
|---|---|---|
HASH | 通用键值存储 | O(1) 平均 |
ARRAY | 定长数组 | 最低延迟 |
PERCPU_HASH/ARRAY | 每 CPU 独立副本 | 无锁竞争 |
RINGBUF | 流式事件传输 | 高效批量 |
LRU_HASH | 淘汰策略 | 内存控制 |
Hook 类型——程序挂载点
eBPF 是事件驱动的,必须附着到特定 Hook:
网络类:
- XDP:网卡驱动层,数据包刚到达时执行,性能最高(线速)
- TC:网络栈 ingress/egress 分类器
- Socket Filter:socket 级别过滤
追踪类:
- kprobe/kretprobe:动态内核函数探测(入口/返回)
- uprobe/uretprobe:用户空间函数探测
- tracepoint:静态内核跟踪点(稳定 ABI,推荐优先使用)
- fentry/fexit:BPF Trampoline 框架,比 kprobe 更快
安全类:
- LSM(BPF-LSM):Linux Security Module 钩子,实现 MAC 强制访问控制
其他:
- cgroup 系列:按控制组做网络/设备策略
- SYSCALL:直接挂载系统调用
1.3 CO-RE + BTF:编译一次,到处运行
传统 eBPF 程序需要针对特定内核编译。每次内核升级,结构体字段偏移变化,程序必须重新编译。
BTF(BPF Type Format) 是 DWARF 的轻量级替代方案,以紧凑二进制格式描述内核数据结构布局。Linux 5.2+ 默认启用。
CO-RE 工作机制:
- 编译一次:Clang 生成带 BTF 重定位信息的 ELF 文件
- 运行时重定位:libbpf 根据当前内核 BTF 自动修正字段偏移
- 无需重新编译:同一份 BPF ELF 可在不同内核版本上运行
二、eBPF 能解决什么问题?
2.1 网络:性能提升 10-100 倍
Cilium(CNCF 毕业项目)是 eBPF 在网络领域最成功的案例:
- CNI 插件:基于 eBPF 的扁平 L3 网络
- kube-proxy 替换:eBPF 哈希表负载均衡,相比 iptables 延迟降低 90%+,CPU 降低 10-100 倍
- 基于身份的安全策略:L3-L7,支持 HTTP/gRPC/Kafka
- Cluster Mesh:跨集群安全互联
2.2 可观测性:< 1% 开销的全景视图
Pixie(CNCF Sandbox):使用 eBPF 自动采集全量请求体、资源指标、网络指标、性能 Profile(火焰图),CPU 使用率 < 2-5%。
Hubble(Cilium 内置):eBPF 驱动的服务拓扑、流量监控、DNS 分析。
传统可观测性工具需要代码埋点,eBPF 的方案做到了零侵入——不改一行代码。
2.3 运行时安全:从检测到执行
| 工具 | 项目状态 | 定位 | 是否可执行策略 |
|---|---|---|---|
| Tetragon | Isovalent/Cisco | 安全可观测性 + 运行时执行 | ✅ 是(TracePolicy) |
| Falco | CNCF 毕业 | 运行时安全威胁检测 | ❌ 仅检测 |
| Tracee | Aqua Security | 深度追踪和取证 | ❌ 仅检测 |
| KubeArmor | CNCF Sandbox | LSM 安全策略执行 | ✅ 是(AppArmor/SELinux) |
关键区别:Falco 看到异常只能告警,Tetragon 和 KubeArmor 可以实时阻断。
2.4 性能分析:定位瓶颈
bpftrace 一行命令即可挂载 tracepoint/kprobe 分析性能瓶颈,无需修改应用代码。
三、怎么用 eBPF?
3.1 开发工具链对比
| 工具 | 语言 | 适用场景 |
|---|---|---|
| bpftrace | awk 风格 DSL | 快速诊断、线上排查、一行脚本 |
| bcc | Python 3 + C | 快速原型、系统性能分析 |
| libbpf | C | 生产级 eBPF 应用、长期维护项目 |
| cilium/ebpf | Go | Go 生态的 eBPF 开发 |
| aya | Rust | Rust 生态的 eBPF 开发 |
3.2 实战:用 bpftrace 监控 Claude Code
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_openat {
if (comm == "claude") {
printf("OPEN: pid=%d, file=%s\\n", pid, str(args->filename));
}
}'
输出示例:
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
关键点:信息由内核直接报告,不经过 Agent 日志系统。即使 Agent 被注入”不要记录文件访问”的指令,内核依然如实上报。
3.3 生产环境:Tetragon TracePolicy
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: ai-agent-monitor
spec:
kprobes:
- call: "security_file_open"
syscall: false
args:
- index: 0
type: "file"
selectors:
- matchNames:
- namespace: "ai-agents"
四、AI Agent 时代的 eBPF:从观测到管控
4.1 为什么传统安全工具在 Agent 场景失效
Web 服务器的行为是可预测的:监听 80/443,读写特定目录,连特定的数据库。你可以写一条 Falco 规则——”除了连 redis:6379 和 postgres:5432 之外的网络连接都告警”——这个规则完美有效。
但 AI Agent 的行为不是确定的。同一个 Agent,上午的任务是”分析销售数据”,下午的任务是”爬取竞品信息”。前者只读本地 CSV,后者可能连几十个外部域名。
| 传统工具失效的原因 | 说明 |
|---|---|
| 行为非确定性 | 每次运行的系统调用序列都不同 |
| 行为分布宽 | Agent 可以合法执行数千种不同操作 |
| 上下文依赖 | 同一操作在不同上下文中含义完全不同 |
| 误报率极高 | 每个合法工具调用都可能触发规则 |
| 攻击面动态 | Agent 的工具集和 API 不断变化 |
4.2 三层观测模型
┌──────────────────────────────────────────────────┐
│ L1: Agent 日志 —— "它打算做什么" │
│ (stdout, callback, 自打 log) │
│ ⚠ 不可信:Agent 被注入后可选择性报告/伪造日志 │
├──────────────────────────────────────────────────┤
│ L2: OTel 链路 —— "它调了什么 API" │
│ (OpenTelemetry: LLM→Tool 调用链) │
│ ⚠ 不完整:只看到应用层约定好的交互 │
├──────────────────────────────────────────────────┤
│ L3: eBPF 内核 —— "它实际做了什么" │
│ (syscalls: open/connect/execve) │
│ ✅ 不可篡改、零侵入、开销 < 3% │
└──────────────────────────────────────────────────┘
eBPF 能观测到每个系统调用:
| 系统调用 | Agent 行为 |
|---|---|
openat2 | 读了什么文件 |
connect | 连了哪个 IP |
execve | 启动了哪个进程 |
sendto/sendmsg | 发送了什么数据 |
4.3 语义鸿沟:eBPF 知道”做了什么”,不知道”为什么做”
假设客服 Agent 收到含间接 prompt injection 的工单,让 Agent 从 PII 表拉数据、POST 到外部端点:
| 检测层 | 能看到的 | 漏掉的 |
|---|---|---|
| eBPF/kernel | 新 TCP 连接到未知 IP;数据库 socket 读取量异常 | 为什么建立连接?是不是 prompt injection 触发的? |
| 容器运行时 | 无镜像漂移、无意外进程 | 攻击在授权边界内完成 |
| K8s 控制面 | RBAC 不变、SA 不变 | 一切——攻击在授权边界内 |
| 应用层 L7 | 注入 prompt、未授权 DB 调用、含 PII 的 POST | 几乎没有——有完整上下文 |
这就是 AgentSight 论文(arXiv:2508.02736, UC Berkeley)提出的 语义鸿沟(Semantic Gap):
- Intent stream:Agent 在 LLM 通信中的意图(可截获 TLS 解密后内容)
- Action stream:Agent 的系统调用
- 断层:内核知道动作不知道意图;LLM 通信有意图但缺关联
AgentSight 的因果关联引擎将两者实时关联,用副 LLM 做语义分析。overhead < 3%。
4.4 对 Agent 的实时管控架构
现实:LLM 推理延迟 500ms-2s,不适合做系统调用级实时拦截。AgentSpec 结论——”LLM-as-Judge 缺乏可靠的实时执行能力”。
可行架构:LLM 离线生成规则 + 轻量引擎实时执行
| 层级 | 技术 | 延迟 | 能力 |
|---|---|---|---|
| L1 | eBPF 快速规则(Tetragon TracePolicy) | 微秒级 | 阻止已知恶意模式 |
| L2 | 统计模型(ARMO Application Profile DNA) | 毫秒级 | 检测异常行为分布 |
| L3 | LLM Judge(采样) | 秒级 | 复杂上下文判断 |
ARMO Application Profile DNA——不是记录”Agent 通常做什么”的静态快照,而是记录”Agent 在不同任务下的行为分布”,随时间演化。当 Agent 行为分布显著偏离基线时触发告警。
groundcover——K8s 集群里跑 eBPF sensor,自动识别 OpenAI/Anthropic 的流量,把 LLM 调用转成 OTel trace 作为 span,无需 SDK 埋点。
4.5 已知攻击的 eBPF 防御
| 攻击类型 | eBPF 检测方法 |
|---|---|
| TrapDoor(零宽 Unicode 注入) | 监控配置文件读取 syscall + 意外 exec + 异常文件写入 |
| Miasma Wave 2(后门配置) | Application Profile 基线偏离检测 |
| LiteLLM 供应链攻击(PyPI 后门) | 网络连接 + 文件操作 + TracePolicy 行为限制 |
五、eBPF 不是银弹
必须诚实地说:
eBPF 解决的是”看见”的问题,不是”理解”的问题。
它能告诉你 Agent 在 14:23:05 连了 104.18.32.47:443,但不能告诉你这是正常 API 调用还是数据外泄。你需要:
- 应用层上下文:HTTP body 里是什么?(需 L7 探针或 AgentSight 式 TLS 截获)
- 业务语义:IP 是否在白名单?(需对接业务系统)
- 因果链:行为由哪个 prompt 触发?(需 OTel 链路追踪)
正确架构是三层叠加,不是单层替代。 L1 给你业务语义,L2 给你调用链,L3 给你不可抵赖的系统行为证据。三者交叉验证,才能回答那个真正重要的问题:Agent 有没有做它不该做的事?
Futurum 2026 年初调研显示,AI Agent 可观测性已进入企业采购优先级 Top 10。
六、速查:eBPF 里程碑时间线
| 时间 | 事件 |
|---|---|
| 1992 | BPF 提出(Berkeley Packet Filter) |
| 2014 | eBPF 补丁合入 Linux 3.18 |
| 2016 | XDP 引入 |
| 2017 | CO-RE / BTF 概念出现 |
| 2018 | BPF 成独立内核目录 |
| 2020 | Sleepable BPF |
| 2021 | Windows 实现 eBPF |
| 2022 | eBPF Foundation 成立 |
| 2025 | AgentSight 论文(eBPF + LLM 因果关联) |
| 2026 | Tetragon for AI Agents / groundcover eBPF LLM 监控 |
七、如果你现在就想动手
- 快速验证:装一个
bpftrace,跑上面的脚本,看看你的 Agent 实际在做什么 - 建立基线:用 Tetragon 在测试环境跑 1-2 周,记录 Agent 行为分布
- 打通三层:把 L1 日志 + L2 OTel + L3 eBPF 三层联动,交叉验证异常行为
- 渐进式执行:从纯监控开始,逐步增加 TracePolicy 阻断规则
eBPF 不是银弹,但它至少让你看见了之前看不见的东西——在 Agent 安全的战场上,看不见等于失守。
参考资料
- 原文:MP 文章 mp.weixin.qq.com/s/Z0pR-xaAG1LqYxI1bg30oA
- eBPF 官方文档 ebpf.io
Cilium / Tetragon cilium.io tetragon.io - Falco falco.org
- KubeArmor kubearmor.io
- AgentSight arXiv:2508.02736 github.com/agentsight/agentsight
- ARMO Application Profile DNA armosec.io
- groundcover groundcover.com
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/sec/ebpf-deep-dive-ai-agent-security.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)