OpenClaw 沙箱完全指南:把 Agent 关进笼子里
当你让一个 AI Agent 在你电脑上执行命令、读写文件、浏览网页时,你有没有想过:如果这个 Agent 突然抽风,下了一个 rm -rf / 会怎样?
这不是危言耸听。LLM 生成的内容是不可预测的——模型会"幻觉",会在代码里插入错误的路径,会在你让 它"帮我清理一下临时文件"时把整个 home 目录删掉。这就是为什么 OpenClaw 引入了沙箱(Sandbox)系统:把 Agent 的手脚捆住,让它在受控的笼子里干活,出了事也炸不到你的真实系统。
本文是 OpenClaw 官方沙箱文档的完整中文解读,涵盖三种隔离模式、三种后端实现、配置方法,以及背后的安全逻辑。
沙箱是什么?不是什么
先说清楚概念。OpenClaw 的沙箱系统是一种可选的、运行在隔离环境中的工具执行层。它不是虚拟化整个系统,只是把"工具调用"(exec、文件读写、浏览器等)放到隔离环境里跑。Gateway 进程本身始终运行在宿主机上,不受影响。
沙箱不是完美的安全边界。官方文档的原话是:
This is not a perfect security boundary, but it materially limits filesystem and process access when the model does something dumb.
换句话说:它防得住"蠢操作"(模型犯迷糊时的破坏性命令),但不要指望它能对抗有决心的攻击者。
三种隔离模式:什么时候把笼子打开
OpenClaw 用 agents.defaults.sandbox.mode 控制沙箱何时生效,有三种模式:
"off" — 不用沙箱
工具直接在宿主机上执行。你家的大门敞开,Agent 想去哪就去哪,适合你完全信任这个 Agent 且愿意承担后果的场景。生产环境强烈不推荐。
"non-main" — 只对非主会话启用沙箱(推荐开发用)
主会话(key 为 "main" 的会话,即你和 Agent 的正常对话)运行在宿主机上,不沙箱化;其他所有会话(子 agent、群组聊天等)都在沙箱里跑。
这个模式的好处是:正常聊天体验不打折(无额外延迟),但后台自动化任务有隔离保护。官方文档说这个模式是"如果你想让普通聊天跑在宿主机上"时的默认选择。
"all" — 全部会话都沙箱化
所有会话无一例外都在沙箱里跑。最安全的姿势,但每次工具调用都有跨边界开销,适合对安全要求极高的场景。
注意:"non-main" 的判断依据是 session.mainKey(默认 "main"),而不是 agent id。群聊、频道会话因为 key 不等于 "main",会被当作 non-main 处理,从而自动进入沙箱。
三种后端:沙箱跑在哪里
有了模式选择,还要决定沙箱跑在哪里。OpenClaw 支持三种后端:
Docker 后端(默认)
backend: "docker" 是默认选项。在本地启动一个 Docker 容器,工具全部在这个容器里执行。容器默认使用 openclaw-sandbox:bookworm-slim 镜像。
优点:
- 完全隔离的网络和文件系统
- 支持沙箱浏览器(通过 Chrome DevTools Protocol 控制无头 Chromium)
- 支持 bind mount(把宿主机的目录挂载进容器)
- 容器销毁后所有改动消失(除非你用 bind mount)
限制:
- 需要本地安装 Docker
- 沙箱容器默认不使用 bridge 网络(除非手动配置),外部网络访问受限
适用场景:本地开发、需要完整隔离的自动化任务。
SSH 后端
backend: "ssh" 把沙箱跑到任意一台可以通过 SSH 访问的远程机器上。OpenClaw 通过 SSH 连接远程主机,在那里执行工具调用。
工作原理:
- 首次创建沙箱时,OpenClaw 从本地 workspace 把文件"播种"(seed)到远程目录
- 之后所有 exec、文件读写都直接操作远程机器,不走本地
- OpenClaw 不会把远程改动同步回本地
这是"远程规范"(remote-canonical)模型——远程才是真相,本地只是种子来源。
适用场景:想把 AI 任务卸载到树莓派、远程服务器,或者受限于本地 Docker 不可用的环境。
OpenShell 后端
backend: "openshell" 使用 OpenShell 托管的远程沙箱环境,适合不想自己管理 SSH 机器的人。OpenShell 插件提供生命周期管理(创建/删除/SSH 配置),OpenClaw 通过 SSH transport 连接到它。
OpenShell 有两种工作模式:
mirror(默认):本地 workspace 是规范源。每次 exec 前同步本地文件进沙箱,exec 后把沙箱里改动的文件同步回本地。本地始终是真相,适合希望沙箱只是"临时执行环境"的人。remote:远程 OpenShell workspace 成为规范。初始从本地播种一次,之后所有操作直接在远程进行,不再同步回本地。适合把远程沙箱当作"真实工作区"的场景。
适用场景:Managed 远程沙箱、团队共享沙箱环境、需要两层同步控制的工作流。
Scope:共享还是独享
选定了后端,还要决定沙箱容器的颗粒度。通过 agents.defaults.sandbox.scope 配置:
| Scope | 行为 | 优点 | 缺点 |
|---|---|---|---|
"session"(默认) |
每个会话独立容器 | 完全隔离,互不影响 | 资源消耗最大 |
"agent" |
每个 Agent 共享一个容器 | 同 agent 下多会话复用,节省资源 | 跨会话可能泄露状态 |
"shared" |
所有沙箱会话共用一个容器 | 最节省资源 | 安全隔离最弱 |
三种后端都支持这三种 scope。
工作区访问控制:沙箱能看到什么
默认情况下,沙箱里的工具只能看到 ~/.openclaw/sandboxes/ 下的隔离工作区,看不到你主目录里的文件。通过 agents.defaults.sandbox.workspaceAccess 可以调整:
"none"(默认):沙箱工具只能访问隔离工作区,什么都碰不到宿主机文件。"ro":只读挂载你的 Agent workspace 到/agent,工具可以读文件但不能写。"rw":读写挂载到/workspace,工具可以正常读写你的 workspace。方便但风险最大。
对于 OpenShell 后端,mirror 模式仍以本地 workspace 为规范源,remote 模式则以远程 workspace 为规范源。
沙箱浏览器:浏览器也进笼子
现代 Agent 经常要控制浏览器做 UI 自动化、网页截图等。OpenClaw 的沙箱浏览器功能让你把 Chromium 也跑在沙箱里:
- 沙箱浏览器使用独立 Docker 网络(默认
openclaw-sandbox-browser),和主网络隔离 - noVNC 观察访问默认有密码保护,URL 里有短命 token
- 可选配置
cdpSourceRange(CDP 入口 IP 白名单)和allowHostControl(是否允许沙箱会话控制宿主机浏览器) - 自定义 URL/Host/Port 白名单用于
target: "custom"场景
仅 Docker 后端支持沙箱浏览器,SSH 和 OpenShell 暂不支持。
Bind Mount:让沙箱安全访问特定目录
沙箱默认是封闭的,但如果 Agent 真的需要访问某些宿主机目录(比如你的项目代码),可以用 bind mount 精确控制:
{
"agents": {
"defaults": {
"sandbox": {
"docker": {
"binds": [
"/home/user/source:/source:ro", // 只读挂载源代码
"/var/data/myapp:/data:ro" // 只读挂载数据目录
]
}
}
},
"list": [
{
"id": "build",
"sandbox": {
"docker": {
"binds": [
"/mnt/cache:/cache:rw" // 某个 Agent 需要读写缓存
]
}
}
}
]
}
}
全局和按 Agent 的 bind mount 是合并的(不是覆盖),所以可以叠加。只读 (:ro) 永远比读写 (:rw) 安全,除非确需写入才开放读写权限。
沙箱生命周期管理
沙箱不是一次配置就完事的。OpenClaw 提供了 openclaw sandbox 命令族来管理运行时:
# 查看当前所有沙箱的状态、容器名、后端、运行时长
openclaw sandbox list
# 查看某个会话/Agent 的沙箱配置详情
openclaw sandbox explain --session agent:main:main
openclaw sandbox explain --agent mybot
# 更新了镜像或配置后,重新创建沙箱容器
openclaw sandbox recreate --all # 重建所有
openclaw sandbox recreate --session main # 只重建某个会话
openclaw sandbox recreate --browser # 只重建浏览器容器
为什么 recreate 很重要?
当你修改了沙箱配置——比如换了 Docker 镜像、改了 SSH 目标、更改了 workspace 模式——旧的沙箱容器仍然会继续用旧配置运行,直到被销毁。OpenClaw 的自动清理(prune)要等 24 小时无活动才会回收。这意味着:如果你天天用的 Agent 配置改了,它会一直用着旧配置跑下去,永远不会自动更新。
recreate 就是强制重启:删除旧容器,下次 Agent 真正需要工具时自动用新配置创建新容器。
prune:自动清理机制
沙箱会自动清理长时间不用的容器,防止磁盘空间被耗尽:
idleHours: 24:24 小时无活动后自动删除容器maxAgeDays: 7:无论是否活跃,超过 7 天强制删除
你也可以手动 recreate,或者在配置里把 prune 相关选项关掉(不推荐)。
elevated 工具:唯一绕过沙箱的出口
有个特殊规则需要记住:tools.elevated 允许的工具始终运行在宿主机上,不受沙箱约束。这是为了让某些必须拥有完整权限的工具(比如系统级管理命令)能够正常工作。
如果沙箱是关闭的(mode: "off"),tools.elevated 不会有任何额外效果——因为工具本来就在宿主机上跑。
实战配置模板
把上面的内容整合一下,给几个常见场景的配置模板:
场景一:本地开发,最常用
{
"agents": {
"defaults": {
"sandbox": {
"mode": "non-main",
"backend": "docker",
"scope": "session",
"workspaceAccess": "rw"
}
}
}
}
场景二:生产环境,最高安全
{
"agents": {
"defaults": {
"sandbox": {
"mode": "all",
"backend": "docker",
"scope": "session",
"workspaceAccess": "none",
"prune": { "idleHours": 2, "maxAgeDays": 3 }
}
}
}
}
场景三:远程 SSH 沙箱
{
"agents": {
"defaults": {
"sandbox": {
"mode": "all",
"backend": "ssh",
"scope": "agent",
"workspaceAccess": "rw",
"ssh": {
"target": "user@remote-server:22",
"workspaceRoot": "/tmp/openclaw-sandboxes",
"identityFile": "~/.ssh/id_ed25519"
}
}
}
}
}
为什么沙箱不可或缺
总结一下为什么要用沙箱:
- 防手滑:模型生成命令有随机性,
rm -rf /这样的灾难性错误在沙箱里只是删掉一个临时容器,不会伤到真实系统。 - 防提示词注入:恶意网页可能在系统提示里植入指令试图让 Agent 执行危险操作,沙箱是最后一道防线。
- 多租户隔离:如果你用 OpenClaw 运行多个用户/客户的 Agent,每个人的任务跑在独立容器里,互不干扰。
- 可重复的构建环境:沙箱容器是镜像定义的,相同配置的容器每次行为完全一致,方便复现问题。
- 合规要求:某些行业(金融、医疗、政府)的数据处理需要隔离环境,Docker 沙箱天然满足要求。
把 Agent 放进沙箱,不代表你不信任它——而是代表你理解"不可预测性"是 AI 的本质。安全从来不是建立在信任之上的,而是建立在约束之上的。
本文基于 OpenClaw 官方沙箱文档 编写,内容已融合进个人理解,如有任何疑问欢迎参考官方文档。