在 AI Agent 场景中,代码 / 命令执行沙箱是负责运行不可信代码的隔离环境 —— 它的核心作用是把 Agent 生成的代码、Shell 命令限制在一个封闭边界内运行,防止恶意 / 误操作破坏主机系统、窃取数据、耗尽资源,同时可靠地回传执行结果。
沙箱的本质是多层隔离与限制技术的组合,底层依赖操作系统能力,上层适配 Agent 的交互需求。

一、底层核心原理:操作系统级隔离基石

现代沙箱(尤其是 Linux 环境下)的能力几乎都建立在三大内核机制之上,配合文件系统、权限裁剪形成完整防护体系。

1. Namespaces(命名空间):视图级隔离

命名空间的作用是给沙箱内的进程制造一个虚拟世界观,让它看不到主机的真实环境,也无法直接触达主机资源。Linux 提供 7 种核心命名空间,沙箱会全部启用:
  • PID Namespace:隔离进程 ID。沙箱内的 1 号进程在主机上只是一个普通用户进程,沙箱内看不到任何主机进程,也无法通过 PID 杀死主机进程。
  • Mount Namespace:隔离文件系统挂载点。沙箱拥有独立的目录树,只能看到分配给它的文件系统,默认无法访问主机磁盘的任何目录。
  • Network Namespace:隔离网络栈。沙箱有独立的网卡、路由表、端口映射,默认状态下完全断网,既不能访问外网,也无法连接主机内网。
  • UTS Namespace:隔离主机名 / 域名。沙箱内可以有独立的 hostname,不影响主机。
  • IPC Namespace:隔离进程间通信。禁止沙箱进程通过共享内存、消息队列和主机进程交互。
  • User Namespace:隔离用户 ID。沙箱内的root用户对应主机上的普通用户,即使沙箱内提权成功,在主机上也没有任何权限。
  • Time Namespace:隔离系统时间。沙箱内可以有独立的时间视图,防止修改系统时间。

2. Cgroups(控制组):资源用量限制

命名空间解决看不见的问题,Cgroups 解决用不了太多的问题 —— 它可以给沙箱硬卡资源上限,从根本上防御资源耗尽攻击(死循环、fork 炸弹、内存溢出等)。
核心限制维度:
  • CPU:限制可用核心数、CPU 时间占比(比如最多使用 0.5 核)
  • 内存:限制最大物理内存 + Swap 用量,超出则触发 OOM 自动终止进程
  • 进程数:限制最大 PID 数量,直接防御 fork 炸弹
  • 磁盘 IO:限制读写速率,防止打满磁盘带宽
  • 磁盘空间:限制沙箱可写入的文件总大小,防止磁盘占满

3. Seccomp-BPF:系统调用过滤

系统调用是用户态程序操作内核的唯一入口,绝大多数危险行为(挂载磁盘、调试其他进程、修改内核参数)都通过系统调用完成。
Seccomp-BPF 可以在内核层面设置系统调用白名单 / 黑名单,只允许沙箱程序调用运行必需的系统调用,直接拦截危险调用。比如沙箱不需要网络时,直接禁止所有socket相关系统调用;禁止mount、ptrace、reboot、setns等高风险调用。
这是最底层的安全防线,即使上层隔离被绕过,危险系统调用也会被内核直接拒绝。

4. 配套的隔离增强机制

沙箱还会叠加以下防护:
  • 只读根文件系统:沙箱的系统根目录设为只读,代码无法修改系统文件、植入后门。
  • 临时可写层:通过 OverlayFS 叠加一个临时可写层,所有写入都只在临时层生效,沙箱销毁后自动消失,不留任何痕迹。
  • 权限裁剪:用非 root 用户运行代码,裁剪 Linux Capabilities(去掉CAP_SYS_ADMIN、CAP_NET_RAW等危险权限),禁用 suid/sgid 程序提权。
  • 强制访问控制:配合 AppArmor/SELinux,进一步限制进程的文件访问、操作权限。

二、主流沙箱实现路线与对比

基于上述底层技术,衍生出 5 种主流的沙箱实现路线,隔离强度、性能、适用场景差异很大。
表格
 
沙箱类型代表技术隔离层级性能启动速度安全等级典型 Agent 场景
容器级沙箱 Docker、Podman 操作系统级 接近原生 几百毫秒 高 本地 Agent、后端服务通用方案
轻量进程沙箱 nsjail、firejail 进程级 原生 几十毫秒 高 高频短任务、Shell 命令执行
微虚拟机沙箱 Firecracker、gVisor 虚拟机级 略低于原生 几百 ms~1s 极高 云服务、对外提供的 Code Interpreter
语言级沙箱 RestrictedPython、Node vm 解释器级 原生 极快 低(易逃逸) 仅作辅助防护,不可单独使用
Wasm 沙箱 Wasmtime、Pyodide 字节码级 接近原生 极快 高 跨平台、前端 / 浏览器端 Agent

1. 容器级沙箱(最主流,本地 Agent 首选)

这是 OpenAI Code Interpreter、绝大多数开源 Agent 采用的方案,核心代表是 Docker。
  • 原理:完整封装 Linux Namespaces + Cgroups + Seccomp,提前打包好带运行环境(Python、依赖库)的镜像。
  • 执行流程:
    1. Agent 生成代码 / 命令
    2. 启动一个一次性容器(--rm 参数,执行完自动销毁)
    3. 将代码、输入文件以只读方式挂载进容器
    4. 在容器内执行代码,捕获标准输出 / 错误、输出文件
    5. 容器自动销毁,不留任何残留
  • 优势:生态成熟、依赖管理方便、配置简单、隔离性可靠
  • 安全红线:禁止--privileged特权模式、默认关闭网络、根文件系统只读、用非 root 用户运行

2. 轻量进程沙箱

代表是谷歌的nsjail,比 Docker 更轻量化,没有镜像层概念,直接调用内核隔离接口创建沙箱。
  • 原理:直接操作 namespaces、seccomp、cgroups 系统调用,创建一个隔离的进程环境,依赖主机预装的运行时。
  • 优势:启动极快(几十毫秒)、内存开销极小,适合高频、短生命周期的命令执行。
  • 劣势:依赖管理麻烦,需要主机提前安装所有需要的库和运行环境。

3. 微虚拟机沙箱

介于传统虚拟机和容器之间,兼顾启动速度和强隔离,代表是 AWS Firecracker、谷歌 gVisor。
  • gVisor:用户态内核,拦截所有系统调用并自己处理,不直接调用主机内核,隔离性远超普通容器。
  • Firecracker:精简的 KVM 虚拟机,启动不到 125ms,隔离性和物理虚拟机一致,AWS Lambda 底层就是它。
  • 这类方案一般用于云厂商的公有服务,本地自用 Agent 很少用到。

4. 语言级沙箱

在编程语言解释器层面做限制,比如 Python 的RestrictedPython、Node.js 的vm模块。
  • 原理:修改 AST(抽象语法树)、重写内置对象,禁止访问危险模块(如os、subprocess)和函数。
  • 致命缺陷:极易被绕过。以 Python 为例,通过自省、异常对象、getattr、__import__等机制有无数种方式突破限制拿到系统权限。
  • 结论:绝对不能单独作为安全防线,只能作为系统级沙箱之外的第二层辅助防护。

5. Wasm 沙箱

基于 WebAssembly 的沙箱,是近年上升很快的方案,特别适合跨平台和前端场景。
  • 原理:把代码编译成 Wasm 字节码,在 Wasm 运行时中执行。运行时默认封闭,无法直接访问文件系统、网络,只能通过显式暴露的接口和外界交互。
  • 优势:跨平台(Windows/Mac/Linux/ 浏览器通用)、隔离性强、启动极快、性能接近原生。
  • 代表:Pyodide(浏览器端运行 Python)、Wasmer/Wasmtime(通用 Wasm 运行时),很多轻量本地 Agent 用它替代 Docker。

三、Agent 沙箱的专属设计

普通沙箱只负责隔离,AI Agent 场景还需要适配代码交互、会话管理、依赖处理等特殊需求。

1. 代码与数据交互机制

沙箱是封闭环境,需要设计可靠的通道和 Agent 交换数据:
  • 标准输入输出:把代码通过stdin传给沙箱内的解释器,从stdout/stderr读取结果,适合短代码、简单命令。
  • 文件挂载:把代码文件、输入数据挂载到沙箱内指定目录,执行完再从挂载目录读取输出文件,适合处理文件、大数据场景。
  • API 服务模式:沙箱内运行一个轻量 HTTP 服务,Agent 通过接口发送执行请求,适合长会话、交互式执行。

2. 会话生命周期管理

  • 一次性模式:每次执行代码都启动全新沙箱,执行完立即销毁。优点是绝对干净无副作用;缺点是状态不保留,每次都要重新加载环境。
  • 会话持久模式:同一个 Agent 会话复用一个沙箱,多次执行共享变量、文件、内存。优点是支持多轮增量执行;缺点是有状态累积风险,必须在会话结束后彻底销毁。

3. 依赖管理方案

Agent 生成的代码经常需要第三方库,沙箱内的依赖处理有三种主流方案:
  1. 基础镜像预装:把常用库(numpy、pandas 等)提前打包进基础镜像,覆盖 80% 场景,最安全。
  2. 临时安装:允许沙箱内临时安装包,但仅当前沙箱有效,销毁即丢失。需要注意控制网络权限,仅允许访问可信镜像源。
  3. 层缓存:利用 Docker 镜像层缓存,安装过的依赖下次启动自动复用,兼顾安全和速度。

4. 熔断与超时机制

  • 执行超时:设置最大执行时长(通常 30 秒以内),超时强制终止沙箱,防御死循环。
  • 资源熔断:实时监控 CPU、内存、磁盘使用率,超过阈值立即销毁。
  • 输出限制:限制标准输出大小,防止海量输出打爆主机内存。

5. 前置静态扫描

代码进入沙箱前先做静态检测,拦截明显恶意行为:
  • 危险命令检测(rm -rf /、磁盘写入炸弹、反弹 Shell 等)
  • 危险模块 / API 检测(根据场景限制ctypes、subprocess、系统调用接口)
  • 敏感信息检测(防止读取环境变量、配置文件)

四、核心安全风险与防护要点

1. 容器逃逸

  • 风险:利用内核漏洞、配置不当逃出沙箱,控制主机。
  • 防护:
    • 严禁使用特权模式(--privileged)
    • 启用 User Namespace,沙箱 root 映射主机普通用户
    • 根文件系统设为只读,禁用 suid 权限
    • 保持内核、容器运行时版本更新
    • 强制启用 Seccomp 和 AppArmor/SELinux

2. 资源耗尽攻击(DoS)

  • 风险:fork 炸弹、无限内存分配、死循环占满资源。
  • 防护:Cgroups 硬限制 CPU、内存、进程数 + 严格执行超时 + 磁盘空间配额。

3. 数据窃取

  • 风险:代码读取沙箱内数据后通过网络外传。
  • 防护:默认完全禁用网络,必要时仅开放白名单域名;禁止挂载主机敏感目录;不透传主机环境变量。

4. 语言级沙箱绕过

  • 风险:Python/JS 层面的限制被轻易突破。
  • 防护:永远不要依赖语言级沙箱作为唯一防线,外层必须套操作系统级隔离。

五、Agent 沙箱选型与最小实现

建议

  • 本地开发 / 自用 Agent:Docker 沙箱是最优解,成熟可靠,配置简单,依赖管理方便。
  • 高频轻量任务:nsjail 或 Wasm 沙箱,启动快开销小。
  • 浏览器端 Agent:Pyodide + Wasm,纯前端无需后端服务。
  • 对外提供服务:微虚拟机方案 + 多层防护。

最小可用 Docker 沙箱示例

本地快速实现一个安全的 Python 代码沙箱,核心配置如下:
 1 docker run --rm \
 2   --network none                  # 完全禁用网络
 3   --memory 512m --cpus 0.5       # 限制内存和CPU
 4   --read-only                     # 根文件系统只读
 5   --tmpfs /tmp:rw,size=100m      # 仅/tmp目录可写,限100M
 6   --pids-limit 128                # 限制最大进程数
 7   -u 1000:1000                    # 用普通用户运行
 8   -v /本地代码目录:/app:ro        # 代码目录只读挂载
 9   python:3.11-slim \
10   python /app/script.py

执行完成后容器自动销毁,不会在主机留下任何痕迹。

总结

Agent 代码沙箱的核心逻辑是「最小权限 + 多层隔离 + 可销毁」:
  1. 底层靠操作系统的命名空间、控制组、系统调用过滤实现硬隔离;
  2. 中间层通过文件系统只读、权限裁剪收缩攻击面;
  3. 上层适配 Agent 的交互、会话、依赖需求;
  4. 最外层通过静态扫描、超时熔断做前置防御。
永远不要在主机直接运行生成的代码,LLM 的幻觉和 Prompt 注入都可能产生破坏性命令,沙箱是代码执行能力的必备基础设施。