沙箱

OpenClaw 可以将工具放在 Docker 容器中运行,减小爆炸半径。这是可选功能,通过配置控制(agents.defaults.sandboxagents.list[].sandbox)。沙箱关闭时,工具直接在宿主机上运行。网关始终在宿主机上运行;只有工具执行在启用沙箱时会被隔离。

这不是完美的安全边界,但当模型做了蠢事时,能实质性地限制文件系统和进程访问。

什么会被沙箱化

  • 工具执行(execreadwriteeditapply_patchprocess 等)。
  • 可选的沙箱浏览器(agents.defaults.sandbox.browser)。
    • 默认情况下,沙箱浏览器在浏览器工具需要时自动启动(确保 CDP 可达)。通过 agents.defaults.sandbox.browser.autoStartagents.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 生成短期 token URL,提供本地引导页面,并在 URL fragment 中携带密码打开 noVNC(不在 query/header 日志中暴露)。
    • agents.defaults.sandbox.browser.allowHostControl 允许沙箱会话显式使用宿主机浏览器。
    • 可选白名单控制 target: "custom"allowedControlUrlsallowedControlHostsallowedControlPorts

不会被沙箱化的:

  • 网关进程本身。
  • 任何显式允许在宿主机上运行的工具(如 tools.elevated)。
    • Elevated exec 在宿主机上运行,绕过沙箱。
    • 沙箱关闭时,tools.elevated 不改变执行方式(本来就在宿主机上)。详见 Elevated 模式

模式

agents.defaults.sandbox.mode 控制何时使用沙箱:

  • "off":不使用沙箱。
  • "non-main":只对非 main 会话启用沙箱(适合你想让普通聊天在宿主机上运行的场景)。
  • "all":所有会话都在沙箱中运行。 注意:"non-main" 基于 session.mainKey(默认 "main"),不是 agent id。群组/频道会话有自己的 key,算作非 main,会被沙箱化。

范围

agents.defaults.sandbox.scope 控制创建多少个容器

  • "session"(默认):每个会话一个容器。
  • "agent":每个 agent 一个容器。
  • "shared":所有沙箱会话共享一个容器。

工作区访问

agents.defaults.sandbox.workspaceAccess 控制沙箱能看到什么

  • "none"(默认):工具只能看到 ~/.openclaw/sandboxes 下的沙箱工作区。
  • "ro":以只读方式挂载 agent 工作区到 /agentwrite/edit/apply_patch 被禁用)。
  • "rw":以读写方式挂载 agent 工作区到 /workspace

入站媒体会被复制到活跃沙箱工作区(media/inbound/*)。 关于 skill:read 工具以沙箱为根路径。workspaceAccess: "none" 时,OpenClaw 会将符合条件的 skill 镜像到沙箱工作区(.../skills),使其可读。"rw" 时,工作区的 skill 可从 /workspace/skills 读取。

自定义绑定挂载

agents.defaults.sandbox.docker.binds 将额外的宿主机目录挂载到容器中。 格式:host:container:mode(例如 "/home/user/source:/source:rw")。

全局绑定和 per-agent 绑定会合并(不是替换)。scope: "shared" 下 per-agent 绑定被忽略。

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 Elevated 了解绑定与工具策略、elevated exec 的交互。

镜像与初始化

默认镜像:openclaw-sandbox:bookworm-slim

构建一次即可:

scripts/sandbox-setup.sh

注意:默认镜像不包含 Node。如果 skill 需要 Node(或其他运行时),要么制作自定义镜像,要么通过 sandbox.docker.setupCommand 安装(需要网络出口 + 可写根文件系统 + root 用户)。

如果你需要包含常用工具(如 curljqnodejspython3git)的功能更完整的沙箱镜像,构建:

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=<derived from 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=2OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N> 控制,0 保持 Chromium 默认值。

如果需要不同的运行时配置,使用自定义浏览器镜像并提供自己的入口点。本地(非容器)Chromium profile 可使用 browser.extraArgs 追加额外启动参数。

安全默认值:

  • network: "host" 被拦截。
  • network: "container:<id>" 默认被拦截(命名空间共享带来的绕过风险)。
  • 紧急开关:agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true

Docker 安装和容器化网关相关内容见:Docker

Docker 网关部署时,docker-setup.sh 可以引导沙箱配置。设置 OPENCLAW_SANDBOX=1(或 true/yes/on)启用该路径。可通过 OPENCLAW_DOCKER_SOCKET 覆盖 socket 位置。完整配置和环境变量参考:Docker

setupCommand(一次性容器初始化)

setupCommand 在沙箱容器创建后执行一次(不是每次运行都执行),在容器内通过 sh -lc 运行。

路径:

  • 全局:agents.defaults.sandbox.docker.setupCommand
  • Per-agent:agents.list[].sandbox.docker.setupCommand

常见陷阱:

  • 默认 docker.network"none"(没有出口),包管理器安装会失败。
  • docker.network: "container:<id>" 需要 dangerouslyAllowContainerNamespaceJoin: true,仅限紧急使用。
  • readOnlyRoot: true 阻止写入;设置 readOnlyRoot: false 或使用自定义镜像。
  • user 必须是 root 才能安装软件包(不设 user 或设 user: "0:0")。
  • 沙箱 exec 不继承宿主机的 process.env。skill API 密钥需通过 agents.defaults.sandbox.docker.env(或自定义镜像)传入。

工具策略与逃生通道

工具 allow/deny 策略在沙箱规则之前生效。全局或 per-agent 拒绝的工具,沙箱也救不回来。

tools.elevated 是显式的逃生通道,让 exec 在宿主机上运行。/exec 指令只对授权发送者在当前会话生效;要彻底禁用 exec,使用工具策略 deny(详见 沙箱 vs 工具策略 vs Elevated)。

排查:

  • openclaw sandbox explain 检查生效的沙箱模式、工具策略和修复配置键。
  • 详见 沙箱 vs 工具策略 vs Elevated 了解”为什么被拦截”的思维模型。保持严格锁定。

多 agent 覆盖

每个 agent 可以覆盖沙箱和工具配置:agents.list[].sandboxagents.list[].tools(加上 agents.list[].tools.sandbox.tools 用于沙箱工具策略)。详见 多 Agent 沙箱与工具 了解优先级。

最小启用示例

{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main",
        scope: "session",
        workspaceAccess: "none",
      },
    },
  },
}

相关文档