
1. 为什么你的 OpenClaw 需要一个真正的“安全锁”如果你正在本地跑 OpenClaw曾用名 Clawdbot、Moltbot大概率已经体验过它“主动执行”的爽感能读写文件、能跑 Shell、能操作浏览器甚至能帮你整理邮箱。但爽感背后有个被很多人忽略的事实——OpenClaw 默认的执行器往往和你的宿主机共享同一套内核。这意味着大模型一旦被提示词注入诱导生成一条rm -rf ~/Documents或者一个反弹 Shell它跑起来和你自己手动敲下去没有任何区别。我见过最典型的事故场景是这样的你让 Agent 帮忙清理一下临时目录它理解成“清理所有不重要的文件”然后开始遍历你的家目录。你在手机上发“停止”但它已经进入了自主执行循环根本不看你的新指令。最后你只能冲到电脑前强制杀进程。这不是段子这是 OpenClaw 这类“持久记忆 主动执行”型 Agent 的固有风险它的信任边界是模糊的而它的执行权限是真实的。传统做法是套一层 Docker。但 Docker 容器和宿主机共享 Linux 内核namespace 和 cgroup 只是逻辑隔离不是物理隔离。内核提权漏洞一旦被利用容器逃逸就是分分钟的事。对于本地部署、还挂着公司内网网卡的机器来说这等于把执行不可信代码的入口直接开在了内网边缘。所以这篇要聊的是给 OpenClaw 换一个硬件级隔离的执行底座基于 E2B 的 MicroVM 沙箱。E2B 底层用的是 Firecracker MicroVM每个沙箱是一台独立的轻量级虚拟机有自己独立的内核不共享宿主机的内核空间。恶意代码在沙箱里再怎么折腾也穿透不了 KVM 的硬件虚拟化边界。同时它用内存快照恢复技术把冷启动压到 150ms–300ms 级别不会让你等一个“虚拟机开机”等到对话都凉了。这篇文章面向的是已经在本地或内网部署 OpenClaw、想给它的代码执行能力加一道硬隔离的读者。我会给出可复制的 E2B 沙箱配置、OpenClaw 侧的接入骨架、以及验证隔离是否真正生效的动作。你不需要先成为虚拟化专家跟着配置走就能复现。2. TaoToken 前置把模型调用和沙箱执行拆成两条链路在动手配沙箱之前先把一个架构原则说清楚模型推理链路和代码执行链路要分开治理。OpenClaw 的“大脑”负责规划、记忆、工具选择这部分走的是大模型 API而“手脚”负责真正跑代码、跑命令这部分必须关进沙箱。两条链路的安全等级完全不同混在一起配就是给自己埋雷。模型侧我建议统一走 TaoToken 的 API 网关来收口。原因很实际OpenClaw 在自主执行时会频繁调用模型做多步推理如果每个模型供应商的 Key 散落在环境变量里一旦 Agent 被诱导去读取环境变量你的所有 Key 就一次性泄露了。把模型调用收敛到一个网关后面至少能做到 Key 不直接暴露在 Agent 可触达的进程环境里。TaoToken 的接入地址是https://taotoken.net/api兼容 OpenAI 风格的接口。你可以在 OpenClaw 的模型配置里把 Base URL 指向它然后用统一的 Key 去调用不同模型。这样 OpenClaw 侧只需要维护一份凭证沙箱侧完全不需要知道任何模型 Key。具体操作上先去控制台创建一个 API Key控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建好之后你会在 OpenClaw 的配置里用到三个东西Base URL、API Key、Model ID。这三个就是后面所有配置的“三件套”缺一个都跑不通。Model ID 按你实际要用的模型填比如做代码生成和工具调用比较多的场景选一个指令跟随能力强的就行。这里有个容易踩的坑很多人把模型 Key 直接写进 OpenClaw 的 skill 脚本里然后这个 skill 又是在沙箱里执行的。这就等于把钥匙插在锁上还挂在门外。正确做法是模型调用发生在 OpenClaw 主进程侧沙箱里只接收“要执行什么代码”的指令不接触任何凭证。如果你还没决定用哪个模型可以先去模型对话页面试一下指令跟随和代码生成的效果https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite对于长期跑编码类 Agent 任务的可以考虑 Coding Plan它在多轮工具调用场景下的额度策略更适合 OpenClaw 这种“规划—执行—再规划”的循环https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite把模型链路收口之后我们才有底气去谈沙箱因为沙箱里跑的东西理论上可以完全不知道模型的存在它只是一个“执行器”。3. 可复制配置E2B 沙箱与 OpenClaw 接入骨架这一节是全文的核心我会给出可以直接抄的配置片段。先说明一点E2B 有官方托管版也支持自建 infra。如果你在内网环境自建更可控如果只是本地加固用官方 SDK 连托管沙箱也能达到隔离效果。下面以自建/自托管场景为主因为“硬件级隔离”的价值在内网部署里才最大化。3.1 E2B 沙箱侧配置E2B 的沙箱通过模板template定义运行环境。你需要一个e2b.toml来描述沙箱的基础镜像、启动命令和资源限制。下面是一个面向 OpenClaw 代码执行场景的最小配置# e2b.toml template_id openclaw-code-sandbox dockerfile e2b.Dockerfile [resources] cpu_count 2 memory_mb 2048 [network] # 默认阻断所有出站只放行白名单 allow_out [ pypi.org, registry.npmjs.org, github.com ] deny_out [ 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 ] [lifecycle] # 沙箱空闲多久后自动销毁单位秒 timeout 300 # 是否在任务结束后立即销毁保证无状态 ephemeral true配套的e2b.Dockerfile只需要一个带常用运行时的基础镜像# e2b.Dockerfile FROM e2b/base:python-3.11 RUN apt-get update apt-get install -y --no-install-recommends \ curl git build-essential \ rm -rf /var/lib/apt/lists/* # 预装 OpenClaw 常用的 Python 依赖 RUN pip install --no-cache-dir pandas numpy requests WORKDIR /home/user这里的关键点有三个。第一deny_out里显式封掉了 RFC1918 内网网段这是防止沙箱内代码横向扫描内网的第一道闸。第二ephemeral true保证任务结束即销毁CoW 临时层被 Drop不留状态。第三timeout给一个合理的空闲回收时间避免沙箱泄漏占资源。3.2 OpenClaw 侧接入骨架OpenClaw 侧你需要一个 skill 或者 executor 模块负责“向沙箱下发代码、拿回结果”。下面是一个 Python 骨架用 E2B SDK 建立连接并执行代码# openclaw_e2b_executor.py import os from e2b_code_interpreter import Sandbox E2B_API_KEY os.environ[E2B_API_KEY] E2B_DOMAIN os.environ.get(E2B_DOMAIN, api.e2b.dev) def run_in_sandbox(code: str, timeout: int 60) - dict: 在 E2B MicroVM 沙箱中执行代码返回 stdout/stderr/结果。 沙箱生命周期与本次调用绑定执行完即销毁。 with Sandbox( api_keyE2B_API_KEY, domainE2B_DOMAIN, templateopenclaw-code-sandbox, timeouttimeout, ) as sbx: execution sbx.run_code(code) return { stdout: execution.logs.stdout, stderr: execution.logs.stderr, error: execution.error, results: [r.text for r in execution.results], } if __name__ __main__: result run_in_sandbox(import platform; print(platform.platform())) print(result)如果你用的是自建 E2B infra把E2B_DOMAIN指向你自己的域名比如E2B_DOMAINaisandbox.yourdomain.net。E2B_API_KEY从你的沙箱服务端申请。然后在 OpenClaw 的 skill 定义里把这个 executor 注册成一个工具。OpenClaw 的 skill 通常是一个描述文件加一个执行入口你可以在 skill 里声明“当需要执行代码时调用run_in_sandbox”。这样 OpenClaw 的规划层决定“要跑一段 Python”执行层就把它丢进 MicroVM拿回结果继续推理。3.3 模型侧配置三件套OpenClaw 调用模型的配置里把 Base URL、Key、Model ID 填成 TaoToken 的{ model_provider: { base_url: https://taotoken.net/api, api_key: sk-你的TaoToken密钥, model_id: 你的模型ID } }注意这个配置属于 OpenClaw 主进程不要放进沙箱模板里。沙箱里跑的代码不应该能读到这个文件。4. 验证请求确认隔离真的生效了配置写完不代表隔离生效你得实际验证。下面几个动作是我实测下来最能说明问题的。4.1 验证沙箱内看不到宿主机文件在沙箱里执行import os print(os.listdir(/)) print(os.path.exists(/proc/1/root/home))如果隔离正常你看到的是沙箱自己的根文件系统/proc/1/root指向的是沙箱内部的 init 进程而不是宿主机的根目录。Docker 容器里这个路径往往能摸到宿主机的影子MicroVM 里则完全看不到。4.2 验证内网不可达在沙箱里尝试访问一个内网地址import socket s socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(3) try: s.connect((10.0.0.1, 80)) print(内网可达隔离失败) except Exception as e: print(内网不可达隔离生效:, e)因为我们在e2b.toml里 deny 了10.0.0.0/8这里应该超时或拒绝。如果居然通了说明网络策略没加载回去检查 Egress 规则。4.3 验证任务结束即销毁连续两次调用run_in_sandbox第一次写一个文件第二次读它run_in_sandbox(open(/tmp/test.txt,w).write(hello)) result run_in_sandbox(import os; print(os.path.exists(/tmp/test.txt))) print(result[stdout]) # 应该是 False如果第二次还能读到文件说明沙箱被复用了ephemeral没生效。真正的无状态沙箱每次都是全新的 CoW 层。4.4 验证模型调用链路在 OpenClaw 主进程里发一个简单的模型请求确认 Base URL 指向 TaoToken 后能正常返回curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的密钥 \ -H Content-Type: application/json \ -d { model: 你的模型ID, messages: [{role: user, content: 回复 OK}] }返回正常说明模型链路通了。这一步和沙箱是独立的但两者都通整个“大脑 手脚”的链路才算完整。5. 本篇常见错排查配置过程中最容易撞上的几个报错我按实际遇到的频率排一下。401 Unauthorized模型侧报这个八成是 API Key 没填对或者 Base URL 少了/api。TaoToken 的接口地址是https://taotoken.net/api不是根域名。检查你的base_url字段别写成https://taotoken.net。沙箱侧报 401检查E2B_API_KEY是否从正确的服务端申请自建 infra 的 Key 和托管版的 Key 不通用。local proxy failed / connection refused这个通常出现在自建 E2B infra 的场景。沙箱控制面在宿主机上监听一个本地端口OpenClaw 通过它建立 VSOCK 隧道。如果报 proxy failed先确认控制面进程活着再确认E2B_DOMAIN解析到的地址和端口对得上。防火墙拦了本地回环端口也会导致这个错。Error reading choices / 返回体解析失败模型调用返回了非预期结构常见于 Model ID 填错或者请求发到了不兼容的端点。确认你用的 Model ID 在 TaoToken 侧是有效的并且请求路径是/v1/chat/completions。如果 OpenClaw 内部用的是 OpenAI SDKBase URL 末尾不要多加/v1SDK 会自己拼。OAuth / token 过期类报错如果你在 OpenClaw 里用了带 OAuth 的模型接入方式注意 OAuth token 和 API Key 是两套东西。走 TaoToken 的 API Key 模式就不涉及 OAuth 刷新反而少一层故障点。遇到 OAuth 报错直接切到 API Key 模式。沙箱启动超时如果冷启动超过 1 秒检查你的模板是不是太大。E2B 的快照恢复依赖预构建的 Memory Snapshot模板里装太多东西会拖慢构建和恢复。把非必要的依赖挪到运行时按需安装或者拆成多个专用模板。CC Switch / Cline MCP / Codex auth.json 相关如果你在 OpenClaw 生态里同时用了这些工具记住它们的凭证文件比如auth.json不要放在沙箱可读的路径下。沙箱里只需要 Base URL、Key、Model ID 三件套中的“执行指令”不需要任何凭证。凭证统一留在主进程侧。6. 把安全锁真正拧紧从配置到习惯配完这一套你得到的是这样一条链路OpenClaw 的规划层通过 TaoToken 调用模型模型返回“要执行什么”执行层把代码丢进 E2B MicroVM沙箱在硬件虚拟化边界内跑完结果流式返回沙箱销毁。模型 Key 不进入沙箱内网不可达状态不残留。但配置只是第一步。真正让安全锁生效的是习惯任何来自模型的代码默认都当不可信代码处理一律走沙箱沙箱模板的 Egress 白名单按最小权限维护需要访问新域名时显式加而不是图省事全放开定期用第 4 节的验证动作回归一遍确认隔离策略没有被后续改动破坏。如果你还没把模型链路收口建议先去 API Keys 页面把 Key 建好再按第 3 节的配置把 OpenClaw 的模型 Base URL 指过去https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite接入文档里有各语言 SDK 的调用示例照着改 Base URL 就行https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite长期跑编码和 Agent 任务的Coding Plan 的额度模型更适合这种高频工具调用场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite最后留一个我踩过的坑沙箱的timeout别设太长。我一开始设了 3600 秒结果一个卡死的任务把沙箱占了一小时资源没释放。后来改成 300 秒空闲回收配合任务级超时既够用又不浪费。安全锁不只是防外部攻击也包括防自己把资源跑飞。