Skip to content

Latest commit

 

History

History
857 lines (686 loc) · 27.3 KB

File metadata and controls

857 lines (686 loc) · 27.3 KB

🔒 MicroVM 安全隔离方案

提案日期: 2026-02-04 状态: 设计阶段 优先级: 🔴 高 (安全关键)


📋 问题陈述

当前安全架构的局限性

OpenCLI 当前拥有基于权限的安全系统:

┌─────────────────────────────────────────┐
│  当前安全架构 (仅权限控制)               │
│                                         │
│  Client Request                         │
│       │                                 │
│       ▼                                 │
│  ┌──────────────┐                       │
│  │ Permission   │                       │
│  │ Manager      │                       │
│  │              │                       │
│  │ • auto       │  ✅ 通过              │
│  │ • notify     │  ✅ 通过              │
│  │ • confirm    │  ⏳ 用户确认          │
│  │ • deny       │  ❌ 拒绝              │
│  └──────┬───────┘                       │
│         │                                │
│         ▼                                │
│  ┌──────────────┐                       │
│  │ Daemon       │  ⚠️ 所有代码在        │
│  │ Process      │     相同进程中执行     │
│  │              │                       │
│  │ • 读取文件    │  🔓 完整系统访问      │
│  │ • 执行命令    │  🔓 无隔离           │
│  │ • 网络访问    │  🔓 共享内存         │
│  │ • AI 调用    │  🔓 共享文件系统      │
│  └──────────────┘                       │
└─────────────────────────────────────────┘

安全风险

风险类型 描述 影响
代码注入 恶意 AI 响应可能注入危险命令 🔴 Critical
权限提升 任务在 daemon 权限下运行 🔴 Critical
文件系统访问 完整文件系统读写权限 🟠 High
网络滥用 无限制的网络访问 🟠 High
资源耗尽 无限制的 CPU/内存使用 🟡 Medium
信息泄露 可访问敏感数据 🔴 Critical

具体攻击场景

场景 1: 恶意 AI 响应

用户: "帮我清理临时文件"
AI (恶意): "执行: rm -rf ~/*"  ← 危险!
         ↓
      Daemon 直接执行 (当前架构)
         ↓
      用户数据全部删除 💥

场景 2: 第三方插件

用户安装第三方插件
    ↓
插件代码在 daemon 进程中运行
    ↓
插件可以:
  • 读取所有文件
  • 访问网络发送数据
  • 修改系统设置
  • 窃取凭据 💥

场景 3: 供应链攻击

依赖包被攻击者控制
    ↓
恶意代码注入到 daemon
    ↓
完整系统访问权限 💥

🎯 目标

安全目标

  1. 隔离执行: 危险任务在隔离环境中运行
  2. 资源限制: CPU、内存、网络带宽限制
  3. 文件系统隔离: 只读或受限的文件系统访问
  4. 网络隔离: 可控的网络访问策略
  5. 快速启动: <100ms 启动时间
  6. 低开销: <50MB 内存开销

分类任务安全等级

安全等级 执行环境 示例任务
🟢 Trusted Daemon 进程 读取配置、查询状态、AI 聊天
🟡 Safe Daemon 进程 读取文件、列出目录、搜索
🟠 Review Daemon + 用户确认 写入文件、打开应用、截图
🔴 Dangerous MicroVM 隔离 执行 shell 命令、安装软件、网络操作
⚫ Blocked 拒绝执行 系统修改、root 操作

🏗️ 提案:MicroVM 隔离架构

新架构图

┌────────────────────────────────────────────────────────────────────┐
│  OpenCLI 安全架构 (带 MicroVM 隔离)                                 │
│                                                                    │
│  Client Request                                                    │
│       │                                                            │
│       ▼                                                            │
│  ┌──────────────────────────┐                                     │
│  │  Daemon (主进程)          │                                     │
│  │                          │                                     │
│  │  ┌────────────────────┐  │                                     │
│  │  │ Permission Manager │  │                                     │
│  │  └─────────┬──────────┘  │                                     │
│  │            │              │                                     │
│  │            ▼              │                                     │
│  │  ┌────────────────────┐  │                                     │
│  │  │ Security Router    │  │                                     │
│  │  │                    │  │                                     │
│  │  │ 任务分类:          │  │                                     │
│  │  │ • Trusted  → 本地  │  │                                     │
│  │  │ • Safe     → 本地  │  │                                     │
│  │  │ • Review   → 本地  │  │                                     │
│  │  │ • Dangerous→ VM    │◀─┼─ 新增组件                           │
│  │  └─────────┬──────────┘  │                                     │
│  └────────────┼──────────────┘                                     │
│               │                                                    │
│      ┌────────┴────────┐                                          │
│      │                 │                                          │
│      ▼                 ▼                                          │
│  ┌────────┐      ┌──────────────────────────────────────┐        │
│  │ 本地执行 │      │  MicroVM Pool (新增)                 │        │
│  └────────┘      │                                      │        │
│                  │  ┌─────────────────────────────────┐ │        │
│                  │  │ VM 1: 运行中                     │ │        │
│                  │  │ • Firecracker VMM               │ │        │
│                  │  │ • Alpine Linux (精简内核)        │ │        │
│                  │  │ • 限制: 1 CPU, 256MB RAM        │ │        │
│                  │  │ • 网络: 受限白名单               │ │        │
│                  │  │ • FS: 只读 + 临时 tmpfs         │ │        │
│                  │  │ • 超时: 5 分钟                   │ │        │
│                  │  └─────────────────────────────────┘ │        │
│                  │                                      │        │
│                  │  ┌─────────────────────────────────┐ │        │
│                  │  │ VM 2: 空闲                       │ │        │
│                  │  │ (预热待命)                       │ │        │
│                  │  └─────────────────────────────────┘ │        │
│                  │                                      │        │
│                  │  ┌─────────────────────────────────┐ │        │
│                  │  │ VM 3: 空闲                       │ │        │
│                  │  └─────────────────────────────────┘ │        │
│                  └──────────────────────────────────────┘        │
└────────────────────────────────────────────────────────────────────┘

组件详解

1. Security Router (新增)

/// 安全路由器 - 决定任务执行环境
class SecurityRouter {
  final PermissionManager permissionManager;
  final MicroVMPool vmPool;

  /// 路由任务到适当的执行环境
  Future<ExecutionResult> routeTask(Task task) async {
    final securityLevel = _classifyTask(task);

    switch (securityLevel) {
      case SecurityLevel.trusted:
      case SecurityLevel.safe:
      case SecurityLevel.review:
        // 本地执行
        return await _executeLocally(task);

      case SecurityLevel.dangerous:
        // MicroVM 隔离执行
        return await _executeInVM(task);

      case SecurityLevel.blocked:
        throw SecurityException('Task blocked by security policy');
    }
  }

  /// 分类任务安全等级
  SecurityLevel _classifyTask(Task task) {
    // 检查操作类型
    if (task.operation == 'execute_shell_command') {
      return SecurityLevel.dangerous;
    }

    if (task.operation == 'install_package') {
      return SecurityLevel.dangerous;
    }

    if (task.operation.startsWith('file_write')) {
      return SecurityLevel.review;
    }

    // 默认安全
    return SecurityLevel.safe;
  }

  /// 在 MicroVM 中执行
  Future<ExecutionResult> _executeInVM(Task task) async {
    // 从池中获取 VM
    final vm = await vmPool.acquireVM();

    try {
      // 设置超时和资源限制
      final result = await vm.execute(task)
          .timeout(Duration(minutes: 5));

      return result;
    } finally {
      // 释放 VM (销毁或重置)
      await vmPool.releaseVM(vm);
    }
  }
}

2. MicroVM Pool (新增)

/// MicroVM 池管理器
class MicroVMPool {
  final int maxVMs = 5;
  final int minIdleVMs = 2;
  final List<MicroVM> _idleVMs = [];
  final List<MicroVM> _busyVMs = [];

  /// 获取可用 VM
  Future<MicroVM> acquireVM() async {
    // 有空闲 VM,直接返回
    if (_idleVMs.isNotEmpty) {
      final vm = _idleVMs.removeAt(0);
      _busyVMs.add(vm);
      return vm;
    }

    // 达到上限,等待
    if (_busyVMs.length >= maxVMs) {
      await _waitForAvailableVM();
      return acquireVM();
    }

    // 创建新 VM
    final vm = await _createVM();
    _busyVMs.add(vm);
    return vm;
  }

  /// 释放 VM
  Future<void> releaseVM(MicroVM vm) async {
    _busyVMs.remove(vm);

    // 销毁 VM (安全起见,不重用)
    await vm.destroy();

    // 维持最小空闲数
    _maintainIdleVMs();
  }

  /// 创建新 VM
  Future<MicroVM> _createVM() async {
    return await MicroVM.create(
      memory: 256 * 1024 * 1024,  // 256 MB
      cpus: 1,
      networkPolicy: NetworkPolicy.restricted,
      filesystemMode: FilesystemMode.readOnlyWithTmp,
    );
  }

  /// 预热空闲 VM
  Future<void> _maintainIdleVMs() async {
    while (_idleVMs.length < minIdleVMs) {
      final vm = await _createVM();
      _idleVMs.add(vm);
    }
  }
}

3. MicroVM 实现 (基于 Firecracker)

/// MicroVM 实例
class MicroVM {
  final String id;
  final Process firecrackerProcess;
  final String socketPath;

  /// 创建 MicroVM
  static Future<MicroVM> create({
    required int memory,
    required int cpus,
    required NetworkPolicy networkPolicy,
    required FilesystemMode filesystemMode,
  }) async {
    final id = Uuid().v4();
    final socketPath = '/tmp/firecracker-$id.sock';

    // 启动 Firecracker VMM
    final process = await Process.start('firecracker', [
      '--api-sock', socketPath,
    ]);

    // 配置 VM
    await _configureVM(socketPath, memory, cpus);

    // 配置网络
    await _configureNetwork(socketPath, networkPolicy);

    // 配置文件系统
    await _configureFilesystem(socketPath, filesystemMode);

    // 启动 VM
    await _startVM(socketPath);

    return MicroVM(
      id: id,
      firecrackerProcess: process,
      socketPath: socketPath,
    );
  }

  /// 在 VM 中执行任务
  Future<ExecutionResult> execute(Task task) async {
    // 通过 vsock 发送任务
    final result = await _sendTaskViaVsock(task);
    return result;
  }

  /// 销毁 VM
  Future<void> destroy() async {
    firecrackerProcess.kill();
    await File(socketPath).delete();
  }
}

🚀 实现方案

方案比较

方案 启动时间 内存开销 隔离程度 复杂度 推荐
Firecracker 125ms 5MB ⭐⭐⭐⭐⭐ 首选
gVisor 50ms 20MB ⭐⭐⭐⭐ 🟡 备选
Docker 500ms 100MB ⭐⭐⭐ ❌ 不推荐
Kata Containers 300ms 120MB ⭐⭐⭐⭐⭐ ❌ 过重

推荐方案: Firecracker

为什么选择 Firecracker?

  1. AWS 开源: 成熟、生产级别
  2. 极快启动: <125ms 启动时间
  3. 极低开销: 5MB 内存开销
  4. 强隔离: 硬件虚拟化 (KVM)
  5. 良好文档: 丰富的文档和示例

Firecracker 架构

┌──────────────────────────────────────────┐
│  Host Machine (OpenCLI Daemon)           │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │  Firecracker VMM Process           │  │
│  │                                    │  │
│  │  ┌──────────────────────────────┐  │  │
│  │  │  MicroVM (Guest)             │  │  │
│  │  │                              │  │  │
│  │  │  • Alpine Linux (20MB)       │  │  │
│  │  │  • OpenCLI Task Runner       │  │  │
│  │  │  • vsock 通信                │  │  │
│  │  │                              │  │  │
│  │  │  资源限制:                    │  │  │
│  │  │  • 1 vCPU                    │  │  │
│  │  │  • 256 MB RAM                │  │  │
│  │  │  • 10 MB/s 网络              │  │  │
│  │  │  • 只读 rootfs               │  │  │
│  │  │  • 临时 tmpfs (100MB)        │  │  │
│  │  └──────────────────────────────┘  │  │
│  └────────────────────────────────────┘  │
│                                          │
│  通信: vsock (虚拟socket)                 │
│  • CID: 3 (guest)                        │
│  • Port: 8000                            │
└──────────────────────────────────────────┘

📝 实施计划

Phase 1: 基础设施 (2-3 周)

1.1 Firecracker 集成

  • 安装 Firecracker 依赖 (KVM, Linux 4.14+)
  • 创建 Alpine Linux rootfs 镜像
  • 实现 Firecracker API 客户端
  • 创建基本的 VM 启动/停止脚本

1.2 MicroVM Pool

  • 实现 MicroVMPool
  • 实现 VM 生命周期管理
  • 实现预热和重用策略
  • 添加监控和日志

1.3 通信协议

  • 实现 vsock 通信层
  • 定义任务序列化格式
  • 实现结果回传机制
  • 添加超时和错误处理

Phase 2: Security Router (1-2 周)

2.1 任务分类

  • 实现 SecurityRouter
  • 定义任务分类规则
  • 实现安全等级评估
  • 添加配置和策略管理

2.2 路由逻辑

  • 实现本地执行路径
  • 实现 VM 执行路径
  • 添加执行环境选择逻辑
  • 实现降级和回退机制

Phase 3: Guest Agent (1 周)

3.1 任务执行器

  • 创建 Guest Agent (Dart/Go)
  • 实现任务接收和解析
  • 实现命令执行
  • 实现结果收集

3.2 安全约束

  • 实现文件系统访问限制
  • 实现网络访问白名单
  • 实现资源使用监控
  • 实现超时强制终止

Phase 4: 集成测试 (1 周)

4.1 功能测试

  • VM 创建和销毁测试
  • 任务执行测试
  • 错误处理测试
  • 性能基准测试

4.2 安全测试

  • 隔离验证测试
  • 逃逸攻击测试
  • 资源限制测试
  • 恶意输入测试

Phase 5: 生产部署 (1 周)

5.1 优化

  • 启动时间优化
  • 内存使用优化
  • 并发性能优化
  • 监控和告警

5.2 文档

  • 架构文档
  • 部署指南
  • 安全策略文档
  • 故障排查指南

🎛️ 配置示例

daemon_config.yaml

security:
  # 启用 MicroVM 隔离
  microvm_enabled: true

  # MicroVM 配置
  microvm:
    # Firecracker 路径
    firecracker_path: /usr/local/bin/firecracker

    # 内核镜像
    kernel_image: /opt/opencli/firecracker/vmlinux

    # rootfs 镜像
    rootfs_image: /opt/opencli/firecracker/rootfs.ext4

    # VM 池配置
    pool:
      min_idle: 2
      max_total: 10
      idle_timeout: 300  # 5 分钟

    # 资源限制
    resources:
      memory_mb: 256
      vcpu_count: 1
      network_bandwidth_mbps: 10
      disk_quota_mb: 100

    # 超时
    timeouts:
      boot_timeout: 5
      task_timeout: 300  # 5 分钟
      shutdown_timeout: 10

  # 任务分类规则
  task_classification:
    dangerous_operations:
      - execute_shell_command
      - install_package
      - system_modify
      - network_request
      - file_delete

    review_operations:
      - file_write
      - file_create
      - open_application
      - take_screenshot

    safe_operations:
      - file_read
      - file_list
      - system_info
      - search

📊 性能预期

MicroVM 启动性能

阶段 时间 说明
Firecracker 启动 ~20ms VMM 进程启动
VM 配置 ~30ms API 调用配置
内核启动 ~50ms Linux 内核启动
Guest Agent ~25ms Agent 初始化
总计 ~125ms 用户可接受

资源使用

资源 每个 VM 5 个 VM 说明
内存 256 MB 1.28 GB Guest + 开销
VMM 内存 5 MB 25 MB Firecracker 进程
CPU 1 vCPU 5 vCPU 限制使用
磁盘 50 MB 250 MB rootfs + tmp

执行性能

操作类型 本地执行 VM 执行 开销
简单命令 10ms 150ms +1400%
文件操作 5ms 130ms +2500%
网络请求 200ms 350ms +75%
AI 调用 1000ms 1150ms +15%

结论: 对于危险操作,150ms 开销是可接受的安全代价。


🔒 安全保证

MicroVM 隔离特性

进程隔离: 完全独立的内核和用户空间 ✅ 内存隔离: 硬件级别的内存保护 ✅ 文件系统隔离: 只读 rootfs + 临时 tmpfs ✅ 网络隔离: 白名单防火墙规则 ✅ 资源限制: CPU/内存/磁盘/网络配额 ✅ 时间限制: 强制超时和终止

安全边界

┌──────────────────────────────────────────┐
│  Host System (Trusted)                   │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │  OpenCLI Daemon                    │  │
│  │  • 完整文件系统访问                 │  │
│  │  • 网络访问                        │  │
│  │  • 系统调用                        │  │
│  └────────────────────────────────────┘  │
│                                          │
│        │ KVM 硬件虚拟化边界               │
│        ▼                                 │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │  MicroVM (Untrusted)               │  │
│  │                                    │  │
│  │  ❌ 无法访问 host 文件系统          │  │
│  │  ❌ 无法访问 host 进程              │  │
│  │  ❌ 无法访问 host 网络              │  │
│  │  ✅ 只能通过 vsock 通信             │  │
│  │  ✅ 受限的 CPU/内存                │  │
│  │  ✅ 临时文件系统 (销毁后清除)       │  │
│  └────────────────────────────────────┘  │
└──────────────────────────────────────────┘

🎯 使用示例

用户视角

场景 1: 安全查询 (本地执行)

用户: "显示当前目录的文件"

OpenCLI:
  1. 分类: Safe → 本地执行
  2. 执行: ls -la
  3. 返回结果

执行时间: ~10ms

场景 2: 危险命令 (MicroVM 执行)

用户: "安装 npm 包 lodash"

OpenCLI:
  1. 分类: Dangerous → MicroVM 隔离
  2. 请求用户确认
  3. 获取 VM (125ms 启动)
  4. 执行: npm install lodash
  5. 返回结果
  6. 销毁 VM

执行时间: ~3s (安全优先)

开发者视角

// 自动路由任务
final result = await securityRouter.routeTask(Task(
  operation: 'execute_shell_command',
  params: {
    'command': 'curl https://api.example.com',
  },
));

// MicroVM 会自动处理:
// 1. 检测到 dangerous 操作
// 2. 获取或创建 VM
// 3. 隔离执行
// 4. 收集结果
// 5. 清理资源

🚧 技术挑战

挑战 1: 平台兼容性

问题: Firecracker 只支持 Linux + KVM

解决方案:

┌─────────────────────────────────────────┐
│  平台适配策略                            │
│                                         │
│  • Linux (x86_64)    → Firecracker ✅   │
│  • macOS (Intel/M1)  → gVisor      🟡   │
│  • Windows           → WSL2 + KVM  🟡   │
│  • 不支持的平台       → 降级到本地   ⚠️   │
└─────────────────────────────────────────┘

挑战 2: 启动延迟

问题: 125ms 启动时间影响用户体验

解决方案:

  • 预热 VM 池 (维持 2-3 个空闲 VM)
  • 异步执行 + 进度通知
  • 批量任务共享 VM

挑战 3: 文件访问

问题: VM 需要访问用户文件

解决方案:

1. 只读挂载特定目录
   /workspace → /mnt/workspace (ro)

2. 通过 vsock 传输小文件
   <1MB: 直接传输
   >1MB: 挂载只读

3. 结果通过 vsock 返回

📈 迁移策略

阶段性部署

Stage 1: Beta 测试 (1 个月)

  • ✅ 默认禁用 MicroVM
  • ✅ 通过配置启用
  • ✅ 仅 shell 命令使用 MicroVM
  • ✅ 收集性能数据

Stage 2: 渐进部署 (2 个月)

  • ✅ 默认启用 (可降级)
  • ✅ 扩展到更多危险操作
  • ✅ 优化启动时间
  • ✅ 生产监控

Stage 3: 完全部署 (3 个月)

  • ✅ 强制启用 (安全要求)
  • ✅ 所有危险操作隔离
  • ✅ 性能优化完成
  • ✅ 安全审计通过

💰 成本分析

开发成本

阶段 工作量 说明
基础设施 2-3 周 Firecracker 集成
Security Router 1-2 周 路由和分类
Guest Agent 1 周 VM 内任务执行
测试 1 周 功能和安全测试
部署 1 周 优化和文档
总计 6-8 周 1-2 名工程师

运行成本

资源 成本 说明
CPU VM 空闲时几乎无开销
内存 ~1-2 GB 5 个 VM 池
磁盘 ~500 MB rootfs + 日志
总计 可接受 现代机器完全支持

🎉 预期收益

安全提升

指标 改进
代码注入风险 🔴 High → 🟢 Low
权限提升风险 🔴 Critical → 🟢 Low
数据泄露风险 🟠 High → 🟡 Medium
系统破坏风险 🔴 Critical → 🟢 Low

用户信心

  • ✅ 安心运行第三方插件
  • ✅ 信任 AI 生成的命令
  • ✅ 企业级安全合规
  • ✅ 透明的安全策略

📚 参考资料

Firecracker

安全模型

类似实现


✅ 决策建议

推荐: 实施 MicroVM 隔离

理由:

  1. 🔴 当前风险高: 所有代码在 daemon 进程中运行
  2. 技术成熟: Firecracker 生产级别,AWS 验证
  3. 性能可接受: 125ms 启动,对用户影响小
  4. 成本合理: 6-8 周开发,1-2 GB 内存
  5. 安全提升明显: 多个关键风险降低到 Low

实施路径

现在 ──────────────────────────────▶ 3个月后
  │                                    │
  │  Phase 1: 基础设施 (3周)            │
  │      ↓                             │
  │  Phase 2: 路由器 (2周)              │
  │      ↓                             │
  │  Phase 3: Guest Agent (1周)        │
  │      ↓                             │
  │  Phase 4: 测试 (1周)                │
  │      ↓                             │
  │  Phase 5: 部署 (1周)                │
  │                                    │
  └────────────────────────────────────┘
       6-8周开发周期

文档版本: 1.0 下次审查: 2026-03-04 负责人: 安全团队