Linux 中的 AI 代理沙箱化

发布: (2026年2月4日 GMT+8 01:35)
5 分钟阅读

Source: Hacker News

沙箱化

标准的解决方案是对代理进行沙箱化——可以在远程机器上(exe.devsprites.devdaytona.io),也可以在本地通过 Docker 或其他虚拟化机制实现。

在 Linux 上的轻量级替代方案是 bubblewrap,它利用 Linux 内核特性(如 cgroups 和用户命名空间)来限制(监禁)进程。

事实证明,bubblewrap 是对 AI 代理进行轻量级沙箱化的良好方案。以下是我个人对这种方案的需求:

  • 模拟我常用的 Linux 开发机器环境(我不想管理多个开发环境)。
  • 限制对除当前项目所需信息之外的任何信息的访问。
  • 仅对当前项目拥有写入权限。
  • 直接操作项目的文件/文件夹,这样我可以轻松地在 IDE 中检查或修改同一文件,或自行运行代码。
  • 网络访问——既能连接 AI 提供商并搜索互联网,又能启动服务器供我连接使用。

bubblewrap 和 Docker 并非硬化的安全隔离机制,但这对我来说已经足够。我并不真正担心以下风险:

  • 通过零日 Linux 内核漏洞逃逸。
  • 隐蔽的侧信道通信。
  • 从当前项目(包括项目专用的访问密钥)中泄露数据。
  • 破坏代码库(代码通过 git 管理,并在 GitHub 或其他地方备份)。

另一种做法是通过创建项目专用的 API 密钥来限制潜在损害,这样即使密钥泄露,影响范围也会最小化。

Source:

实际操作

下面是我的 bubblewrap 沙箱脚本示例:

#!/usr/bin/bash

exec 3<$HOME/.claude.json

exec /usr/bin/bwrap \
    --tmpfs /tmp \
    --dev /dev \
    --proc /proc \
    --hostname bubblewrap --unshare-uts \
    --ro-bind /bin /bin \
    --ro-bind /lib /lib \
    --ro-bind /lib32 /lib32 \
    --ro-bind /lib64 /lib64 \
    --ro-bind /usr/bin /usr/bin \
    --ro-bind /usr/lib /usr/lib \
    --ro-bind /usr/local/bin /usr/local/bin \
    --ro-bind /usr/local/lib /usr/local/lib \
    --ro-bind /opt/node/node-v22.11.0-linux-x64/ /opt/node/node-v22.11.0-linux-x64/ \
    --ro-bind /etc/alternatives /etc/alternatives \
    --ro-bind /etc/resolv.conf /etc/resolv.conf \
    --ro-bind /etc/profile.d /etc/profile.d \
    --ro-bind /etc/bash_completion.d /etc/bash_completion.d \
    --ro-bind /etc/ssl/certs /etc/ssl/certs \
    --ro-bind /etc/ld.so.cache /etc/ld.so.cache \
    --ro-bind /etc/ld.so.conf /etc/ld.so.conf \
    --ro-bind /etc/ld.so.conf.d /etc/ld.so.conf.d \
    --ro-bind /etc/localtime /etc/localtime \
    --ro-bind /usr/share/terminfo /usr/share/terminfo \
    --ro-bind /usr/share/ca-certificates /usr/share/ca-certificates \
    --ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \
    --ro-bind /etc/hosts /etc/hosts \
    --ro-bind /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf \
    --ro-bind /usr/share/zoneinfo /usr/share/zoneinfo \
    --ro-bind $HOME/.bashrc $HOME/.bashrc \
    --ro-bind $HOME/.profile $HOME/.profile \
    --ro-bind $HOME/.gitconfig $HOME/.gitconfig \
    --ro-bind $HOME/.local $HOME/.local \
    --bind $HOME/.claude $HOME/.claude \
    --bind $HOME/.cache $HOME/.cache \
    --file 3 $HOME/.claude.json \
    --bind "$PWD" "$PWD" \
    claude --dangerously-skip-permissions "$@"

如果这看起来相当特立独行,那是因为它本来就是这样。与其使用通用规则,我反复尝试 bwrap,直到找到我的系统所需的最小配置。

一些有趣的细节

  • /tmp/proc/dev 会被 bwrap 自动处理。
  • 我以与本机相同的路径绑定挂载(即暴露)文件和目录,所以文件位置或项目路径没有区别。
  • 我没有暴露整个 /etc,只挂载了必需的最小集合。
  • $HOME/.claude.json 的内容会被注入到沙箱中,因此对该文件的任何更改都不会影响真实文件。
  • $HOME/.claude/ 目录是 读写 映射的,允许 Claude 保存会话数据。
  • /opt/node/node-v22.11.0-linux-x64/ 是我自定义的 Node.js 安装位置。
  • 更改主机名可以轻松区分宿主机和沙箱。

我可能会根据需要微调脚本,但这对我来说已经是一个相当稳固的起点。

如何自定义

如果你想将其适配到其他 AI 代理或你的系统,我的建议是修改脚本,使其运行 bash,然后手动启动你的代理,观察出现的问题并相应地进行调整。

一个有用的命令是 strace,它可以跟踪文件访问系统调用,让你看到需要哪些文件:

strace -e trace=open,openat,stat,statx,access -o /tmp/strace.log codex

检查日志以找出所需的文件,并根据需要进行绑定挂载。

Back to Blog

相关文章

阅读更多 »