syedtasavour/Airlock

GitHub: syedtasavour/Airlock

Airlock 是一个基于 Docker 的一次性安全沙箱,通过文件系统隔离、能力裁剪和出站白名单代理,在 macOS 上安全地运行不受信任的代码。

Stars: 1 | Forks: 0

# 🛡️ airlock **一个一次性、经过安全强化的 Linux 沙箱,用于运行不受信任的代码并进行部署, 提供一次性的 CLI 登录方式 —— 无需暴露你的 Mac 密钥、文件或 机密信息。**
把它看作是可疑代码与你真实机器之间的气闸:代码进入, 执行其工作,容器在退出时销毁。没有任何东西会泄露出去。 ``` cd ~/some/cloned/oss-project airlock run # locked-down, throwaway shell — safe to run anything ``` ## 目录 - [这为什么重要](#why-this-matters) - [何时使用(场景)](#when-to-use-it-scenarios) - [为什么即使是你*自己的*代码也要使用它](#why-use-it-even-for-your-own-code) - [三种模式](#three-modes) - [选哪种模式?—— 基于安全性和成本评估的用例](#which-mode--use-cases-rated-by-safety--cost) - [设置(全新 / 重置 Mac)](#setup-fresh--reset-mac) - [快速开始](#quick-start) - [命令](#commands) - [网络 —— 白名单](#networking--the-whitelist) - [多个终端](#multiple-terminals) - [开发服务器 / 端口](#dev-servers--ports) - [Claude 登录](#claude-login) - [安全模型 —— 及其局限性](#security-model--and-its-limits) - [目录结构](#layout) - [版权](#copyright) ## 这为什么重要 现代软件开发意味着要不断运行你未曾编写的代码: 克隆开源仓库、`npm install` 数以百计的传递 依赖项、尝试来自随机 GitHub 链接的工具。其中任何一个都可能 包含恶意的 **postinstall 脚本**或**被篡改的包**(这是 真实且常见的供应链攻击)。 在普通的 Mac 上,这些代码以**你的身份**运行 —— 它可以读取 `~/.ssh`、你的云 凭证、浏览器 token、`.env` 文件 —— 并将它们上传到任何地方。等到 你察觉时,你的密钥已经丢失了。 `airlock` 消除了此类攻击的两个主要环节: | 攻击步骤 | 没有 airlock | 使用 airlock | |---|---|---| | 读取你的机密 | 完整的家目录访问权限 | 仅挂载项目文件夹 | | 将它们发送出去 | 任何互联网主机 | 除域名白名单外阻止所有出站流量 | | 持久化 / 传播 | 可写入任何位置 | 只读根目录,一次性容器 | 这与 Anthropic 用于遏制 Claude Code 的模型相同: **文件系统隔离 + 网络出站控制。** 单靠其中任何一个都是不够 的 —— 隔离可阻止逃逸,出站控制可阻止数据泄露。 ## 何时使用(场景) - **运行不受信任的开源代码。** 克隆它,`airlock run`,探索一下。如果 它是恶意软件,它也无法触及你的密钥或回连控制服务器。 - **为拥有多个账户的客户进行部署。** 每次启动都会退出登录,因此你 每次都能以正确的客户身份重新进行 `vercel login` / `heroku login` —— 不会 出现跨账户混淆,磁盘上也不会保留任何凭证。 - **尝试可疑的 CLI / 安装脚本。** `curl … | bash` 风格的安装程序 将在容器中运行,而不是以你的身份运行。 - **在你的 Mac 上重现仅限 Linux 的 Bug**,而无需双系统启动。 - **真正恶意的代码或自主 agent。** `airlock sbx` 会在 microVM 中运行它,并使用其*独立的* kernel,因此即使是容器逃逸也无法触及你的 Mac —— 同时应用了相同的出站白名单。 ## 为什么即使是你*自己的*代码也要使用它 `airlock dev` 与其说是为了不信任,不如说是为了获得一个干净、一致、一次性的 工作站: - **与你的部署目标保持 Linux 一致性。** 你的代码在 生产环境的 Linux 上运行;在 Linux 中进行构建/测试可以在它们发布*之前*捕获“在我的 Mac 上能运行”的 Bug (路径大小写、原生模块、行尾)。 - **保持你的 Mac 纯净。** 没有全局的 `npm -g` 蔓延,没有版本管理器 冲突,没有残留的构建垃圾。清除容器,你的笔记本电脑 不受影响。 - **可复现 + 可共享。** 环境就是 `Dockerfile`。在任何机器上都具有相同的设置 ,并且在擦除后可恢复(参见设置)。 - **爆炸半径。** 错误的 `rm -rf`、失控的构建、fork 炸弹 —— 都会受到 容器的 CPU/内存/PID 限制和只读根目录的限制,而不是你的真实磁盘。 - **内置 Claude。** `claude` 已预装并已登录,因此你可以 在同一个干净的盒子内进行 AI 辅助工作。 ## 三种模式 | | `airlock run` (不受信任) | `airlock dev` (受信任) | `airlock sbx` (MICRO-VM) | |---|---|---|---| | **用途** | 你不信任的开源代码 | 你自己的代码 | 恶意代码 / agent | | **隔离** | 容器(共享 kernel) | 容器(共享 kernel) | **microVM(独立 kernel)** | | **主机机密** | 仅 Claude **token** | Claude token **+ 历史记录** | 无(仅限项目) | | **网络** | 🔒 仅限白名单代理 | 🌐 完整互联网 | 🔒 仅限白名单代理 | | **文件系统** | 仅限项目目录 | 仅限项目目录 | 仅限项目目录 | | **Claude Code** | ✅ 已登录(无历史记录) | ✅ 已登录(完整历史记录) | 使用 `docker sandbox run claude` | | **成本** | 轻量 | 轻量 | 较重(虚拟机内存 + 启动) | `run` 和 `dev` 共享安全强化特性:非 root 用户、**只读根文件系统**、 丢弃所有 Linux capabilities、无权限提升、基于内存的临时 家目录、CPU / 内存 / PID 限制,以及一次性(`--rm`)容器。 `sbx` 增加了**独立的 Linux kernel**(Docker Sandbox microVM),因此即使是 容器逃逸的 0-day 漏洞也无法触及你的 Mac —— 并应用了 airlock 相同的出站 白名单。它是最强大的,也是最重型的。 ## 选哪种模式?—— 基于安全性和成本评估的用例 **安全性** = 它包含恶意代码的程度。**成本** = 系统资源 + 启动时间。选择能覆盖你所受威胁的最轻量模式。 | 场景 | 模式 | 安全性 | 成本 | |---|---|:---:|:---:| | `npm install` / 克隆随机的开源仓库 | `run` | 🟢🟢🟢🟢 | 🪶 轻量 | | 运行你不信任的 `curl … \| bash` 安装程序 | `run` | 🟢🟢🟢🟢 | 🪶 轻量 | | 为客户部署(全新的 `vercel`/`heroku` 登录) | `run` | 🟢🟢🟢🟢 | 🪶 轻量 | | 真正**恶意**的代码 / 恶意软件分析 | `sbx` | 🟢🟢🟢🟢🟢 | 🔋 重型 | | 具有 shell 访问权限的**自主 AI agent** | `sbx` | 🟢🟢🟢🟢🟢 | 🔋 重型 | | 需要**防逃逸**边界的不受信任代码 | `sbx` | 🟢🟢🟢🟢🟢 | 🔋 重型 | | 你**自己的**项目 —— 在 Linux 上构建/测试 | `dev` | 🟡🟡 | 🪶 轻量 | | 你自己的代码 + 带有完整历史记录的 Claude | `dev` | 🟡🟡 | 🪶 轻量 | | 在你的 Mac 上重现仅限 Linux 的 Bug | `dev` | 🟡🟡 | 🪶 轻量 | **经验法则:** - **对于任何你不信任的东西,默认使用 `run`** —— 它已经阻止了机密 窃取(仅挂载了项目)和数据泄露(白名单)。对于全天 使用来说足够轻量,即使在 16 GB 内存的 Air 上也是如此。 - **只有在 kernel 逃逸会造成灾难性后果时(真正的 恶意软件、完全自主的 agent),并且你有多余的内存(microVM 在运行时可能会 占用主机约 50% 的内存)时,才升级到 `sbx`**。 - **仅对于你编写/信任的代码使用 `dev`** —— 它具有完整的互联网访问权限和你的 Claude 历史记录,因此不适用于不受信任的代码。 ### 安全阶梯(最安全 → 最不安全) ``` sbx 🟢🟢🟢🟢🟢 microVM (own kernel) + whitelist + no secrets — hostile code, agents run 🟢🟢🟢🟢 container + whitelist + token-only — untrusted OSS, deploys dev 🟡🟡 container + full internet + your history — your own trusted code ``` ## 设置(全新 / 重置 Mac) 如果你擦除或更换了 Mac,只需三个步骤即可恢复 airlock: 1. **恢复此文件夹** —— 从你的备份中恢复,或者 `git clone ` 到 例如 `~/sandbox/airlock`。(备份该文件夹!它是唯一的事实来源。 `.secrets/` token *不*会被备份,也不需要备份 —— 它会从你的 Keychain 重新 同步。) 2. **运行设置:** bash ~/sandbox/airlock/setup.sh 它会检查(并指导安装)Docker,创建 `airlock` alias,创建 `.secrets/`,构建镜像,并自检以确保白名单阻止 未知主机。重新运行是安全的。 3. **打开一个新终端**(或执行 `source ~/.zshrc`)并开始: cd && airlock run 如果未安装 Docker,`setup.sh` 将输出为你的芯片安装 Docker Desktop 的确切命令,然后你重新运行它即可。 ## 快速开始 ``` # UNTRUSTED: clone 可疑内容并安全运行 cd ~/some/cloned/oss-project airlock run # locked-down shell at /workspace # inside: npm install && npm run dev -- -H 0.0.0.0 # 在你的 Mac 上打开 http://localhost:3000 # TRUSTED: 使用 Claude 开发你自己的代码 cd ~/CodeBase/MyProject airlock dev # inside: claude ``` 你启动时所在的文件夹将成为 `/workspace` —— 这是容器可以看到的**唯一** 主机文件夹。 ### 工具链 - **Node 24.16**(默认),**pnpm** 和 **npm** 已预装并可离线使用。 - **nvm** 可用于切换 Node 版本:`nvm install 20 && nvm use 20`。 由于沙箱的家目录是临时的,通过 nvm 安装的版本会在当前 会话期间保留(下次启动需重新安装)。默认的 24.16 始终存在。 - 部署 CLI:**vercel · netlify · heroku · firebase · wrangler**。此外还有 **git**、**ripgrep** 和 **claude** (Claude Code)。 ## 命令 ``` airlock run [CMD] UNTRUSTED mode — no history, whitelist-only network airlock dev [CMD] TRUSTED mode — Claude login + full internet airlock sbx [CMD] STRONGEST — Docker microVM (own kernel) + same whitelist airlock exec [CMD] open ANOTHER terminal into the running sandbox airlock allow DOM add a domain to the egress whitelist (then rebuild) airlock blocked list the URLs/hosts the proxy denied (not whitelisted) airlock down stop & remove sandbox + proxy containers airlock status show images, what's running, and whether it's SAFE airlock build (re)build the images airlock rebuild rebuild from scratch (no cache) airlock logs follow proxy logs live (watch what's allowed/blocked) airlock help show help (also --help, -h) ``` 传递一次性命令而不是启动 shell:`airlock run npm test`、 `airlock dev claude`、`airlock exec vercel deploy`。 ### 每次启动都会告诉你当前的状态 `airlock run` / `airlock dev` 会打印一条横幅,以便你始终了解当前模式、 挂载的确切主机路径、网络策略以及你的登录状态。颜色会在 终端上显示,并在通过管道传输时自动禁用。 ``` ──────────────────────────────────────────────────── 🔒 airlock · UNTRUSTED safe — locked-down sandbox ──────────────────────────────────────────────────── path /Users/you/some/oss-project ↳ mounted at /workspace — the only host folder the box can see network whitelist only · 27 domains allowed, everything else blocked secrets none of your files · Claude token only, no history ports 3000 3001 5173 4000 8080 → http://localhost: on your Mac claude logged in (synced from your Keychain) ──────────────────────────────────────────────────── type 'exit' to leave — the container is destroyed (fresh next spin) ``` ### `airlock status` 这是一个仪表板,显示镜像、正在运行的进程(标记为 🔒 SAFE / ⚠ TRUSTED)、 两种模式,以及以**可读域名**(而非正则表达式)显示的网络白名单: ``` Running now 🔒 SAFE airlock-untrusted-run-… · untrusted · whitelist net · Up 5s Network whitelist · 27 domains reachable in 'run' mode; all others blocked *.npmjs.org github.com *.github.com registry.yarnpkg.com *.vercel.com api.anthropic.com … ``` ## 网络 —— 白名单 在 `run` 模式下,沙箱**没有直接的互联网连接**。它位于 `internal` Docker 网络上,只能连接到一个小型代理(`tinyproxy`,默认拒绝)。 代理**仅在目标主机匹配** `proxy/filter` **中的规则时** 才会转发请求 —— 包括 HTTPS(它过滤的是 `CONNECT` 主机)。 已验证的行为: ``` github.com -> HTTP 200 (allowed) registry.npmjs.org -> HTTP 200 (allowed) example.com -> 403 blocked anything-not-listed -> 403 blocked ``` 查看被阻止的内容,然后允许你信任的主机: ``` airlock blocked # lists denied hosts as URLs (works after exit too) airlock allow files.example.com airlock rebuild # bake the new whitelist into the proxy image ``` `airlock blocked` 输出示例: ``` Denied — not on the whitelist: ✗ https://tracker.evil-test.io 1× ✗ https://some-cdn.attacker.net 1× ``` 默认白名单:npm / yarn / pip / cargo、GitHub / GitLab、常见的部署 目标(Vercel、Netlify、Heroku、Cloudflare、Firebase)和 Anthropic。编辑 `proxy/filter` 进行批量更改(每行一个扩展正则表达式,与 主机匹配)。`airlock logs` 显示正在被阻止的内容。 ### `airlock sbx` —— microVM 模式(最强) `run` 和 `dev` 是容器(共享主机 kernel)。`airlock sbx` 在 **Docker Sandbox microVM** —— 它*独立的* Linux kernel —— 中运行 项目,因此即使是容器逃逸的 0-day 漏洞也无法触及你的 Mac。airlock 将其**相同的 默认拒绝出站白名单**应用于 microVM 的代理,因此它同时具备**防逃逸 和防泄露**功能。 ``` cd ~/some/cloned/oss-project airlock sbx # boot (or reuse) a microVM, apply whitelist, drop in airlock sbx npm test # one-off command inside the microVM airlock sbx --fresh # delete the old box and start a clean one airlock sbx down # destroy this project's microVM ``` - 需要 `docker sandbox`(Docker Desktop 4.58+)。如果缺少,airlock 会告知你, 你可以回退到 `airlock run`。 - microVM 复用 airlock 的工具链镜像作为其(Node、pnpm、部署 CLI)。使用 `AIRLOCK_SBX_TEMPLATE=` 进行覆盖,或将其设置为空以使用 Docker 的默认 shell 模板。 - 来自 `proxy/filter` 的相同白名单被转换到沙箱代理中 (已验证:未列入白名单的主机会收到 **403**,已列入白名单的主机收到 **200**)。通过 `docker sandbox network log` 查看被阻止的内容。 - **默认保留并重复使用**(按项目划分,一个 microVM)。这与 Docker 的 模型相匹配 —— 沙箱在重启后依然存在 —— 因此你的 `/login`、`nvm install` 以及 其他家目录设置可以在下次启动时保留下来,并且启动速度很快。Node 和 部署 CLI 已内置在镜像中,因此无论如何都不需要重新安装。 `airlock sbx --fresh` 删除旧盒子并创建一个干净的; `airlock sbx down`(或 `airlock down`)销毁它。 - Claude 不会自动植入(microVM 仅挂载你的项目),但由于 盒子被**保留**,你只需在其中运行一次 `/login`,它就会持续存在。或者使用 Docker 的原生 agent:`docker sandbox run claude`。 当你退出 `airlock run` 沙箱时,代理及其网络会 **自动销毁** —— 不会遗留任何连接互联网的进程。(如果第二个 `airlock exec`/`run` 终端仍处于打开状态,代理将保持运行,直到最后一 个终端退出。) ## 多个终端 不要运行两次 `airlock run` —— 这会启动*第二个*容器,并在 已发布的端口上发生冲突。改为附加到同一个容器: ``` airlock run # terminal 1: start it, run your app airlock exec # terminal 2, 3, …: jump into the SAME box ``` ## 开发服务器 / 端口 端口 `3000`、`3001`、`5173`、`4000`、`8080` 被转发到你的 Mac。**将 你的开发服务器绑定到 `0.0.0.0`**,而不是 localhost,否则主机无法访问它: ``` npm run dev -- -H 0.0.0.0 # Next.js / CRA npm run dev -- --host 0.0.0.0 # Vite ``` 然后打开 `http://localhost:3000`。需要其他端口?将其添加到 `docker-compose.yml` 中的 `ports:`,然后执行 `airlock build`。 ## Claude 登录 `claude` 已预装并在两种模式下均已登录。由于 macOS 将你的 Claude 登录信息保存在 **Keychain**(而非文件)中,`airlock` 将其导出到 `.secrets/.credentials.json`(chmod 600,被 git 忽略),以只读方式挂载,并 将其复制到容器的临时家目录中。Token 刷新仅在容器内进行,并且 **永远不会写回**你的 Mac。 - `dev` 模式还会挂载你的 `~/.claude` 历史记录;`run` 模式**仅挂载 token**(无过去的对话)。 - 首次运行会弹出 **Keychain 提示** → 点击 **始终允许**。 - 如果 Claude 提示“未登录”,请在其中运行 `/login`,或者在启动前设置 `ANTHROPIC_API_KEY`。 ## 安全模型 —— 及其局限性 **它可以防范的内容:** 恶意依赖项或脚本读取你的家 目录 / 密钥(文件系统隔离)以及泄露数据(出站白名单), 以及持久化和资源耗尽(只读根目录、一次性容器、 CPU/内存/PID 限制)。 **它无法防范的内容 —— 请实事求是:** - **共享 kernel(`run`/`dev`)。** 这些是容器,而不是虚拟机。kernel 级别的 容器逃逸(0-day)将击败它们。要获得最大的隔离,请使用 **`airlock sbx`**,它在具有独立 kernel 的 microVM 中运行。 - **项目目录是可读写的。** 不受信任的代码可以修改你打开的 文件夹中的文件(那是你自己的项目)。它无法触及其他任何内容。 - **列入白名单的域名是受信任的。** 如果你 `allow` 了一个域名,代码就可以与 它通信;GitHub/npm 可以托管任意内容。请保持列表严格。 - **不受信任模式下会存在 Claude token**(以便 `claude` 能在那里工作)。 不受信任的代码可能会读取它。代理会阻止将数据泄露给随机主机,但 白名单域名理论上可能会将其携带出去。如果这很重要:在 `docker-compose.yml` 中为 `untrusted` 设置 `AIRLOCK_SEED_CLAUDE=0`。如果 token 被暴露,请使用 `/logout` 撤销它或轮换你的登录信息。 - **Dev 模式不适用于不受信任的代码** —— 它具有完整的互联网访问权限和你的 历史记录。对于任何你不信任的内容,请使用 `airlock run`。 ## 目录结构 ``` ~/sandbox/airlock/ ├── airlock # the host CLI (aliased as `airlock`) ├── setup.sh # one-shot restore on a fresh/reset Mac ├── Dockerfile # sandbox image (Node + deploy CLIs + Claude) ├── docker-compose.yml # two profiles (run/dev) + proxy + networks + limits ├── entrypoint.sh # seeds Claude login (token-only in run, full in dev) ├── in-container.sh # `airlock` reminder shown inside the box ├── proxy/ │ ├── Dockerfile # tinyproxy image │ ├── tinyproxy.conf # default-deny egress config │ └── filter # the domain whitelist (edit / `airlock allow`) ├── .secrets/ # exported Claude token (git-ignored, chmod 600) └── README.md ``` ## 版权 © 2026 Syed Tasavour。个人开发者工具。 **按“原样”提供,不提供任何形式的担保**。`airlock` 显著提高了 攻击的成本,但并不能保证安全 —— 参见 [安全模型 —— 及其局限性](#security-model--and-its-limits)。你 对自己运行的代码和列入白名单的域名负责。 你可以自由地复制、修改和复用它,用于你自己的设置。
标签:Cutter, Docker, MITM代理, 安全防御评估, 安全隔离, 容器加固, 沙箱, 请求拦截