跳转至

OpenShell

OpenShell 是一个托管的沙箱后端:OpenClaw 将沙箱生命周期委托给 openshell CLI,并通过 SSH 执行命令。所选的 OpenShell 网关可以使用 Docker、Podman 或虚拟化在本地管理沙箱,也可以在独立基础设施上运行它们。此 OpenShell 网关与 OpenClaw 网关不同,后者继续运行智能体和主机端插件。

该插件复用与通用 SSH 后端 相同的 SSH 传输和远程文件系统桥接,并添加了 OpenShell 生命周期(sandbox create/get/delete/ssh-config)以及可选的 mirror 工作区同步模式。

先决条件

  • openshell CLI 已安装,并位于 OpenClaw 网关进程的 PATH 中(或通过 plugins.entries.openshell.config.command 指定自定义绝对路径)
  • 网关主机上可用 OpenSSH 客户端
  • 配置 OpenShell 工作区时,OpenShell 版本需为 v0.0.88 或更新版本
  • 一个活跃且可访问的 OpenShell 网关,并具有创建沙箱的权限。本地网关不需要云账户
  • 使用本地沙箱时,OpenShell 网关主机上需要有受支持的计算运行时
  • OpenClaw 网关在主机上运行

使用 NVIDIA OpenShell 文档 安装 CLI 并配置 OpenShell 网关。在配置 OpenClaw 之前,请以运行 OpenClaw 网关的同一操作系统用户身份验证 OpenShell CLI:

openshell --version
openshell gateway list
openshell sandbox list

gateway list 会用 * 标记当前活动的网关。如果未选择网关,请运行 openshell gateway select <gateway-name>。要注册现有的本地网关端点,请运行 openshell gateway add http://127.0.0.1:8080 --local。请将端点替换为你正在运行的网关的地址。对于经过身份验证的远程网关,请使用 openshell gateway login <gateway-name> 按其登录流程操作。

OpenClaw 网关服务必须能看到与这些预检命令相同的 OpenShell CLI、网关注册、凭据和 OpenShell 工作区选择。仅限 shell 的 PATH 或 OPENSHELL_WORKSPACE 设置不会自动传递给后台服务。

快速开始

openclaw plugins install @openclaw/openshell-sandbox
{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",
        backend: "openshell",
        scope: "session",
        workspaceAccess: "rw",
      },
    },
  },
  plugins: {
    entries: {
      openshell: {
        enabled: true,
        config: {
          from: "openclaw",
          mode: "remote",
        },
      },
    },
  },
}

验证配置并重启 OpenClaw 网关:

openclaw config validate
openclaw gateway restart

在下一个智能体回合中,OpenClaw 会创建一个 OpenShell 沙箱,并通过它路由工具执行。请验证插件和实际生效的沙箱:

openclaw plugins inspect openshell --runtime --json
openclaw sandbox list
openclaw sandbox explain
openshell sandbox list

在某个沙箱化智能体回合首次需要运行时之前,openclaw sandbox list 一直为空。

工作区模式

这是 OpenShell 最重要的决策。

OpenShell 还有一个名为 工作区(workspace)的控制面资源。它与下文描述的文件系统工作区不同:它界定沙箱、提供者、策略、推理路由和成员资格。设置 plugins.entries.openshell.config.workspace 以使用现有的非默认 OpenShell 工作区。该插件不会创建 OpenShell 工作区,也不会管理其成员资格。当此设置未设置时,插件会保留 OpenShell CLI 的环境 OPENSHELL_WORKSPACE 选择;如果不存在环境选择,则回退到 CLI 的 default。

mirror(默认)

plugins.entries.openshell.config.mode: "mirror" 会将本地工作区视为权威:

  • 在 exec 之前,OpenClaw 将本地工作区同步到沙箱中。
  • 在 exec 之后,OpenClaw 将远程工作区同步回本地。
  • 在同一个 OpenClaw 网关进程内,共享同一工作区的命令和文件工具操作会等待当前操作完成。该锁覆盖完整的上传、命令和下载,或完整的文件读取/变更及其同步。不同的后端句柄共享同一把锁。
  • 文件工具通过沙箱桥接访问,但在回合之间,本地仍然是事实来源。
  • 工作目录检查会检查将被上传的主机目录,并在返回前释放其锁。执行拥有自己完整的从上传到下载的操作。被放弃的检查不会阻塞后续工具。远程权限和镜像特定的限制会在执行开始时检查。

最适合开发工作流:在 OpenClaw 之外进行的本地编辑会在下一次 exec 时生效,并且沙箱的行为与 Docker 后端非常接近。

权衡:每次 exec 回合都会产生上传 + 下载成本。

外部编辑器和其他网关进程不参与该锁。避免在镜像命令运行时更改本地工作区,因为其下载可能会覆盖这些外部编辑。

remote

mode: "remote" 会将远程工作区视为权威:

  • 在沙箱创建后的首次使用时,OpenClaw 会从本地一次性为远程工作区播种。如果网关在首次使用前重启,下次使用会检测到仍然为空的远程工作区并进行播种。已经包含内容的远程工作区永远不会被重新播种。
  • 此后,exec、read、write、edit 和 apply_patch 将直接作用于远程工作区。OpenClaw 不会将远程更改同步回本地。
  • 初始化按每个远程运行时串行执行,但初始化之后,命令和文件工具可以重叠,包括跨智能体回合。因此,后台命令可以等待后续回合写入的文件。对同一文件的并发写入遵循正常的远程文件系统语义。
  • 已物化的技能会在后端为某个回合初始化时刷新,而不是在每次文件系统操作之前刷新。与其他沙箱后端一样,较晚的回合可以在较早的后台命令仍在运行时刷新技能。
  • 提示时的媒体读取仍然有效(文件/媒体工具通过沙箱桥接读取)。
  • 出站图像和其他附件可以使用已配置远程工作区下的路径,例如 /sandbox/chart.png。

最适合长时间运行的代理和 CI:更低的每轮开销,且主机本地编辑不会静默覆盖远程状态。

Warning

在完成初始播种后,在 OpenClaw 之外的主机上编辑文件对远程沙箱不可见。运行 openclaw sandbox recreate 以重新播种。

选择模式

mirror remote
权威工作区 本地主机 远程 OpenShell
同步方向 双向(每次执行) 一次性播种
每轮开销 更高(上传 + 下载) 更低(直接远程操作)
本地编辑可见? 是,下次执行时 否,直到重新创建
最适合 开发工作流 长时间运行的代理、CI

配置参考

所有 OpenShell 配置都位于 plugins.entries.openshell.config 下:

Key Type Default Description
mode "mirror" or "remote" "mirror" 工作区同步模式
command string "openshell" openshell CLI 的路径或名称
from string "openclaw" 首次创建的沙箱来源
gateway string unset OpenShell 网关名称(顶层 --gateway)
gatewayEndpoint string unset OpenShell 网关端点(顶层 --gateway-endpoint)
workspace string unset 用于每次 CLI 操作的现有 OpenShell 工作区
policy string unset OpenClaw Gateway 主机上沙箱策略 YAML 文件的路径
providers string[] [] 沙箱创建时附加的提供商名称(去重,每个条目一个 --provider 标志)
gpu boolean false 请求 GPU 资源(--gpu)
autoProviders boolean true 创建期间传递 --auto-providers(为 false 时传递 --no-auto-providers)
remoteWorkspaceDir string "/sandbox" 沙箱内的主要可写工作区
remoteAgentWorkspaceDir string "/agent" 代理工作区挂载路径(工作区访问权限不是 rw 时为只读)
timeoutSeconds number 120 openshell CLI 操作的超时时间

remoteWorkspaceDir 和 remoteAgentWorkspaceDir 必须是绝对路径,并且保持在受管根目录 /sandbox 或 /agent 之下。其他绝对路径将被拒绝。请选择不同且不重叠的目录,因为 OpenClaw 独立管理它们的内容。为了升级兼容性,以前配置的重叠根目录仍然被接受。

timeoutSeconds 适用于普通的 OpenShell CLI 操作。沙箱创建始终获得至少 300 秒的超时时间,因此镜像构建和首次配置不会被默认的 120 秒命令超时中断。

policy 是文件路径,而不是策略名称或 ID。建议使用绝对路径,例如 /etc/openclaw/openshell-policy.yaml。相对路径会在沙箱创建期间从代理的本地工作区解析。显式策略会覆盖 OpenShell CLI 的 OPENSHELL_SANDBOX_POLICY 环境变量。当两者均未设置时,OpenShell 使用其正常的策略选择和默认值。

providers 在选定的 OpenShell 工作区中指定现有的 OpenShell 凭据提供商。当 autoProviders: true 时,OpenShell 可以从 Gateway 进程已有的凭据中创建缺失的提供商。当 autoProviders: false 时,请先创建所需的提供商,并使用 openshell --workspace <workspace-name> provider list 验证它们。请将 API 密钥保存在 OpenShell 提供商中,而不是将它们添加到沙箱环境变量中。

workspace 必须符合 OpenShell 当前的工作区名称约定:1-19 个小写字母数字字符或单个连字符,不能有前导、尾随或连续连字符。请先使用 openshell workspace create --name <name> 创建它。当所选工作区不存在或被删除时,OpenShell 会拒绝沙箱操作。将其设置为 "default" 以显式覆盖环境中的非默认 OpenShell 工作区。

该设置适用于此插件实例管理的每个 OpenShell 沙箱。它不能为每个 OpenClaw 代理或会话选择不同的 OpenShell 工作区。更改它不会迁移现有的沙箱。在旧工作区仍处于配置状态时删除 OpenClaw 的 OpenShell 沙箱,然后更改设置并重启 Gateway。

沙箱级设置(mode、scope、workspaceAccess)与任何后端一样,位于 agents.defaults.sandbox 下。有关完整矩阵,请参阅 Sandboxing。

要将非机密的环境值传递给沙箱中的命令,请使用现有的 agents.defaults.sandbox.docker.env 设置。OpenShell 后端也会在命令执行期间应用这些值。OpenShell 目前不会将它们注入沙箱创建或后台服务中。请将凭据保存在 OpenShell 提供商或其他专用的机密传递机制中。

示例

极简远程设置

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",
        backend: "openshell",
      },
    },
  },
  plugins: {
    entries: {
      openshell: {
        enabled: true,
        config: {
          from: "openclaw",
          mode: "remote",
        },
      },
    },
  },
}

带 GPU 的镜像模式

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",
        backend: "openshell",
        scope: "agent",
        workspaceAccess: "rw",
      },
    },
  },
  plugins: {
    entries: {
      openshell: {
        enabled: true,
        config: {
          from: "openclaw",
          mode: "mirror",
          gpu: true,
          providers: ["openai"],
          timeoutSeconds: 180,
        },
      },
    },
  },
}

带自定义网关的按代理 OpenShell

{
  agents: {
    defaults: {
      sandbox: { mode: "off" },
    },
    entries: {
      researcher: {
        default: true,
        sandbox: {
          mode: "all",
          backend: "openshell",
          scope: "agent",
          workspaceAccess: "rw",
        },
      },
    },
  },
  plugins: {
    entries: {
      openshell: {
        enabled: true,
        config: {
          from: "openclaw",
          mode: "remote",
          gateway: "lab",
          gatewayEndpoint: "https://lab.example",
          workspace: "research",
          policy: "/etc/openclaw/openshell-policy.yaml",
        },
      },
    },
  },
}

生命周期管理

# List all sandbox runtimes (Docker + OpenShell)
openclaw sandbox list

# Inspect effective policy
openclaw sandbox explain

# Recreate (deletes remote workspace, re-seeds on next use)
openclaw sandbox recreate --all

# Recreate only one agent or the exact session scope shown by sandbox list
openclaw sandbox recreate --agent researcher
openclaw sandbox recreate --session "agent:researcher:main"

在 remote 模式下,recreate 尤其重要:它会删除该作用域的规范远程工作区,下次使用时将从本地重新生成一个全新工作区。在 mirror 模式下,recreate 主要重置远程执行环境,因为本地始终保持规范地位。

sandbox list 和 recreate 命令在检查或删除之前,会激活已配置后端的所属插件以及每个已记录运行时的属主插件。这些操作不会加载无关插件,且浏览器专属命令仍独立于 OpenShell 后端。

OpenClaw 在升级后会保留已注册沙箱随附的旧版运行时名称,以便其远程工作区保持可寻址。重新创建该作用域会删除旧版运行时。下次使用将创建当前 19 字符的运行时名称。

OpenShell v0.0.92 仍能定位由 v0.0.68 创建的沙箱记录,但网关升级后,Docker 支撑的沙箱可能仍处于非 Ready 阶段。OpenClaw 会保留已注册的运行时身份,拒绝隐式创建替代品,并报告作用域限定的 openclaw sandbox recreate 命令。在 remote 模式下,请将该重新创建视为破坏性操作,因为远程工作区是规范工作区。

更改以下任何一项后,请重新创建:

  • agents.defaults.sandbox.backend
  • plugins.entries.openshell.config.from
  • plugins.entries.openshell.config.mode
  • plugins.entries.openshell.config.policy
  • plugins.entries.openshell.config.providers、gpu 或 autoProviders
  • plugins.entries.openshell.config.remoteWorkspaceDir 或 remoteAgentWorkspaceDir

在更改 OpenShell 网关或 OpenShell 工作区时,应在旧网关和工作区仍处于选中状态时重新创建受影响的沙箱。否则清理操作会针对新位置,而非现有沙箱。

如果 OpenShell 无法删除沙箱,OpenClaw 会报告失败并保留运行时注册表条目,以便安全重试重新创建或清理。请恢复原始网关、工作区、身份验证和连通性,使用 openshell --workspace <workspace-name> sandbox get <sandbox-name> 检查运行时,并重新运行作用域限定的 openclaw sandbox recreate 命令。不要通过切换已配置的工作区或删除注册表条目来掩盖失败。

安全加固

镜像模式文件系统桥接器将本地工作区根目录固定,并在每次读取、写入、mkdir、remove 和 rename 之前(通过 realpath)重新检查规范路径,拒绝路径中间的符号链接。符号链接替换或重新挂载的本地工作区无法将文件访问重定向到镜像树之外。

工作区同步在双向均排除 .git、hooks 和 git-hooks。仓库凭据、历史和受信任的钩子代码保留在 OpenClaw Gateway 主机上,而不会复制到不受信任的沙箱中。

镜像同步绝不会将无法表示的条目(例如符号链接、FIFO 或 Unix 套接字)复制到任一工作区。这些类型的现有主机条目在每个深度均保持完整,其父目录也保持不变,即使沙箱删除了这些目录或用文件替换了它们。与这些保留的主机路径冲突的远程替换将被忽略。普通文件和目录仍会接收远程更改和删除。

自定义镜像约定

OpenShell 源镜像拥有远程操作系统和软件包集合。OpenClaw 不会对此后端应用 Docker 镜像、根文件系统、网络、用户或软件包设置。

与 OpenClaw 文件系统桥接器一起使用的自定义镜像必须提供:

  • /bin/sh
  • 用于持久沙箱主进程的 sleep(当 OpenShell CLI 支持分离式沙箱创建时,即 sandbox create --detach)
  • 用于固定远程文件系统读取和变更的 python3
  • 兼容 GNU 的 stat(-c)、readlink(-f)和 find
  • 标准的 mkdir、mv、rm 和 rmdir 工具

当代理工作区与沙箱工作区不同时,沙箱用户和策略还需要对两个已配置的远程根目录具有写权限。标准的非特权镜像通常无法创建默认的 /agent 目录。请在镜像和策略中创建并授予对 /agent 的访问权限,或者在已可写的沙箱根目录下方配置两个不重叠的目录。

{
  plugins: {
    entries: {
      openshell: {
        enabled: true,
        config: {
          remoteWorkspaceDir: "/sandbox/workspace",
          remoteAgentWorkspaceDir: "/sandbox/agent",
        },
      },
    },
  },
}

软件包安装和私有证书根必须包含在源镜像中,或在沙箱内部安装。所选 OpenShell 策略必须允许所需的网络目标,并且沙箱用户和文件系统必须允许写入。sandbox.docker.network、sandbox.docker.readOnlyRoot、sandbox.docker.user 和 sandbox.docker.setupCommand 不会配置 OpenShell。

当前限制

  • OpenShell 后端不支持沙箱浏览器。
  • 一个插件实例使用一个 OpenShell 工作区。不支持按智能体或按会话选择 OpenShell 工作区。
  • sandbox.docker.binds 不适用于 OpenShell。如果配置了 binds,沙箱创建将失败。
  • sandbox.docker.* 下特定于 Docker 的运行时配置项(env 除外)仅适用于 Docker 后端。
  • 原生插件代码和 Gateway RPC 保留在 Gateway 主机上。仅当沙箱工具策略允许时,插件拥有的工具和 MCP 工具才可用于沙箱会话。

故障排查

首先分别排查 OpenClaw Gateway 健康、插件激活和 OpenShell 网关连接:

openclaw gateway status --deep --require-rpc
openclaw plugins inspect openshell --runtime --json
openclaw sandbox explain
openclaw sandbox list
openshell gateway list
openshell sandbox list
openclaw logs --follow
  • 插件缺失或后端不可用: 安装 @openclaw/openshell-sandbox,设置 plugins.entries.openshell.enabled: true,验证配置,然后重新启动 OpenClaw Gateway。运行 openclaw plugins inspect openshell --runtime --json 检查正在运行的 Gateway,而不仅仅是磁盘上的插件注册。
  • 找不到 openshell: 为运行 Gateway 的用户安装 CLI,或将 plugins.entries.openshell.config.command 设置为其可执行文件的绝对路径。交互式 shell 能正常工作并不能证明托管服务具有相同的 PATH。
  • 没有活动网关、未授权或连接失败: 检查 openshell gateway list,选择目标网关,如果其部署需要登录,则使用 openshell gateway login <gateway-name> 重新认证。当服务不应依赖交互式 CLI 的活动选择时,请显式设置 plugins.entries.openshell.config.gateway。
  • 工作区缺失或沙箱列表不正确: 使用 openshell workspace list 验证所选的 OpenShell 工作区,然后运行 openshell --workspace <workspace-name> sandbox list。在 OpenClaw 中启用缺失的工作区之前,先使用 openshell workspace create --name <workspace-name> 创建它们。请记住,Gateway 服务可能不会继承交互式 shell 中的 OPENSHELL_WORKSPACE。
  • 无法读取策略文件或出站流量被拒绝: 使用绝对主机路径配置现有的 YAML 策略文件,检查其权限,并验证策略是否允许目标和请求方二进制文件。使用 openshell sandbox get <sandbox-name> --policy-only 检查正在运行的沙箱。Docker 网络设置不会改变 OpenShell 策略。
  • 提供商创建失败: 使用 openshell provider list 检查所选的 OpenShell 工作区,然后按照 OpenShell 文档中的凭据流程创建或刷新所需提供商。如果禁用了 autoProviders,则所需提供商必须已经存在。
  • 本地缺少远程文件: 这是 remote 模式下的预期行为。远程文件是权威文件,不会同步回主机。当需要主机可见的更改时,请使用 mirror 模式。重新创建远程沙箱会破坏其仅存在于远程的文件。
  • 无法发送图像或附件: 使用配置的 remoteWorkspaceDir 下的路径,例如 /sandbox/report.png,而不是假设每个后端都使用 Docker 的 /workspace 目录。
  • 镜像同步报告恢复路径: OpenClaw 将主机影子副本保留在工作区之外,因为其移动或恢复无法完成。错误会指明保留路径和工作区路径,并保留原始失败信息。在删除任一副本之前,请比较两个路径并恢复所需文件。部分移动可能在每个路径中留下不同的文件。OpenClaw 会保留其余的工作区条目,而不是用不完整或未经验证的备份覆盖它们。如果恢复已完成,且只有保留目录的清理失败,错误会确认已恢复的工作区路径,并指明残留目录。
  • 重新创建或清理无法删除沙箱: 恢复对原始 OpenShell 网关和工作区的访问,使用 openshell --workspace <workspace-name> sandbox get <sandbox-name> 确认沙箱仍然存在,然后重试相应的重新创建操作。OpenClaw 会一直保留注册表条目,直到删除成功。

工作原理

  1. OpenClaw 对沙箱名称运行 sandbox get(使用所选的 OpenShell 工作区以及任何已配置的 --gateway/--gateway-endpoint)。如果失败,它会使用 sandbox create 在同一个 OpenShell 工作区中创建一个沙箱,并传入 --name、--from、设置了时的 --policy、启用时的 --gpu、--auto-providers/--no-auto-providers,以及每个已配置提供商对应的一个 --provider 标志。
  2. OpenClaw 对沙箱名称运行 sandbox ssh-config 以获取 SSH 连接详细信息。
  3. 核心将 SSH 配置写入临时文件,并通过与通用 SSH 后端相同的远程文件系统桥接打开 SSH 会话。
  4. 在 mirror 模式下:执行前将本地同步到远程,运行后再同步回来。
  5. 在 remote 模式下:首次使用时初始化一次,然后直接在远程工作区上操作。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw