news 2026/10/23 3:33:16

Sandbox 隔离哪些资源?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Sandbox 隔离哪些资源?

第203题:Sandbox 隔离哪些资源?

1. 核心回答

对于执行不可信代码的 Sandbox,我会至少隔离六类资源:

  1. 文件系统
  2. 进程
  3. 网络
  4. 身份与凭据
  5. CPU、内存、进程数和执行时间
  6. 系统调用与内核攻击面

实际工程中还会进一步限制设备、IPC、磁盘写入和输出大小。

整体原则可以概括为:

默认拒绝 → 最小暴露 → 有限资源 → 有限生命周期 → 可审计销毁

例如一个用于 Agent 执行 Python 代码的沙箱,理想状态应该是:

只看到当前任务文件

不能访问宿主文件

默认不能访问公网

没有生产凭据

不能观察其他任务进程

只能调用必要系统调用

CPU / 内存 / 时间都有上限

任务结束后实例销毁


2. 文件系统隔离

文件系统隔离解决的问题是:

沙箱中的代码能够读写哪些文件。

Linux 可以通过 Mount Namespace 为不同执行环境提供不同的挂载视图。

一个不可信代码沙箱通常不会直接暴露:

  • /etc
  • /home
  • /root
  • SSH Key
  • 云服务配置文件
  • Docker Socket
  • 其他用户数据
  • 其他任务 Workspace

更合理的设计是:

只读基础镜像

    当前任务需要的只读输入

      独立临时可写目录

      例如:

      /app -> read-only /input -> read-only /work -> writable tmpfs /output -> controlled writable directory

      任务结束后删除/work。

      真正需要返回给用户的文件,通过受控的/output导出。

      这样可以避免程序:

      • 修改宿主文件;
      • 读取其他用户数据;
      • 在系统目录中持久化;
      • 污染后续任务。

      2.1 Host Bind Mount 要特别谨慎

      如果直接:

      -v /:/host

      或者把敏感宿主目录以可写形式挂载进去,那么文件系统隔离基本失效。

      因此需要遵循:

      No Host Mount by Default

      确有需要时:

      最小目录 + read-only


      3. 进程隔离

      第二类是 Process Isolation。

      Linux 的 PID Namespace 可以让沙箱拥有独立的 PID 空间。

      沙箱内部可能看到:

      PID 1 PID 2 PID 3

      但无法正常观察宿主上的:

      database ssh other-agent other-user-job

      这样可以防止程序直接:

      • 枚举宿主进程;
      • 给宿主进程发送 Signal;
      • 干扰其他任务;
      • 读取其他进程状态。

      同时还应该限制能够创建多少进程。

      例如:

      pids.max = 128

      否则攻击者可以执行 Fork Bomb:

      process ├── process │ ├── process │ └── process └── process ├── process └── process

      持续创建进程直至宿主资源耗尽。

      因此:

      PID Namespace 负责可见性隔离,PIDs Limit 负责资源耗尽控制。


      4. 网络隔离

      第三类是 Network Isolation。

      Network Namespace 可以为 Sandbox 创建独立:

      • 网络设备;
      • IP Stack;
      • Routing Table;
      • Port;
      • Socket Namespace。

      对于执行用户提交代码的环境,我通常采用:

      Default Deny Network

      也就是默认无公网访问。

      原因包括:

      • 防止下载恶意 Payload;
      • 防止建立反向 Shell;
      • 防止扫描内网;
      • 防止访问 Metadata Service;
      • 防止数据外泄;
      • 防止攻击内部服务。

      如果任务必须联网,例如:

      pip install

      可以改成受控访问:

      Sandbox ↓ Egress Proxy ↓ Domain Allowlist ↓ Approved Repository

      例如只允许:

      pypi.org files.pythonhosted.org

      而不能访问:

      任意公网地址 内网数据库 169.254.169.254 其他租户服务

      因此网络策略可以按照:

      无网络

      ↓

      域名 Allowlist

      ↓

      受控 Egress Proxy

      逐级开放。


      5. 身份和凭据隔离

      这一层经常被遗漏。

      即使文件、网络和进程都做了隔离,如果 Sandbox 获得了高权限 Credential,风险仍然很高。

      需要隔离:

      • API Key;
      • Database Password;
      • Cloud Credential;
      • SSH Key;
      • OAuth Token;
      • Kubernetes ServiceAccount;
      • Docker Socket;
      • Internal Service Token。

      对于普通代码执行任务:

      Production Credential = 0

      是最安全的默认值。

      如果确实需要调用外部服务,应提供:

      Short-lived + Scoped + Task-specific

      的临时凭据。

      例如任务只需要:

      object_storage.read

      就不要授予:

      object_storage.admin

      6. 用户身份和 Linux Capability

      Linux User Namespace 可以把沙箱内部的 UID/GID 映射到宿主上的低权限用户。

      例如沙箱中:

      uid = 0

      在宿主机上可以映射为:

      uid = 100000+

      这样即使程序在 Sandbox 内表现为 root,它在宿主上仍然缺少真正的 root 权限。

      同时需要删除不必要的 Linux Capabilities。

      例如通常不应该授予:

      CAP_SYS_ADMIN CAP_SYS_MODULE CAP_SYS_PTRACE CAP_NET_ADMIN CAP_SYS_BOOT

      安全设计通常遵循:

      Drop All Capabilities ↓ Add Only Required Capabilities

      对于普通 Python、JavaScript 或代码编译任务,往往根本不需要额外 Capability。


      7. CPU、内存和进程资源隔离

      Sandbox 还要防止 Denial of Service。

      例如用户提交:

      whileTrue:pass

      会持续消耗 CPU。

      或者:

      x=[]whileTrue:x.append("A"*100000000)

      会持续占用内存。

      因此应该通过 cgroups 等资源控制机制限制:

      CPU Memory PIDs I/O

      例如:

      CPU = 1 Core Memory = 512 MB PIDs = 128

      Docker 官方文档明确指出,容器在没有配置资源限制时,默认可以使用宿主调度器允许的大量 CPU 和内存。

      因此“运行在容器里”本身不能解决资源耗尽问题。


      8. 执行时间也必须限制

      除了 CPU 和内存,还应该有 Wall-clock Timeout。

      例如:

      timeout = 30s

      如果任务超过:

      30 秒

      执行器直接:

      SIGTERM ↓ grace period ↓ SIGKILL

      这样能够处理:

      • 死循环;
      • 无限等待;
      • 网络阻塞;
      • Deadlock;
      • 恶意 Sleep;
      • 算法复杂度异常。

      所以资源预算可以理解为:

      Compute Budget = CPU + Memory + PIDs + Disk + Execution Time + Output Size

      每一项都应该存在明确上限。


      9. 系统调用隔离

      即使文件、网络等已经隔离,进程仍然通过 System Call 与 Linux Kernel 交互。

      因此还需要限制:

      syscall surface

      Linux seccomp 可以通过过滤规则限制允许执行的系统调用。

      例如可以禁止或限制高风险操作:

      mount reboot setns unshare ptrace swapon

      Docker 默认也使用 seccomp profile,限制一部分系统调用。

      需要注意:

      seccomp 提供系统调用过滤能力,它只是完整 Sandbox 的一个组件。

      Linux Kernel 官方文档也明确指出,seccomp filtering 用于减少暴露给应用程序的 Kernel Surface,完整的安全边界还需要其他硬化机制配合。


      10. AppArmor / SELinux 进一步限制行为

      System Call 本身粒度仍然有限。

      例如应用可能合法调用:

      open()

      但我们希望:

      允许 open("/work/a.txt") 禁止 open("/etc/shadow")

      此时可以使用:

      • AppArmor;
      • SELinux;

      等 Mandatory Access Control 机制。

      Docker 默认环境可以使用docker-defaultAppArmor Profile。

      AppArmor 可以进一步限制:

      • 文件访问;
      • 网络行为;
      • ptrace;
      • 可执行程序;
      • Capability。

      形成:

      Namespaces + cgroups + Capabilities + seccomp + AppArmor / SELinux

      多层隔离。


      11. 设备也应该控制

      Sandbox 一般不应该直接获得宿主设备访问权限。

      例如:

      /dev GPU USB Block Device KVM

      需要按照任务最小化暴露。

      尤其应该避免随意授予:

      --privileged

      因为 Privileged Container 会显著扩大 Capability 和设备访问范围。

      普通代码执行任务通常只需要极少数基础设备,例如:

      /dev/null /dev/zero /dev/random

      GPU 也应作为单独授权资源管理。


      12. 为什么单独使用容器还需要继续加固

      Container 提供非常有价值的基础隔离,包括:

      • Namespace;
      • cgroup;
      • Capability;
      • seccomp;
      • LSM。

      安全强度仍然取决于配置和宿主 Kernel。

      如果出现:

      • Kernel Vulnerability;
      • Container Runtime Vulnerability;
      • Dangerous Capability;
      • Host Mount;
      • Docker Socket Exposure;
      • Privileged Container;

      隔离边界可能被突破。

      因此对于:

      可信内部服务

      普通容器加固可能已经满足需求。

      对于:

      用户任意代码 恶意样本 不可信 Agent 工具调用 CTF / Malware 多租户 Code Execution

      我会进一步考虑更强的隔离层,例如:

      • gVisor;
      • Firecracker microVM;
      • 独立虚拟机;
      • 专用执行节点。

      gVisor 会在应用和宿主 Kernel 之间增加独立 Application Kernel。

      Firecracker 则基于 KVM 创建 microVM,为每个工作负载提供独立 Guest Kernel 边界。


      13. Sandbox 的生命周期也要隔离

      安全沙箱最好采用:

      One Task → One Fresh Sandbox → Execute → Collect Artifact → Destroy

      不要让多个不可信任务长期共享同一个可写环境。

      否则前一个任务可能留下:

      • 恶意文件;
      • 后门;
      • 环境变量;
      • 修改后的依赖;
      • Cache Poisoning;
      • 持久进程。

      任务结束后应销毁:

      Filesystem Process Network Namespace Temporary Credential Memory State

      下一任务重新创建干净环境。


      14. 怎么验证 Sandbox 真的隔离成功

      不能只执行:

      print("hello world")

      然后认为沙箱安全。

      我会主动测试逃逸路径。

      14.1 文件测试

      尝试:

      读取 /etc/shadow 读取宿主 home 修改宿主文件 访问其他任务目录

      预期:

      Denied

      14.2 网络测试

      尝试:

      访问公网 扫描内网 访问 Metadata Service 建立 Reverse Shell

      预期:

      Denied

      14.3 进程测试

      尝试:

      查看 Host PID ptrace 其他进程 Fork Bomb

      预期:

      不可见 / 被拒绝 / 被 PIDs Limit 终止

      14.4 资源测试

      测试:

      无限 CPU 无限内存 无限进程 无限输出 无限执行时间

      验证:

      CPU throttle OOM termination PIDs limit Output limit Timeout

      均能正确触发。

      14.5 权限测试

      尝试:

      获得 root 加载 Kernel Module mount Host Filesystem 访问 Docker Socket 使用 Host Network

      全部应该受到策略限制。


      15. 一个比较完整的安全架构

      对于 Agent Code Execution,我会设计成:

      Agent ↓ Sandbox Controller ↓ Policy Check ↓ Fresh Isolated Runtime ├── Read-only RootFS ├── Task-only Workspace ├── PID Namespace ├── Network Namespace ├── User Namespace ├── Dropped Capabilities ├── seccomp ├── AppArmor / SELinux ├── CPU / Memory / PIDs Limit ├── Timeout └── No Production Credentials ↓ Execute ↓ Collect Approved Artifacts ↓ Destroy Sandbox

      如果代码风险等级较高:

      Native Container ↓ gVisor / microVM ↓ Dedicated Worker

      逐步提高隔离强度。


      16. 面试时可以压缩成下面这段

      Sandbox 至少要隔离六类资源:文件、进程、网络、凭据、计算资源和系统调用。

      文件侧通过独立 Mount Namespace、只读 RootFS 和任务级临时目录,避免看到宿主和其他任务的数据;进程侧用 PID Namespace 和 PIDs Limit;网络默认关闭,需要联网时通过 Allowlist 或 Egress Proxy;身份侧使用非特权用户、User Namespace、最小 Capability,并且不向任务暴露生产 Credential。

      资源侧通过 cgroups 限制 CPU、内存、进程数和 I/O,同时设置执行 Timeout,防止死循环、Fork Bomb 和资源耗尽。内核交互侧使用 seccomp 限制 System Call,再配合 AppArmor 或 SELinux 缩小文件、网络和 Capability 权限。

      容器可以提供这些机制的基础实现。对于任意用户代码、恶意样本或多租户 Agent 执行环境,我还会考虑 gVisor、Firecracker microVM 或独立执行节点增加隔离强度。最后通过文件越权、网络外连、Fork Bomb、资源耗尽、权限提升和 Sandbox Escape 等攻击测试验证边界是否真正生效。

      核心原则是:

      只给任务完成所必需的文件、网络、权限、资源和生命周期。


      17. 来源

      1. Linux man-pages,namespaces(7):说明 Linux Namespace 用于隔离全局系统资源,包括 Mount、PID、Network、User 等 Namespace。
      2. Linux man-pages,mount_namespaces(7)、pid_namespaces(7)、network_namespaces(7)、user_namespaces(7):分别说明文件挂载视图、进程 ID、网络栈以及 UID/GID 和 Capability 的隔离机制。
      3. Linux Kernel Documentation,Control Group v2:说明 cgroup 的资源分配和限制机制。
      4. Linux Kernel Documentation,Seccomp BPF:说明 seccomp 用于过滤 System Call、缩小暴露给应用程序的 Kernel Surface,并明确其属于构建 Sandbox 的组件。
      5. Docker Documentation,Docker Engine Security:说明 Docker 使用 Namespace、cgroup、Linux Capabilities 和其他 Kernel Security Features 建立容器隔离。
      6. Docker Documentation,Resource Constraints:说明容器默认没有 CPU/Memory 资源上限,需要显式配置资源限制。
      7. Docker Documentation,Seccomp Security Profiles:说明 Docker 默认 seccomp profile 会限制部分系统调用。
      8. Docker Documentation,AppArmor Security Profiles:说明docker-defaultAppArmor Profile 及其访问控制作用。
      9. gVisor Documentation,What is gVisor?:说明 gVisor 通过独立 Application Kernel 减少应用直接接触 Host Kernel 的攻击面。
      10. AWS / Firecracker Documentation:说明 Firecracker 使用 KVM microVM 为多租户工作负载提供硬件虚拟化边界。
      版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
      网站建设 2026/10/20 14:41:01

      UCOS-II多任务系统时钟配置与任务调度实战指南

      简介:这份资源是面向嵌入式专业学生与初学者的UCOS-II课程设计资料,围绕多任务调度与系统时钟两大核心展开,帮助读者在真实工程中理解实时操作系统(RTOS)的任务管理机制。内容涵盖UCOS-II的移植与配置、任务创建与优先…

      作者头像 李华
      网站建设 2026/10/23 3:32:45

      Verilog加法器设计全攻略:从RTL代码到FPGA综合优化

      最近在做数字逻辑课程的实验,有个学弟问我加法器到底怎么用 Verilog 写才规范,是不是直接写assign sum a b;就够了。这问题其实很有意思。加法器是数字电路的基石,从最简单的半加器到 ALU 里的关键路径,几乎每个数字系统都离不开…

      作者头像 李华
      网站建设 2026/10/21 18:35:00

      BlendMask实例分割:融合Top-Down与Bottom-Up的轻量高效方案

      做实例分割调研的那段时间,我一直在 top-down 和 bottom-up 两条路线之间反复比较。Mask R-CNN 这类方法精度确实稳,但 RoI 相关的计算量摆在那里,训练和推理都不便宜;YOLACT 那种纯 bottom-up 的玩法速度是快,可一旦画…

      作者头像 李华