🤖 妙趣AI

OpenClaw 技能沙箱与安全隔离

你不信任Agent写的代码?很好,说明你活下来了。

📌 功能介绍

技能沙箱(Skill Sandbox)是OpenClaw的安全基础设施。它将Agent执行的代码和操作隔离在受控环境中,防止恶意或意外的代码访问系统资源、窃取数据或破坏系统。简单说:给Agent一个沙盒,让它在里面玩泥巴,别把房子弄脏了。

💡 妙趣提示:沙箱不是「信任Agent不会犯错」,而是「即使Agent犯了错,损失也被控制在最小范围」。这是完全不同的安全哲学——把「信任」变成「隔离」。

🛠️ 使用方法

1. 沙箱配置

# sandbox-config.yaml
sandbox:
  runtime: "nsjail"  # nsjail | gvisor | firecracker | wasm
  
  nsjail:
    mode: "clone_newnet"  # 网络隔离
    maxCpus: 2
    maxMem: 512MB
    timeout: 30s
    mountProc: false
    mountPts:
      - src: "/data/shared/readonly"
        dst: "/data/readonly"
        isBind: true
        rw: false
    
  gvisor:
    platform: "ptrace"
    network: "sandbox"
    
  wasm:
    runtime: "wasmtime"
    allowWasi: true
    maxMemory: "256MB"

permissions:
  filesystem:
    read:
      - "/data/agent/workspace/**"
      - "/tmp/agent/**"
    write:
      - "/tmp/agent/**"
    deny:
      - "/etc/**"
      - "/root/**"
      - "/var/log/**"
  
  network:
    allowOutbound: true
    allowedHosts:
      - "api.openai.com"
      - "api.github.com"
    deniedPorts: [22, 23, 25, 3389]
  
  process:
    maxProcesses: 5
    maxOpenFiles: 100
    
  system:
    allowEnvRead: true
    allowEnvWrite: false
    allowSyscalls: false

2. 为技能启用沙箱

# 通过配置文件
# skill-config.yaml
skills:
  - name: "user-code-executor"
    sandbox:
      enabled: true
      runtime: "wasm"
      timeout: "10s"
      memoryLimit: "128MB"
      networkAccess: false
      
  - name: "web-scraper"
    sandbox:
      enabled: true
      runtime: "gvisor"
      timeout: "60s"
      memoryLimit: "256MB"
      networkAccess: true
      allowedHosts:
        - "example.com"
        - "docs.python.org"

# 通过CLI
openclaw skill sandbox --skill user-code-executor \
  --enable \
  --runtime wasm \
  --timeout 10s \
  --memory 128MB \
  --no-network

3. 权限级别

# 定义权限模板
openclaw permission template create --name "readonly-data" \
  --permissions "fs:read:/data/**,net:deny,proc:deny"

openclaw permission template create --name "sandboxed-code" \
  --permissions "fs:read:/tmp/**,fs:write:/tmp/**,net:deny,proc:limit:5"

openclaw permission template create --name "web-access" \
  --permissions "fs:deny,net:allow:api.github.com,proc:deny"

# 为技能分配权限模板
openclaw skill assign-permissions \
  --skill data-analyzer \
  --template readonly-data

🏆 最佳实践

沙箱策略选择

场景 运行时 安全等级
用户提交的代码 Wasm / Firecracker 🔒 最高
可信的第三方技能 gVisor 🔐 高
内部开发的技能 nsjail 🔑 中等
核心系统技能 无沙箱 ⚠️ 低(需审计)
⚠️ 重要:沙箱不是银弹!侧信道攻击(如时间攻击、缓存攻击)可能绕过沙箱隔离。对于处理高度敏感数据的场景,建议结合硬件隔离(如SGX/TDX)使用。

💻 代码示例

安全代码执行器

const { SandboxExecutor } = require('@openclaw/sandbox');

async function safeCodeExecution(code, language) {
  const executor = new SandboxExecutor({
    runtime: 'wasm',
    timeout: 10000,
    memoryLimit: '128MB',
    networkAccess: false,
    filesystemAccess: {
      read: ['/data/input/'],
      write: ['/tmp/output/']
    }
  });
  
  // 设置安全约束
  executor.setConstraints({
    maxOutputSize: '1MB',
    maxCPU: 5000,  // 5秒CPU时间
    disableSyscalls: ['fork', 'exec', 'ptrace', 'mount']
  });
  
  try {
    const result = await executor.run(code, {
      language,
      stdin: 'input data here',
      env: { SANDBOX_MODE: 'true' }
    });
    
    return {
      success: true,
      stdout: result.stdout,
      stderr: result.stderr,
      exitCode: result.exitCode,
      executionTime: result.duration,
      memoryUsed: result.peakMemory
    };
    
  } catch (error) {
    if (error.code === 'TIMEOUT') {
      return { success: false, error: '代码执行超时(10秒限制)' };
    } else if (error.code === 'MEMORY_LIMIT') {
      return { success: false, error: '内存超限(128MB限制)' };
    } else if (error.code === 'SANDBOX_VIOLATION') {
      return { success: false, error: `安全违规: ${error.detail}` };
    }
    throw error;
  }
}

权限验证中间件

function createPermissionGuard(requiredPermissions) {
  return async function(ctx, next) {
    const skillPerms = ctx.skill.permissions || [];
    
    for (const required of requiredPermissions) {
      const [resource, action, path] = required.split(':');
      
      const allowed = skillPerms.some(perm => {
        if (perm.resource !== resource || perm.action !== action) return false;
        if (path && !matchPath(path, perm.path)) return false;
        return true;
      });
      
      if (!allowed) {
        throw new Error(`权限不足: 需要 ${required},技能 ${ctx.skill.name} 未授权`);
      }
    }
    
    await next();
  };
}

// 使用示例
app.post('/api/execute', 
  createPermissionGuard(['fs:write:/tmp/**', 'proc:limit:5']),
  async (ctx) => {
    // 执行代码(已验证权限)
    const result = await executeInSandbox(ctx.request.body.code);
    ctx.body = result;
  }
);

🔗 相关链接

📅 更新时间:2026-05-11 | 📖 更多OpenClaw教程请访问 工具教程索引