我们对 Docker Sandbox 未记录的 MicroVM API 进行了逆向工程

2026-05-21 1 阅读 yakkomajuri
Docker 附带了一个未记录的 API,用于生成 microVM。我们对其进行逆向工程并构建了开源沙盒代理 SDK,以允许在其中编排编码代理。 Docker 和容器是我们运行后端的标准。最近,越来越多的工作负载转移到沙箱中执行不受信任的代码,而 Docker 并不适合这种情况。随着 Docker Sandboxes 的推出,Docker 悄悄地为 microVM 提供了一个未记录的 API,可以为沙箱提供支持。这看起来有望成为使用 microVM 管理您自己的基础设施上的沙箱的统一方式,就像 10 年前 Docker 为容器所做的那样。 (目前它仅支持 macOS/Windows。需要嵌套虚拟化。) 什么是 Docker 沙箱? Docker Sandboxes(发布帖子)是 Docker 用于安全运行 AI 编码代理的解决方案。 Claude Code、Codex 和 Gemini 需要运行任意代码、安装包和修改文件。 MicroVM 让它们运行 --dangerously-skip-permissions 而不会造成危险。 Docker 提供了一个简单的 CLI: docker sandbox run claude ~/project 乍一看,这看起来像是一个美化的 docker run 命令,但实际上 Docker 使用的是完全不同的技术:microVM。 MicroVM 与容器:深入了解容器是大多数开发人员在运行 docker run 时所了解和喜爱的。它们在主机之间提供基本的文件系统、网络和进程隔离。然而,一个常见的误解是,容器足以运行不受信任的代码(AI 代理、用户提交的脚本、多租户插件)。按照设计,容器共享主机的内核,以便快速且轻量级。然而,这意味着受损的容器可能会使主机面临风险。使用容器的安全影响是一个较长的话题,但大多数业界都认为容器对于不可信代码执行来说是一种不好的做法。为了实现更好的安全性,AWS Lambda、Fly.io 等产品和大多数沙箱提供商都使用 microVM 来构建具有独立内核的轻量级虚拟机,以实现更好的安全性。它比完整的虚拟机更轻,但不会带来太多的开销。这被认为是隔离用户代码的黄金标准。如果您想了解更多信息,还有许多其他文档可以更好地描述 microVM 和 Firecracker。这就是为什么 Docker 在 microVM 而不是容器上构建沙箱,同时保持与 Docker 容器的兼容性。以下是两者的比较: Docker 容器 Docker 沙箱安全 共享内核(命名空间) 独立内核(microVM) 不可信代码 不安全 安全网络访问 直接 HTTP 通过过滤代理 卷 直接挂载 双向文件同步 平台 仅 Linux、macOS、Windows macOS、Windows 用例 这会打开容器无法安全处理的用例: 不受信任的代码执行:运行用户提交的脚本,而不会给主机带来风险 AI 编码代理:让 Claude/Codex 以完全权限安全运行多租户插件:隔离 SaaS 应用程序中的客户代码 安全 CI/CD:使用 VM 级隔离而不是容器运行构建 MicroVMs API docker 沙箱运行严格限于 Docker 的白名单代理:Claude、Codex、Gemini、Copilot、Kiro 和 Cagent。目前它不允许您运行自己的 Docker 容器。因此,很自然地,我深入研究了是否可以对底层 microVM API 进行逆向工程,以便在沙箱内运行我想要的任何代码。 /vm HTTP API:创建虚拟机 Docker 的 sandboxd 守护进程管理所有虚拟机并监听 ~/.docker/sandboxes/sandboxd.sock 。它提供了三个端点: GET /vm :列出所有虚拟机 POST /vm :创建虚拟机 DELETE /vm/{vm_name} :销毁虚拟机 我们将使用以下命令创建虚拟机:curl -X POST --unix-socket ~/.docker/sandboxes/sandboxd.sock \ http://localhost/vm \ -H "Content-Type: application/json" \ -d '{"agent_name": "my-sandbox", "workspace_dir": "/path/to/project"}' 我们得到响应: { "vm_id" : "abc123" , "vm_config" : { "socketPath" : "/Users/you/.docker/sandboxes/vm/my-sandbox-vm/docker.sock" , "fileSharingDirectories" : [ "/path/to/project" ] , "stateDir" : "/Users/you/.docker/sandboxes/vm/my-sandbox-vm" } , "ca_cert_path" : "/Users/you/.docker/sandboxes/vm/my-sandbox-vm/proxy_cacerts/proxy-ca.crt" } VM 名称遵循模式 {agent_name}-vm 。 socketPath 是每个虚拟机的 Docker 守护进程,我们将在下一步中使用它。与 microVM 的 Docker 守护进程对话 通常所有容器共享 /var/run/docker.sock 。具有套接字访问权限的任何人都可以查看和控制所有其他容器。沙箱翻转了这一点。每个 microVM 在 ~/.docker/sandboxes/vm//docker.sock 都有自己的 Docker 守护进程,以实现最大程度的隔离。容器在 microVM 内像平常一样运行,但与主机和其他 VM 完全隔离。为了针对不同的守护进程,我们需要使用 curl --unix-socket ... 或 docker --host unix://... 覆盖 Unix 套接字路径。将镜像加载到虚拟机中 新虚拟机已完成