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 连接远程主机,在那里执行工具调用。

工作原理

  1. 首次创建沙箱时,OpenClaw 从本地 workspace 把文件"播种"(seed)到远程目录
  2. 之后所有 exec、文件读写都直接操作远程机器,不走本地
  3. 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"
        }
      }
    }
  }
}

为什么沙箱不可或缺

总结一下为什么要用沙箱:

  1. 防手滑:模型生成命令有随机性,rm -rf / 这样的灾难性错误在沙箱里只是删掉一个临时容器,不会伤到真实系统。
  2. 防提示词注入:恶意网页可能在系统提示里植入指令试图让 Agent 执行危险操作,沙箱是最后一道防线。
  3. 多租户隔离:如果你用 OpenClaw 运行多个用户/客户的 Agent,每个人的任务跑在独立容器里,互不干扰。
  4. 可重复的构建环境:沙箱容器是镜像定义的,相同配置的容器每次行为完全一致,方便复现问题。
  5. 合规要求:某些行业(金融、医疗、政府)的数据处理需要隔离环境,Docker 沙箱天然满足要求。

把 Agent 放进沙箱,不代表你不信任它——而是代表你理解"不可预测性"是 AI 的本质。安全从来不是建立在信任之上的,而是建立在约束之上的。


本文基于 OpenClaw 官方沙箱文档 编写,内容已融合进个人理解,如有任何疑问欢迎参考官方文档。