一句话版本
隔离强度大致分四个档次:进程级限制(seccomp、Seatbelt、Landlock 等,限制一个进程能做的系统调用和能访问的文件)、容器(命名空间 + cgroups,看起来像独立系统,但和宿主机共用同一个内核)、用户态内核(gVisor,在容器和真实内核之间再加一层)、虚拟机 / 微型虚拟机(Firecracker 等,有自己独立的内核,靠硬件虚拟化隔离)。 越往后越安全,也越重、越慢。选哪一层,取决于你要运行的代码有多不可信。
全文分三层:
- 通俗理解:同一栋楼里的隔断、独立的房间、独立的房子
- 实际用处:浏览器、Docker、Google 的 gVisor、AWS Lambda 的 Firecracker
- 原理与工程要点:每一层的机制、攻击面和开销对比
第一层:通俗理解
1.1 隔断、房间和房子
| 层级 | 比喻 | 被突破后 |
|---|---|---|
| 进程级限制 | 在开放式办公室里给你划一块区域,规定你不能碰哪些柜子 | 规定写漏了,你就能碰到 |
| 容器 | 同一栋楼里的独立房间,但共用水电管道(内核) | 管道出问题,可能进入别的房间 |
| gVisor | 房间里再装一套自己的水电系统,只通过少数几个阀门连到大楼 | 要先突破自己那套系统,再突破少数阀门 |
| 虚拟机 | 独立的房子,有自己的水电(独立内核),只和外界共用一条马路(虚拟化层) | 要突破虚拟化层,难度高得多 |
1.2 关键概念:内核是共享的吗
内核是操作系统的核心,管理所有硬件和权限。普通程序要做任何"真事"(读文件、联网、创建进程),都要通过系统调用请求内核。
- 容器里的程序直接向宿主机的内核发系统调用。内核有几百个系统调用、几千万行代码,只要其中一处有漏洞,就可能被用来逃出容器;
- 虚拟机里的程序向自己的内核发系统调用,要影响宿主机,还得再突破虚拟化层,那里的攻击面小得多。
第二层:实际用处
| 技术 | 谁在用 | 用途 |
|---|---|---|
| 浏览器渲染进程沙箱 | Chrome、Firefox、Safari | 每个网页的渲染进程被严格限制,网页里的漏洞很难直接控制整台电脑 |
| seccomp-bpf | Docker 默认配置、Chrome、Android | 用过滤规则禁用危险的系统调用 |
| macOS Seatbelt、Linux Landlock / bubblewrap | 应用沙箱、部分 AI 编程工具 | 限制进程可访问的文件路径和网络 |
| Docker / 容器 | 几乎所有云服务 | 打包和隔离应用;默认配置不适合运行完全不可信的代码 |
| gVisor(Google,2018 年开源) | Google Cloud 的部分无服务器产品 | 在用户态重新实现大部分 Linux 系统调用,减少对宿主内核的直接暴露 |
| Firecracker(AWS,2018 年开源) | AWS Lambda、Fargate | 极简的微型虚拟机,启动只要约百毫秒,兼顾虚拟机的隔离和容器的速度 |
| Kata Containers | 多家云厂商 | 让每个容器运行在一个轻量虚拟机里 |
| WebAssembly 运行时 | 边缘计算、插件系统 | 语言级沙箱,只能访问显式授予的能力 |
运行 AI 生成代码的云端执行环境,普遍选择 gVisor、Firecracker 这类比普通容器更强的隔离。
第三层:原理与工程要点
3.1 进程级限制
| 机制 | 平台 | 做什么 |
|---|---|---|
| seccomp-bpf | Linux | 系统调用白名单 / 黑名单 |
| Landlock | Linux(5.13+) | 非特权进程也能限制自己能访问的文件路径和网络端口 |
| Seatbelt(sandbox-exec) | macOS | 用规则描述允许访问的文件、网络、进程操作 |
| AppContainer | Windows | 应用级隔离 |
| 降权运行 | 通用 | 用专门的低权限用户运行,不用 root(见《最小权限与密钥管理》) |
优点是轻量、几乎没有开销;缺点是规则写起来复杂,容易遗漏。
3.2 容器
容器 = 命名空间(让进程看到一个独立的文件系统、进程列表、网络、主机名、用户)+ cgroups(限制 CPU、内存、进程数)+ 通常再加 seccomp 和能力(capabilities)限制。
它是隔离,但不是安全边界的终点:所有容器共享宿主内核。常见的削弱配置(特权模式、挂载 Docker socket、给太多能力)会让隔离形同虚设(见《容器逃逸》)。
3.3 gVisor
gVisor 的核心组件 Sentry 在用户态实现了 Linux 系统调用接口。容器里的程序以为在和 Linux 内核对话,实际上是在和 Sentry 对话;Sentry 自己只用很少的一部分宿主系统调用,并且受严格的 seccomp 限制。
代价:系统调用密集的程序(大量文件 I/O、网络 I/O)会明显变慢;部分系统调用不支持。
3.4 虚拟机与微型虚拟机
传统虚拟机模拟一整台电脑(BIOS、各种设备),启动慢、占内存多。Firecracker 这类微型虚拟机只保留最少的虚拟设备(网卡、磁盘、串口),用 Rust 编写,启动约百毫秒、内存开销几 MB。隔离依靠 CPU 的硬件虚拟化(Intel VT-x、AMD-V),攻击者需要突破虚拟机监控器(KVM + Firecracker 进程,而后者本身也被 seccomp 和 jail 进一步限制)。
3.5 对比
| 进程级 | 容器 | gVisor | 微型虚拟机 | |
|---|---|---|---|---|
| 隔离强度 | 低到中 | 中 | 中高 | 高 |
| 共享宿主内核 | 是 | 是 | 部分(极少数系统调用) | 否 |
| 启动时间 | 即时 | 毫秒级 | 毫秒级 | 约百毫秒 |
| 性能开销 | 极小 | 小 | I/O 密集时明显 | 小到中 |
| 适合 | 自己的代码、本地 Agent | 自己的服务 | 半可信 / 不可信代码 | 完全不可信的代码 |
3.6 叠加使用
最佳实践是多层叠加:微型虚拟机里运行容器,容器内用非 root 用户,加 seccomp 规则,再加网络出口白名单(见《网络出口控制》)。攻击者必须连续突破每一层。
总结
| 层次 | 要点 |
|---|---|
| 关键问题 | 内核是否共享 |
| 四档 | 进程限制 → 容器 → gVisor → 微型虚拟机 |
| 选择 | 越不可信的代码,用越强的隔离 |
| 实践 | 多层叠加;容器不是安全边界的终点 |