Appearance
沙盒(Sandboxing)
OpenClaw 可以在沙盒后端内运行工具,以降低出错时的爆炸半径。 这是可选功能,通过配置控制(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 入口。 - noVNC 观察访问默认受密码保护;OpenClaw 生成一个短效 token URL,提供本地引导页面并通过 URL 片段(非查询参数/头部日志)带密码打开 noVNC。
agents.defaults.sandbox.browser.allowHostControl允许沙盒会话明确定向到宿主机浏览器。- 可选的允许列表限制
target: "custom":allowedControlUrls、allowedControlHosts、allowedControlPorts。
- 默认情况下,沙盒浏览器在需要时自动启动(确保 CDP 可达)。可通过
不会被沙盒化的内容:
- Gateway 进程本身。
- 任何明确允许在宿主机运行的工具(如
tools.elevated)。- 提升模式下的 exec 在宿主机运行,绕过沙盒。
- 如果沙盒关闭,
tools.elevated不改变执行方式(本来就在宿主机上)。参见 提升模式。
模式
agents.defaults.sandbox.mode 控制何时使用沙盒:
"off":不使用沙盒。"non-main":只对非主会话沙盒化(如果你希望普通聊天在宿主机上运行,可选此项)。"all":每个会话都在沙盒中运行。 注:"non-main"基于session.mainKey(默认"main"),而非 agent id。群组/频道会话使用各自的 key,因此被视为非主会话,会被沙盒化。
作用域
agents.defaults.sandbox.scope 控制创建多少个容器:
"session"(默认):每个会话一个容器。"agent":每个 agent 一个容器。"shared":所有沙盒会话共享一个容器。
后端
agents.defaults.sandbox.backend 控制哪个运行时提供沙盒:
"docker"(默认):本地 Docker 支持的沙盒运行时。"ssh":通用 SSH 支持的远程沙盒运行时。"openshell":OpenShell 支持的沙盒运行时。
SSH 专用配置位于 agents.defaults.sandbox.ssh。 OpenShell 专用配置位于 plugins.entries.openshell.config。
选择后端
| Docker | SSH | OpenShell | |
|---|---|---|---|
| 运行位置 | 本地容器 | 任意 SSH 可访问的主机 | OpenShell 托管沙盒 |
| 设置方式 | scripts/sandbox-setup.sh | SSH 密钥 + 目标主机 | 启用 OpenShell 插件 |
| 工作区模型 | 绑定挂载或复制 | 远端为主(一次性同步) | mirror 或 remote |
| 网络控制 | docker.network(默认无) | 取决于远端主机 | 取决于 OpenShell |
| 浏览器沙盒 | 支持 | 不支持 | 暂不支持 |
| 绑定挂载 | docker.binds | 不适用 | 不适用 |
| 最适合 | 本地开发,完全隔离 | 将执行转移到远端机器 | 带可选双向同步的托管远端沙盒 |
SSH 后端
当你希望 OpenClaw 在任意 SSH 可访问的机器上沙盒化 exec、文件工具和媒体读取时,使用 backend: "ssh"。
json5
{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "ssh",
scope: "session",
workspaceAccess: "rw",
ssh: {
target: "user@gateway-host:22",
workspaceRoot: "/tmp/openclaw-sandboxes",
strictHostKeyChecking: true,
updateHostKeys: true,
identityFile: "~/.ssh/id_ed25519",
certificateFile: "~/.ssh/id_ed25519-cert.pub",
knownHostsFile: "~/.ssh/known_hosts",
},
},
},
},
}工作原理:
- OpenClaw 在
sandbox.ssh.workspaceRoot下创建每个作用域的远端根目录。 - 首次使用时,OpenClaw 从本地工作区一次性同步到远端。
- 之后,
exec、read、write、edit、apply_patch、提示媒体读取、入站媒体暂存都通过 SSH 直接操作远端工作区。 - OpenClaw 不自动将远端变更同步回本地工作区。
认证材料:
identityFile、certificateFile、knownHostsFile:使用现有本地文件通过 OpenSSH 配置传递。identityData、certificateData、knownHostsData:使用内联字符串或 SecretRef。OpenClaw 通过普通 secrets 运行时解析,写入权限0600的临时文件,SSH 会话结束时删除。
这是远端为主模型——初始同步后,远端 SSH 工作区成为真正的沙盒状态。
重要注意事项:
- 初始同步后在 OpenClaw 外部对宿主机进行的编辑不会自动在远端可见,除非重建沙盒。
openclaw sandbox recreate删除该作用域的远端根目录,下次使用时从本地重新同步。- SSH 后端不支持浏览器沙盒。
sandbox.docker.*设置不适用于 SSH 后端。
OpenShell 后端
当你希望 OpenClaw 在 OpenShell 托管的远端环境中沙盒化工具时,使用 backend: "openshell"。完整设置指南、配置参考和工作区模式比较,请参见专门的 OpenShell 页面。
OpenShell 复用了通用 SSH 后端相同的核心 SSH 传输和远端文件系统桥接,并增加了 OpenShell 特定的生命周期(sandbox create/get/delete、sandbox ssh-config)以及可选的 mirror 工作区模式。
json5
{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "openshell",
scope: "session",
workspaceAccess: "rw",
},
},
},
plugins: {
entries: {
openshell: {
enabled: true,
config: {
from: "openclaw",
mode: "remote", // mirror | remote
remoteWorkspaceDir: "/sandbox",
remoteAgentWorkspaceDir: "/agent",
},
},
},
},
}OpenShell 模式:
mirror(默认):本地工作区保持为主。OpenClaw 在 exec 前将本地文件同步到 OpenShell,exec 后再同步回来。remote:沙盒创建后,OpenShell 工作区成为主副本。OpenClaw 从本地工作区一次性同步到远端,之后文件工具和 exec 直接操作远端沙盒,不同步回来。
工作区模式
mirror
本地工作区保持为主时使用。
使用场景:
- 你在 OpenClaw 外部编辑本地文件,希望沙盒自动看到变更
- 希望 OpenShell 沙盒行为尽量接近 Docker 后端
- 希望宿主机工作区在每次 exec 后反映沙盒写入
权衡:exec 前后有额外的同步开销。
remote
希望 OpenShell 工作区成为主副本时使用。
使用场景:
- 沙盒主要存在于远端 OpenShell 侧
- 希望降低每轮的同步开销
- 不希望宿主机本地编辑悄悄覆盖远端沙盒状态
重要注意事项:
- 初始同步后,如果你在宿主机外部编辑文件,远端沙盒不会自动看到这些变更。
- 如果沙盒被重建,远端工作区会从本地工作区重新同步。
OpenShell 生命周期
OpenShell 沙盒通过普通沙盒生命周期管理:
openclaw sandbox list显示 OpenShell 运行时和 Docker 运行时openclaw sandbox recreate删除当前运行时,下次使用时让 OpenClaw 重建- prune 逻辑也感知后端
工作区访问
agents.defaults.sandbox.workspaceAccess 控制沙盒能看到什么:
"none"(默认):工具看到~/.openclaw/sandboxes下的沙盒工作区。"ro":将 agent 工作区以只读方式挂载到/agent(禁用write/edit/apply_patch)。"rw":将 agent 工作区以读写方式挂载到/workspace。
使用 OpenShell 后端时:
mirror模式在 exec 轮次之间仍以本地工作区为主remote模式在初始同步后以远端 OpenShell 工作区为主
入站媒体会被复制到活动沙盒工作区(media/inbound/*)。 技能说明:read 工具以沙盒为根。使用 workspaceAccess: "none" 时,OpenClaw 会将符合条件的技能镜像到沙盒工作区(.../skills)以便读取。使用 "rw" 时,工作区技能可从 /workspace/skills 读取。
自定义绑定挂载
agents.defaults.sandbox.docker.binds 将额外的宿主机目录挂载到容器中。 格式:host:container:mode(如 "/home/user/source:/source:rw")。
全局绑定和每个 agent 的绑定会合并(而非替换)。在 scope: "shared" 下,每个 agent 的绑定会被忽略。
agents.defaults.sandbox.browser.binds 仅挂载到沙盒浏览器容器中:
- 设置后(包括
[]),会替换浏览器容器的agents.defaults.sandbox.docker.binds。 - 未设置时,浏览器容器回退到
agents.defaults.sandbox.docker.binds(向后兼容)。
示例(只读源码 + 额外数据目录):
json5
{
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以及会暴露它们的父挂载)。 - 敏感挂载(secrets、SSH 密钥、服务凭据)除非绝对必要,应使用
:ro。 - 参见 沙盒 vs 工具策略 vs 提升模式 了解绑定与工具策略和提升 exec 的交互关系。
镜像与设置
默认 Docker 镜像:openclaw-sandbox:bookworm-slim
一次性构建:
bash
scripts/sandbox-setup.sh注:默认镜像不包含 Node。如果技能需要 Node(或其他运行时),要么烘焙自定义镜像,要么通过 sandbox.docker.setupCommand 安装(需要网络出口 + 可写根目录 + root 用户)。
如果你需要包含常用工具(如 curl、jq、nodejs、python3、git)的更完整沙盒镜像,构建:
bash
scripts/sandbox-common-setup.sh然后将 agents.defaults.sandbox.docker.image 设为 openclaw-sandbox-common:bookworm-slim。
沙盒浏览器镜像:
bash
scripts/sandbox-browser-setup.sh默认情况下,Docker 沙盒容器无网络。通过 agents.defaults.sandbox.docker.network 覆盖。
安全默认值:
network: "host"被阻止。network: "container:<id>"默认被阻止(命名空间加入绕过风险)。- 应急覆盖:
agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true。
setupCommand(一次性容器设置)
setupCommand 在沙盒容器创建后运行一次(不是每次运行都执行)。 通过 sh -lc 在容器内执行。
常见陷阱:
- 默认
docker.network是"none"(无出口),包安装会失败。 docker.network: "container:<id>"需要dangerouslyAllowContainerNamespaceJoin: true,仅限应急使用。readOnlyRoot: true阻止写入;设为readOnlyRoot: false或烘焙自定义镜像。user必须是 root 才能安装包(省略user或设为user: "0:0")。- 沙盒 exec 不继承宿主机的
process.env。对技能 API key 使用agents.defaults.sandbox.docker.env(或自定义镜像)。
工具策略 + 逃生出口
工具允许/拒绝策略在沙盒规则前仍然有效。如果工具被全局或每个 agent 拒绝,沙盒不会恢复它。
tools.elevated 是在宿主机运行 exec 的显式逃生出口。 /exec 指令仅适用于授权发送者并在每个会话中持久化;要硬性禁用 exec,使用工具策略拒绝(参见 沙盒 vs 工具策略 vs 提升模式)。
调试:
- 使用
openclaw sandbox explain检查有效沙盒模式、工具策略和修复配置键。 - 参见 沙盒 vs 工具策略 vs 提升模式 了解"为什么被阻止"的思维模型。
多 Agent 覆盖
每个 agent 可以覆盖沙盒 + 工具: agents.list[].sandbox 和 agents.list[].tools(以及 agents.list[].tools.sandbox.tools 用于沙盒工具策略)。 参见 多 Agent 沙盒与工具 了解优先级。
最简启用示例
json5
{
agents: {
defaults: {
sandbox: {
mode: "non-main",
scope: "session",
workspaceAccess: "none",
},
},
},
}相关文档
- OpenShell:托管沙盒后端设置、工作区模式和配置参考
- 沙盒配置
- 沙盒 vs 工具策略 vs 提升模式:调试"为什么被阻止"
- 多 Agent 沙盒与工具:每个 agent 的覆盖和优先级
- 安全