沙箱机制
沙箱机制
OpenClaw 可以在 Docker 容器内运行工具 以减少爆炸半径。
这是可选的,由配置控制(agents.defaults.sandbox 或
agents.list[].sandbox)。如果沙箱关闭,工具在主机上运行。
Gateway 保持在主机上;工具执行在启用时在隔离的沙箱中运行。
这不是一个完美的安全边界,但当模型执行愚蠢操作时,它能实质性地限制文件系统 和进程访问。
哪些内容会被沙箱化
- 工具执行(
exec、read、write、edit、apply_patch、process等)。 - 可选的沙箱浏览器(
agents.defaults.sandbox.browser)。- 默认情况下,沙箱浏览器在浏览器工具需要时自动启动(确保 CDP 可访问)。
通过
agents.defaults.sandbox.browser.autoStart和agents.defaults.sandbox.browser.autoStartTimeoutMs配置。 - 默认情况下,沙箱浏览器容器使用专用的 Docker 网络(
openclaw-sandbox-browser)而不是全局bridge网络。 通过agents.defaults.sandbox.browser.network配置。 - 可选的
agents.defaults.sandbox.browser.cdpSourceRange通过 CIDR 允许列表限制容器边缘 CDP 入口(例如172.21.0.1/32)。 - noVNC 观察者访问默认受密码保护;OpenClaw 发出一个短生命周期的令牌 URL,提供本地引导页面并在 URL 片段(而非查询/头部日志)中打开带密码的 noVNC。
agents.defaults.sandbox.browser.allowHostControl允许沙箱会话显式 targeting 主机浏览器。- 可选的允许列表控制
target: "custom":allowedControlUrls、allowedControlHosts、allowedControlPorts。
- 默认情况下,沙箱浏览器在浏览器工具需要时自动启动(确保 CDP 可访问)。
通过
不被沙箱化:
- Gateway 进程本身。
- 任何显式允许在主机上运行的工具(例如
tools.elevated)。- 提升执行在主机上运行并绕过沙箱。
- 如果沙箱关闭,
tools.elevated不会改变执行(已经在主机上)。参见 提升模式。
模式
agents.defaults.sandbox.mode 控制何时使用沙箱:
"off":无沙箱。"non-main":仅沙箱化非主会话(如果你希望正常聊天在主机上运行,这是默认值)。"all":每个会话都在沙箱中运行。 注意:"non-main"基于session.mainKey(默认"main"),而非代理 id。 群组/频道会话使用自己的键,因此它们被视为非主会话并会被沙箱化。
范围
agents.defaults.sandbox.scope 控制创建多少个容器:
"session"(默认):每个会话一个容器。"agent":每个代理一个容器。"shared":所有沙箱会话共享一个容器。
工作区访问
agents.defaults.sandbox.workspaceAccess 控制沙箱可以看到什么:
"none"(默认):工具看到~/.openclaw/sandboxes下的沙箱工作区。"ro":将代理工作区以只读方式挂载到/agent(禁用write/edit/apply_patch)。"rw":将代理工作区以读写方式挂载到/workspace。
入站媒体被复制到活动沙箱工作区(media/inbound/*)。
技能说明:read 工具以沙箱为根。使用 workspaceAccess: "none" 时,
OpenClaw 将符合条件的技能镜像到沙箱工作区(.../skills)以便
它们可以被读取。使用 "rw" 时,工作区技能可从
/workspace/skills 读取。
自定义绑定挂载
agents.defaults.sandbox.docker.binds 将额外的主机目录挂载到容器中。
格式:host:container:mode(例如 "/home/user/source:/source:rw")。
全局和每代理的绑定会合并(而非替换)。在 scope: "shared" 下,每代理的绑定被忽略。
agents.defaults.sandbox.browser.binds 将额外的主机目录仅挂载到沙箱浏览器容器中。
- 当设置时(包括
[]),它会替换浏览器容器的agents.defaults.sandbox.docker.binds。 - 当省略时,浏览器容器回退到
agents.defaults.sandbox.docker.binds(向后兼容)。
示例(只读源代码 + 额外的数据目录):
{
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"],
},
},
},
],
},
}
安全说明:
- 绑定绕过沙箱文件系统:它们以你设置的任何模式(
:ro或:rw)暴露主机路径。 - OpenClaw 阻止危险的绑定源(例如:
docker.sock、/etc、/proc、/sys、/dev,以及会暴露它们的父挂载)。 - 敏感挂载(密钥、SSH 密钥、服务凭证)应设为
:ro,除非绝对必要。 - 如果你只需要对工作区的只读访问,可与
workspaceAccess: "ro"结合使用;绑定模式保持独立。 - 参见 沙箱 vs 工具策略 vs 提升 了解绑定如何与工具策略和提升执行交互。
镜像 + 设置
默认镜像:openclaw-sandbox:bookworm-slim
构建一次:
scripts/sandbox-setup.sh
注意:默认镜像不包含 Node。如果技能需要 Node(或
其他运行时),要么构建自定义镜像,要么通过
sandbox.docker.setupCommand 安装(需要网络出口 + 可写根目录 +
root 用户)。
如果你想要一个包含常用工具的功能更完整的沙箱镜像(例如
curl、jq、nodejs、python3、git),构建:
scripts/sandbox-common-setup.sh
然后将 agents.defaults.sandbox.docker.image 设置为
openclaw-sandbox-common:bookworm-slim。
沙箱浏览器镜像:
scripts/sandbox-browser-setup.sh
默认情况下,沙箱容器无网络运行。
通过 agents.defaults.sandbox.docker.network 覆盖。
捆绑的沙箱浏览器镜像也为容器化工作负载应用保守的 Chromium 启动默认值。 当前容器默认值包括:
--remote-debugging-address=127.0.0.1--remote-debugging-port=<从 OPENCLAW_BROWSER_CDP_PORT 派生>--user-data-dir=${HOME}/.chrome--no-first-run--no-default-browser-check--disable-3d-apis--disable-gpu--disable-dev-shm-usage--disable-background-networking--disable-extensions--disable-features=TranslateUI--disable-breakpad--disable-crash-reporter--disable-software-rasterizer--no-zygote--metrics-recording-only--renderer-process-limit=2- 当
noSandbox启用时,使用--no-sandbox和--disable-setuid-sandbox。 - 三个图形硬化标志(
--disable-3d-apis、--disable-software-rasterizer、--disable-gpu)是可选的,在 容器缺乏 GPU 支持时很有用。如果你的工作负载需要 WebGL 或其他 3D/浏览器功能, 设置OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0。 --disable-extensions默认启用,可以通过OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0禁用以支持依赖扩展的流程。--renderer-process-limit=2由OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>控制,其中0保持 Chromium 的默认值。
如果你需要不同的运行时配置,使用自定义浏览器镜像并提供
你自己的入口点。对于本地(非容器)Chromium 配置,使用
browser.extraArgs 附加额外的启动标志。
安全默认值:
network: "host"被阻止。network: "container:<id>"默认被阻止(命名空间加入绕过风险)。- 紧急突破覆盖:
agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true。
Docker 安装和容器化 Gateway 位于此处: Docker
对于 Docker Gateway 部署,docker-setup.sh 可以引导沙箱配置。
设置 OPENCLAW_SANDBOX=1(或 true/yes/on)启用该路径。你可以
通过 OPENCLAW_DOCKER_SOCKET 覆盖 socket 位置。完整设置和环境
参考:Docker。
setupCommand(一次性容器设置)
setupCommand 在沙箱容器创建后仅运行一次(不是每次运行)。
它通过 sh -lc 在容器内执行。
路径:
- 全局:
agents.defaults.sandbox.docker.setupCommand - 每代理:
agents.list[].sandbox.docker.setupCommand
常见陷阱:
- 默认
docker.network是"none"(无出口),所以包安装会失败。 docker.network: "container:<id>"需要dangerouslyAllowContainerNamespaceJoin: true且仅用于紧急突破。readOnlyRoot: true阻止写入;设置readOnlyRoot: false或构建自定义镜像。user必须是 root 才能安装包(省略user或设置user: "0:0")。- 沙箱执行不继承主机
process.env。使用agents.defaults.sandbox.docker.env(或自定义镜像)来设置技能 API 密钥。
工具策略 + 紧急出口
工具允许/拒绝策略在沙箱规则之前仍然适用。如果工具被全局 或每代理拒绝,沙箱不会将其恢复。
tools.elevated 是一个显式的紧急出口,在主机上运行 exec。
/exec 指令仅适用于授权的发送者并按会话持久化;要硬禁用
exec,使用工具策略拒绝(参见 沙箱 vs 工具策略 vs 提升)。
调试:
- 使用
openclaw sandbox explain检查有效的沙箱模式、工具策略和修复配置键。 - 参见 沙箱 vs 工具策略 vs 提升 了解"为什么被阻止?"的思维模型。 保持锁定状态。
多代理覆盖
每个代理可以覆盖沙箱 + 工具:
agents.list[].sandbox 和 agents.list[].tools(以及 agents.list[].tools.sandbox.tools 用于沙箱工具策略)。
参见 多代理沙箱和工具 了解优先级。
最小启用示例
{
agents: {
defaults: {
sandbox: {
mode: "non-main",
scope: "session",
workspaceAccess: "none",
},
},
},
}