Hotdry.
security

Linux命名空间、seccomp-bpf与cgroups构建AI代理沙箱的工程实践

深入解析如何使用Linux三大原生隔离机制为AI代理构建轻量级沙箱,包含可落地的配置参数、防御策略与监控要点。

AI 代理在执行代码、访问文件系统或发起网络请求时,其自主性也带来了不可控的安全风险。与其依赖重量级虚拟化方案,工程师可以选择 Linux 内核原生提供的三大安全原语 —— 命名空间(Namespaces)、seccomp-bpf 和 cgroups—— 构建轻量级、细粒度的沙箱隔离层。

沙箱的核心目标与威胁模型

AI 代理沙箱的核心诉求集中在三方面:文件系统隔离防止敏感文件被误删或篡改,网络管控阻断未授权的数据外泄,资源限制避免单一代理耗尽主机资源。

威胁模型需假设代理可能被诱导执行恶意指令。典型攻击路径包括:通过提示注入(prompt injection)诱导代理覆盖 $HOME 目录,或利用代理的代码执行能力在沙箱内植入反向 shell。因此,沙箱设计需遵循最小权限原则,默认拒绝所有敏感操作,仅显式开放必要权限。

命名空间:构建隔离边界

Linux 命名空间为进程提供独立的资源视图。对于 AI 代理沙箱,以下四类命名空间最为关键:

PID 命名空间 实现进程 ID 隔离,使沙箱内 PID 1 成为独立 init 进程。崩溃或资源泄漏不会污染宿主的进程树。创建参数:unshare --pid --fork

Mount 命名空间 控制文件系统可见范围。推荐采用只读绑定挂载(bind mount)映射系统目录(如 /usr/bin),同时以读写模式映射项目工作目录。示例:mount --bind -o ro /host/usr /sandbox/usr

Network 命名空间 提供独立的协议栈。可完全禁用网络(unshare --net),或通过虚拟以太网对(veth pair)连接至宿主网络命名空间,由 iptables/nftables 执行细粒度出站过滤。

User 命名空间 实现 UID/GID 映射,使沙箱内 root 实际对应宿主的非特权用户(如 UID 100000)。这消除了容器逃逸后获得宿主 root 权限的风险。映射配置:echo "0 100000 65536" > /proc/self/uid_map

seccomp-bpf:系统调用过滤

seccomp(Secure Computing Mode)通过 BPF 程序过滤系统调用,将攻击面从完整的 Linux 内核接口缩减至白名单范围内的最小集合。

配置策略建议:首先通过 strace -f -e trace=all 记录代理正常运行时的 syscall 足迹,生成初始白名单。关键保留项包括文件操作(openatreadwriteclose)、进程管理(cloneexit_group)、内存管理(mmapmunmap)和网络(如启用网络访问,需保留 socketconnectsendtorecvfrom)。

防御效果:seccomp 对非白名单 syscall 默认触发 SIGSYS 终止进程。这能有效阻断常见逃逸路径,如利用 mountpivot_root 绕过文件系统限制,或通过 open_by_handle_at 直接访问宿主 inode。

工程实现:使用 libseccomp 库生成 BPF 字节码,通过 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) 加载。对于 Python 代理,可使用 seccomp 绑定库动态生成配置。建议配合 SCMP_ACT_TRAP 而非 SCMP_ACT_KILL,便于调试阶段捕获违规 syscall。

cgroups:资源限制与隔离

cgroups(Control Groups)v2 提供统一的资源控制器,防止单个代理耗尽 CPU、内存或 I/O 资源。

关键控制器配置

  • CPUcpu.max = "50000 100000" 限制使用 50% 单核时间;cpu.weight = 100 设置相对调度权重。
  • Memorymemory.max = "1G" 设置硬上限,超限触发 OOM Killer;memory.high = "800M" 设置软限制,内核优先回收该组内存。
  • IOio.max = "259:0 rbps=1048576 wbps=1048576" 限制块设备读写速率为 1MB/s,防止 I/O 洪水攻击。
  • Pidspids.max = 64 限制进程 / 线程数量,阻断 fork 炸弹。

层级设计:建议按代理会话创建独立 cgroup:/sys/fs/cgroup/ai-sandbox/session-xxx/。代理退出后清理该层级,避免 cgroup 泄漏。通过 cgroup 命名空间(unshare --cgroup)确保沙箱内无法查看或操作其他 cgroup。

三层机制的协同策略

单一机制不足以构建完整防御。推荐的分层架构如下:

第一层(命名空间) 建立隔离边界,限制进程可见的资源范围。User 命名空间消除特权升级风险,Mount 命名空间控制文件访问,PID 命名空间隔离进程生命周期。

第二层(seccomp) 在内核接口层面阻断危险操作。即使攻击者突破命名空间限制,仍受限于允许的 syscall 集合,无法执行 mountpivot_rootkexec_load 等高风险调用。

第三层(cgroups) 兜底资源滥用场景。无论沙箱内代码如何异常,CPU、内存、I/O 用量均受硬上限约束,避免影响宿主及其他工作负载。

可落地的实现清单

基于上述分析,以下是可直接部署的配置参数与检查项:

启动参数模板

unshare --pid --net --ipc --uts --mount --user --fork --map-root-user \
  --cgroup /sys/fs/cgroup/ai-sandbox/$(uuidgen) \
  bwrap --ro-bind /usr /usr --ro-bind /lib /lib --bind /workspace /workspace \
    --unshare-all --die-with-parent --new-session \
    --seccomp 10< <(generate_seccomp_filter.py) \
    --cgroups /sys/fs/cgroup/ai-sandbox/current \
    python agent.py

seccomp 白名单最小集read, write, openat, close, fstat, lseek, mmap, mprotect, munmap, brk, rt_sigaction, rt_sigprocmask, ioctl, pread64, pwrite64, readv, writev, pipe2, dup2, nanosleep, clone, wait4, exit_group, futex

cgroups 阈值建议:内存 1GB(max)/ 800MB(high),CPU 50% 单核,进程数 64,文件描述符 1024,块设备 I/O 1MB/s。

监控与告警:通过 cgroup 的 memory.events(oom_kill 计数)、cpu.stat(throttled_time)实时追踪沙箱健康状况。seccomp 违规可通过 auditddmesg 捕获 SECCOMP 关键字日志。

已知局限:命名空间隔离无法防御内核漏洞(如 privilege escalation via unpatched CVE);seccomp 白名单需随代理行为迭代维护,过度限制可能破坏功能;cgroups v1/v2 混用环境可能存在控制器竞争。建议将本方案作为纵深防御的一环,与微虚拟机或 gVisor 等更强隔离手段按需组合使用。


资料来源:GitHub - jingkaihe/matchlock;Senko Rašić - Sandboxing AI agents in Linux;alerighi.it - Linux sandboxing with namespaces。

查看归档