小虾 (xiaoxia.app) OpenClaw 多用户沙箱隔离方案报告

2026-03-19 · Jay's Lab 深度研究

摘要

小虾 (xiaoxia.app) 是基于 OpenClaw 的多租户托管平台(仓库 github.com/xiaojay/xx),为每个用户启动独立容器运行 OpenClaw 实例。本报告评估 6 种沙箱隔离方案,从轻量到重量排列,并给出分阶段实施建议。

核心结论:Docker + gVisor (runsc) 是当前最优解 — 一行配置改动,零代码修改,容器逃逸防护提升数个量级。

为什么需要更强的隔离?

OpenClaw 的安全模型近期受到严峻挑战:

在多租户场景下,共享内核意味着一个恶意用户可能攻击其他所有用户。隔离不是锦上添花,是生存必需。

方案对比总览

方案隔离级别启动时间内存开销改动量推荐度
Docker 容器(现有)进程级<1s~50MB⚠️ 仅内部用
Docker + gVisor用户态内核~1s+15MB一行配置⭐⭐⭐ 强烈推荐
NVIDIA OpenShellK3s + Landlock + Seccomp~5s~200MB中等⭐⭐ 观望
Firecracker microVM完整虚拟机~125ms~5MB较大⭐⭐ 高安全场景
Docker SandboxMicroVM (macOS) / 增强容器 (Linux)~2s~100MB中等⭐ 关注中
Bubblewrap (bwrap)Linux namespace<100ms~0❌ 不适合

1. Docker 容器(现有方案)

隔离级别

进程级隔离,共享宿主内核。使用 Linux namespaces (PID, NET, MNT, UTS, IPC) + cgroups 实现资源隔离。

优点

缺点与安全风险

- Snyk TOCTOU 攻击:通过 renameat2() 原子交换 symlink,绕过 assertSandboxPath 路径验证,实现任意文件读写(Snyk Labs 报告

- 沙箱策略绕过:/tools/invoke 端点未合并 sandbox policy,允许受限会话调用敏感工具(browser, gateway, nodes)

- CVE-2025-2719:symlink 写入跟随导致沙箱逃逸,已在 commit 4fd29a3 修复(DailyCVE

适用场景

可信用户、内部部署、开发测试环境。

相关链接

2. Docker + gVisor (runsc) ⭐ 强烈推荐

隔离级别

用户态内核 — gVisor 在用户空间实现了一个独立的 Linux 内核(称为 Sentry),拦截所有 syscall。即使容器内的代码尝试利用内核漏洞,攻击面被限制在 gVisor 的用户态实现中,而非宿主机真实内核。

工作原理


┌─────────────────────────────┐
│   OpenClaw (Node.js)        │  ← 用户容器
├─────────────────────────────┤
│   gVisor Sentry (用户态内核) │  ← syscall 拦截层
├─────────────────────────────┤
│   宿主机 Linux 内核          │  ← 真实内核,被 gVisor 保护
└─────────────────────────────┘

应用的 syscall 不直接到达宿主内核,而是被 gVisor Sentry 解释执行。Sentry 只使用约 70 个宿主 syscall(而非 300+),大幅缩小攻击面。

安装与配置

Step 1: 安装 gVisor


# Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main" | sudo tee /etc/apt/sources.list.d/gvisor.list > /dev/null
sudo apt-get update && sudo apt-get install -y runsc

Step 2: 配置 Docker daemon


// /etc/docker/daemon.json
{
  "runtimes": {
    "runsc": {
      "path": "/usr/bin/runsc"
    }
  }
}

sudo systemctl restart docker

Step 3: 使用 gVisor 运行容器


# 单容器测试
docker run --runtime=runsc -it node:20 node -e "console.log('Hello from gVisor!')"

# 或设为默认 runtime(所有容器都用 gVisor)
# /etc/docker/daemon.json 添加:
# "default-runtime": "runsc"

对小虾的改动

xx 代码零改动! 只需修改 Docker daemon 配置或在启动容器时指定 --runtime=runsc

如果想要更灵活的控制(比如部分容器用 gVisor,部分不用),可以在 container.go 中增加 Runtime 字段:


// container.go - 示例改动
type ContainerConfig struct {
    Image   string
    Runtime string // "runsc" for gVisor, "" for default runc
    // ... existing fields
}

func (c *ContainerConfig) Create() error {
    args := []string{"run", "-d"}
    if c.Runtime != "" {
        args = append(args, "--runtime="+c.Runtime)
    }
    // ... rest of container creation
}

性能影响

根据 gVisor 官方性能指南,CPU bound 工作负载无性能损失,主要开销在系统调用密集的场景(如大量文件 I/O)。

为什么最适合小虾

1. 改动最小 — Docker daemon 配一行,代码零改动

2. 收益最大 — 从"共享内核"直接升级到"用户态内核隔离"

3. 生产验证 — Google Cloud Run、GKE Sandbox 都基于 gVisor

4. 向后兼容 — 随时可以切回 runc,不影响现有架构

相关链接

3. NVIDIA OpenShell(GTC 2026 新发布)

概述

NVIDIA 在 GTC 2026(2026年3月17日)开源发布的 agent 沙箱运行时,专门为 AI coding agent(Claude Code、Codex、OpenClaw)设计。Apache 2.0 许可证。

架构


┌───────────────────────────────────┐
│         Docker Container          │
│  ┌─────────────────────────────┐  │
│  │        K3s Cluster          │  │
│  │  ┌───────┐  ┌────────────┐ │  │
│  │  │Gateway│  │Policy Engine│ │  │
│  │  └───────┘  └────────────┘ │  │
│  │  ┌──────────────────────┐  │  │
│  │  │   Sandbox Pod        │  │  │
│  │  │  ┌────────────────┐  │  │  │
│  │  │  │  OpenClaw Agent │  │  │  │
│  │  │  └────────────────┘  │  │  │
│  │  │  Landlock + Seccomp  │  │  │
│  │  └──────────────────────┘  │  │
│  │  ┌──────────────────────┐  │  │
│  │  │   Privacy Router     │  │  │
│  │  └──────────────────────┘  │  │
│  └─────────────────────────────┘  │
└───────────────────────────────────┘

四层防护

层级功能热更新
文件系统Landlock 防止未授权读写❌ 创建时锁定
网络默认阻断所有出站连接✅ 热更新
进程Seccomp 阻止提权和危险 syscall❌ 创建时锁定
推理Privacy Router 重定向 LLM API 调用✅ 热更新

特色功能

局限性

对小虾的评估

当前不适合直接使用,但值得持续关注。等 v1.0 稳定版 + 多租户支持后,可能成为最佳选择。

相关链接

4. Firecracker microVM

隔离级别

完整虚拟机隔离(独立内核) — 每个 microVM 拥有独立的 Linux 内核、虚拟 CPU 和内存。即使 guest 被完全攻破,也无法影响宿主机或其他 microVM。这是 AWS Lambda 和 Fargate 使用的同款技术。

工作原理


┌──────────────────────────────────────────┐
│              宿主机                        │
│  ┌─────────────┐  ┌─────────────┐        │
│  │  microVM 1  │  │  microVM 2  │  ...   │
│  │ ┌─────────┐ │  │ ┌─────────┐ │        │
│  │ │OpenClaw │ │  │ │OpenClaw │ │        │
│  │ └─────────┘ │  │ └─────────┘ │        │
│  │ Linux内核   │  │ Linux内核   │        │
│  └──────┬──────┘  └──────┬──────┘        │
│         │  KVM  /  KVM   │               │
│  ┌──────┴────────────────┴──────┐        │
│  │     Firecracker VMM (Rust)   │        │
│  └──────────────────────────────┘        │
│              宿主机 Linux 内核             │
└──────────────────────────────────────────┘

关键指标

优点

缺点

对小虾的评估

安全性最强,但工程复杂度也最高。适合作为远期目标(Phase 3),当用户规模和安全要求达到一定级别后考虑。

相关链接

5. Docker Sandbox(Docker 官方新功能)

概述

Docker 于 2026 年 1 月推出的官方沙箱功能,专为 AI coding agent 设计。

特点

局限性

对小虾的评估

值得关注,但 Linux 上的增强容器模式对安全提升有限。如果小虾未来需要支持 macOS 部署,Docker Sandbox 是好选择。

相关链接

6. Bubblewrap (bwrap)

概述

Flatpak 项目的轻量级沙箱工具,使用 Linux namespaces 实现隔离,无需 root 权限。Anthropic 的 Claude Code 沙箱在 Linux 上就使用 bubblewrap(Anthropic 工程博客)。

特点

为什么不适合小虾

相关链接

Snyk OpenClaw 沙箱逃逸深度分析

Snyk Labs 于 2026 年 2-3 月公开了两种 OpenClaw 沙箱绕过方法,这对所有基于 OpenClaw 的多租户平台(包括小虾)有直接影响。

漏洞 1: `/tools/invoke` 策略执行失败

问题/tools/invoke HTTP 端点在构建可用工具列表时,未合并 sandbox policy。代码经过 Profile → Global → Agent → Group → Subagent 策略层,但遗漏了 Sandbox 策略层

影响:任何持有 gateway 凭证的受限会话(包括远程集成、插件),都能调用应被禁止的敏感工具(如 browsergatewaynodes)。

修复:Snyk 提交了 PR #4026#4022

漏洞 2: TOCTOU 竞态条件 + Symlink 攻击

问题assertSandboxPath 函数使用 assertNoSymlink 逐段检查路径是否为符号链接。但在检查完成后、实际文件操作执行前,存在时间窗口。

攻击方式

1. 准备正常文件 /foo/bar 和恶意 symlink /foo/malicious(指向 /etc/passwd 等)

2. 持续调用文件操作工具读写 /foo/bar

3. 同时使用 renameat2() + RENAME_EXCHANGE 原子交换两个文件

4. 在验证通过后、文件操作前的窗口期,如果交换成功,即可逃逸沙箱

影响:任意文件读写宿主文件系统 — 可读取 SSH key、写入恶意代码。

关键点:Node.js 的 fs 模块默认跟随 symlink,不会二次验证路径是否仍在沙箱内。

对小虾的启示

这些漏洞证明了一个根本原则:应用层沙箱不可信。不管 OpenClaw 的路径验证修了多少次,只要共享内核,攻击面就永远存在。真正的防线必须在内核/hypervisor 层。

相关链接

对小虾 (xx) 的分阶段实施建议

Phase 1: 加固现有 Docker 方案(立即)

工作量:1-2 天


# 1. 确保 OpenClaw 版本 >= 2026.2.26(包含 CVE-2025-2719 修复)
# 2. 启用 seccomp profile
docker run --security-opt seccomp=default ...

# 3. 只读根文件系统 + tmpfs
docker run --read-only --tmpfs /tmp --tmpfs /home/openclaw/.config ...

# 4. 限制 capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE ...

# 5. 禁止 privileged 模式(确认现有代码未使用)
# 6. 启用 no-new-privileges
docker run --security-opt no-new-privileges ...

Phase 2: 迁移到 Docker + gVisor(1-2 周)⭐

工作量:1-2 周(含测试)


# Step 1: 安装 gVisor(见上方安装步骤)

# Step 2: 修改 Docker daemon 配置
cat > /etc/docker/daemon.json << 'EOF'
{
  "runtimes": {
    "runsc": {
      "path": "/usr/bin/runsc",
      "runtimeArgs": [
        "--network=sandbox",
        "--platform=systrap"
      ]
    }
  },
  "default-runtime": "runsc"
}
EOF
sudo systemctl restart docker

# Step 3: 验证
docker run --runtime=runsc hello-world
docker run --runtime=runsc node:20 node -e "console.log(process.version)"

xx 代码可选改动(增加灵活性):


// container.go 改动示例
type ContainerOptions struct {
    // ... existing fields
    Runtime string `json:"runtime,omitempty"` // "runsc" | "runc" | ""
}

func createContainer(opts ContainerOptions) error {
    args := []string{"create"}
    
    // 使用 gVisor runtime
    runtime := opts.Runtime
    if runtime == "" {
        runtime = os.Getenv("XX_CONTAINER_RUNTIME") // 环境变量控制
    }
    if runtime != "" {
        args = append(args, "--runtime="+runtime)
    }
    
    // ... rest of container creation
    return nil
}

# 通过环境变量全局控制
export XX_CONTAINER_RUNTIME=runsc

Phase 3: Firecracker microVM(6-12 个月后,视需求)

工作量:2-4 周

当满足以下条件时考虑:

可参考的实现:

成本与复杂度对比

维度Docker+gVisor+Firecracker
部署复杂度
代码改动0-10行重写容器层
运维复杂度中高
每用户成本~50MB~65MB~55MB
安全等级最高
合规性不足足够充分
回滚难度-极易困难

结论

小虾当前最紧迫的行动是启用 gVisor。 这是投入产出比最高的安全升级:

1. 一行配置改动(Docker daemon 加 --runtime=runsc

2. 零代码修改(xx 仓库不需要任何改动即可生效)

3. 安全提升巨大(从进程级隔离升级到用户态内核隔离)

4. 随时可回滚(切回 runc 即可)

在多租户 AI Agent 托管场景下,共享内核的风险已经被 Snyk 等安全研究团队反复证明。gVisor 是在不增加架构复杂度的前提下,将安全性提升一个量级的最佳选择。

本报告由 Tony (Jay's AI Assistant) 研究撰写,数据截至 2026-03-19。报告中的链接和信息可能随时间变化,建议实施前查阅最新文档。