1. 为什么你的 OpenClaw 需要一个 Docker 技能沙箱
OpenClaw 这类 Agent 框架最吸引人的地方,就是它真的能替你动手:执行 Shell、读写文件、调用外部 API。但反过来看,这些能力也是它最危险的地方。一个没有隔离的实例,理论上任何技能都能读取~/.ssh/id_rsa、往/etc里写东西,甚至把整台机器当成跳板。我见过不少朋友在本地跑得挺爽,直到某个从技能商店随手装的插件在后台偷偷执行了一段混淆脚本,才意识到问题的严重性。
技能沙箱隔离要解决的核心问题就一句话:把高风险操作关进一个受限的 Docker 容器里,让模型即使"犯傻"也碰不到主机的敏感资源。它适合已经完成 OpenClaw 基础安装、懂一点 Docker 命令、并且打算把 Agent 用在真实工作流里的开发者。如果你只是本地玩玩、不接任何外部技能,那可以先跳过;但只要涉及文件写入、命令执行、网络请求,这套隔离就值得认真配一遍。
OpenClaw 官方给了两种互补策略。第一种是全量 Docker 运行,把整个 Gateway 塞进容器,隔离最彻底,适合高安全要求场景。第二种是工具沙箱,Gateway 留在主机上保持响应速度,只有每次工具调用(exec、read、write、edit)才进容器执行。生产环境我更推荐第二种,因为它在性能和安全之间取得了平衡。本文就围绕工具沙箱展开,给你一套可复制的配置、一份权限挂载清单,再演示一次越权操作被拦截的完整验证过程。
需要先明确一个认知:沙箱不是完美的安全边界。官方文档自己也说得很清楚,它的价值在于"当模型做出愚蠢行为时,实质性地限制了文件系统和进程访问"。换句话说,它挡的是意外和低级攻击,不是国家级对手。所以配置之外,供应链审查和定期审计同样不能省。
2. TaoToken 前置准备:把模型接入和沙箱配置分开做
在动手配沙箱之前,先把模型接入这条链路理顺,否则后面调试沙箱时你分不清是隔离策略的问题还是 API 调用的问题。我习惯把这两件事拆开:先用 TaoToken 把模型通道跑通,再单独调沙箱。
TaoToken 在这里扮演的是模型访问层。你可以把它理解成一个统一的入口,让你在 OpenClaw 里通过标准的 Base URL 和 API Key 去调用不同的大模型,而不用为每个模型单独折腾一套鉴权。对沙箱实验来说这很关键——因为沙箱里跑的是工具执行,模型决策在主机侧完成,两者解耦之后,你改沙箱配置不会影响模型通道,反之亦然。
具体操作上,先去控制台创建一个 API Key。打开 https://taotoken.net/console 登录后进入密钥管理页面,新建一个 Key 并复制保存。这个 Key 只显示一次,丢了就得重建。拿到之后,模型接入需要的三件套就是:
- Base URL:
https://taotoken.net/api - API Key:你在控制台生成的那串
- Model ID:按你实际要用的模型填写,比如对话类或编码类模型
如果你用的是 Claude Code 这类工具做代码辅助,接入文档在 https://taotoken.net/doc 有更细的说明。想先验证模型通道是否正常,可以直接去模型对话页面发一条测试消息,确认能收到回复再继续。对于长期跑编码和 Agent 任务的场景,Coding Plan 会更划算,适合把沙箱实验和日常开发放在同一条通道上。
这里要提醒一句:模型通道和沙箱是两层独立的安全域。TaoToken 管的是"模型能不能被调用",Docker 沙箱管的是"工具执行能碰到什么"。不要指望其中一层去弥补另一层的漏洞。把 Key 配好、模型能通,我们就可以进入沙箱配置了。
3. 可复制的沙箱配置:openclaw.json 里的隔离参数
OpenClaw 的沙箱配置集中在~/.openclaw/openclaw.json。下面这份是我实测下来比较稳的基础结构,你可以直接抄,再按需改:
{ "agents": { "defaults": { "sandbox": { "mode": "non-main", "scope": "session", "workspaceAccess": "none", "docker": { "network": "none", "binds": [] } } } } }三个核心参数得逐个说清楚,因为它们直接决定隔离强度。
mode控制"什么时候启用沙箱"。off是永不隔离,只适合开发测试;non-main表示只有非主会话才进沙箱,这是生产环境推荐值;all则是所有会话都隔离,安全要求最高但性能开销也最大。这里的"主会话"基于session.mainKey,默认是main。群组和频道会话各有自己的键,会被当成非主会话隔离;而你直接和 Agent 的私聊通常算主会话。所以non-main的实际效果是:私聊放行、外部来源隔离。
scope控制"创建多少容器"。session是每个会话一个容器,资源消耗高但隔离最彻底;agent是每个智能体一个容器,折中方案;shared是所有会话共用一个容器,资源最省但隔离最弱,不推荐。
workspaceAccess控制沙箱对 Agent 工作区的访问权限。none是默认值,工具只能看到独立的沙箱工作区;ro以只读方式挂载 Agent 工作区,适合需要读配置文件的技能;rw是读写挂载,最危险,除非绝对必要否则别用。
如果你要给不同职责的 Agent 配不同安全级别,可以在agents.list里逐个覆盖。比如一个面向家人的 Agent,我会把写操作全部禁掉:
{ "agents": { "list": [ { "id": "family", "sandbox": { "mode": "all", "scope": "agent", "docker": { "setupCommand": "apt-get update && apt-get install -y git curl" } }, "tools": { "allow": ["read"], "deny": ["exec", "write", "edit", "apply_patch"] } } ] } }关于tools.allow和tools.deny,有一条铁律:deny 的优先级高于 allow。哪怕某个工具同时出现在两个列表里,只要它在 deny 中,就会被拒绝。所以你可以放心地用 allow 列白名单、用 deny 兜底封杀高危项。
网络和挂载是另外两个容易踩坑的点。默认network: "none"意味着沙箱容器没有网络出口,这是最安全的。但如果你在setupCommand里要装软件,就必须临时开bridge网络并允许可写根文件系统,装完再关掉。docker.binds则允许把主机目录挂进容器,比如:
"binds": [ "/home/user/source:/source:ro" ]注意:ro只读标记,以及一个关键事实——绑定挂载是"逃生通道",它直接穿透沙箱文件系统暴露主机路径。像docker.sock、SSH 密钥这类敏感挂载,能不给就不给;非要给也必须只读。另外scope: "shared"时会忽略每智能体的绑定配置,这点要记牢。
4. 验证请求:亲手触发一次越权拦截
配置写完不算完,得实际验证隔离是否生效。我设计了一个最小验证流程,你可以照着复现。
第一步,确认沙箱容器能正常起来。重启 OpenClaw 后,在非主会话里发一条会触发工具调用的指令,比如让它读取一个文件。然后到主机上执行:
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"你应该能看到一个由 OpenClaw 拉起的沙箱容器在运行。如果看不到,说明 mode 或 scope 没生效,回去检查 JSON 是否被正确加载。
第二步,触发一次越权写操作。在会话里让 Agent 尝试往主机敏感路径写文件,比如/etc/hosts或~/.ssh/authorized_keys。因为workspaceAccess: "none"且没有绑定挂载,这个操作应该被拦下。你会看到类似"permission denied"或"path not allowed"的返回,而不是真的写进去。
第三步,验证网络隔离。让 Agent 尝试访问一个外部地址。在network: "none"下,请求会直接失败,报连接超时或网络不可达。这一步能确认沙箱没有偷偷放行外网。
第四步,用官方审计工具做一次体检:
openclaw security audit它会检查入站访问控制、网络暴露面、本地文件权限、Gateway 认证配置和配对策略。想更激进一点可以跑openclaw security audit --deep,它会模拟攻击者视角做深度探测;--fix则能自动修复一批常见问题。审计报告里如果出现"沙箱未启用"或"工作区可写"之类的告警,就说明你的配置还有缺口。
实测下来,这套验证跑通之后,你对隔离边界的信心会踏实很多。重点不是看它"能不能拦",而是看它"拦的时候报什么错"——错误信息越明确,后续排障越省事。
5. 本篇常见错排查:401、local proxy failed 与 OAuth 报错
沙箱配置过程中,报错往往来自两个层面:模型通道和容器执行。分清楚才能快速定位。
401 Unauthorized基本都出在模型通道。原因通常是 API Key 没填对、复制时带了空格,或者 Key 已失效。排查方法是回到 TaoToken 控制台确认 Key 状态,然后检查 OpenClaw 配置里 Base URL 是否为https://taotoken.net/api、Key 是否完整。注意 Base URL 不要带多余路径,也不要加 UTM 参数。
local proxy failed这类错误通常和网络策略有关。如果你在沙箱里配了network: "none",但某个技能又试图走本地代理,就会失败。这时候要么给该技能单独放行网络,要么确认它根本不需要联网。还有一种情况是主机侧的代理配置和沙箱网络策略冲突,检查一下环境变量里有没有残留的代理设置。
reading choices 报错一般出现在模型返回结构异常时。可能是 Model ID 填错,导致返回体不是预期的对话格式;也可能是通道临时抖动。先确认 Model ID 和 TaoToken 文档一致,再重试一次。如果持续出现,换一个模型验证是不是通道问题。
OAuth 相关报错多发生在用 Claude Code 或类似工具接入时。这类工具对鉴权方式有特定要求,需要按接入文档配置。如果你在 OpenClaw 里同时用了 OAuth 和 API Key 两套鉴权,容易互相干扰,建议只保留一套。
排查时有个通用思路:先隔离变量。把沙箱配置临时改成mode: "off",如果问题消失,说明是隔离策略导致的;如果问题还在,那就是模型通道或工具本身的问题。这个二分法能帮你省下大量瞎猜的时间。
另外,如果你在配置里用到了 CC Switch、Cline MCP 或 Codex 的auth.json,务必把三件套写全:Base URL、Key、Model ID。缺任何一个都会导致鉴权失败,而且报错信息往往不会直接告诉你缺了哪个。
6. 把隔离变成习惯:持续运维与下一步
配好沙箱只是起点。安全这件事没有"一劳永逸",只有"持续运维"。我的做法是每月跑一次openclaw security audit,关注 OpenClaw 官方的安全公告,补丁出来就及时应用。技能安装前用clawhub inspect <slug>审查代码,看到诱导执行npm install、pip install或远程脚本下载的,直接跳过。那些打着"自动赚钱""破解"旗号的技能,基本可以判定为高风险。
工具白名单也要定期复盘。生产环境至少保持mode: "non-main",用专用低权限账户运行 OpenClaw,只开放专用工作目录,禁止访问~/.ssh、/etc这类敏感路径。高危工具如 shell、browser 写权限,能禁就禁。
如果你想把模型通道和沙箱实验放在同一条链路上,可以先把 API Key 备好:https://taotoken.net/api-keys ,接入细节看文档 https://taotoken.net/doc ,验证模型是否通就去模型对话页面发一条消息。长期跑编码和 Agent 任务的话,Coding Plan 会更省心。沙箱管住"手",模型通道管住"脑",两层都稳了,你的 OpenClaw 才算真正能放心用。