周五下午,我像往常一样在 CI 服务器上跑 brew install,终端闪过一行新信息:“进程已放入 homebrew.sandbox 切片”。顺手敲下 pgrep 和 cat /proc//cgroup,输出里果然不是默认的 user.slice,而是 homebrew.sandbox。那一刻突然意识到:Homebrew 6.0 悄悄给 Linux 用户加了道防护门。
故事得从年初的讨论说起。Homebrew 维护团队早就在头疼一个问题:在所有用户共享一台编译服务器的环境里,一个公式(formula)的安装脚本可以读到你的 SSH 密钥、改掉 .bashrc,甚至把 /usr/local 搅得一团乱。6.0 版本给 Linux 端装上一个沙盒,核心思路不复杂——不搞容器,不拉隔离命名空间,直接用 systemd 对每个公式施加“睡眠管制”级别的约束。安装或运行时,systemd 把进程丢进一个专门的 cgroup 切片,限制它能碰的文件路径、系统调用能力和设备节点。一旦公式尝试往不该写的地方伸手,内核在 cgroup 层就把它挡回去了,根本不用惊动容器边界。
这条时间线复盘下来非常清晰:6.0 发布前,Homebrew 在 Linux 上几乎没有运行时防护,完全依赖用户自身的权限隔离。2024 年的某个里程碑提交后,沙盒逻辑被集成进 brew 命令。现在,每当你执行 brew install,Homebrew 就会对正要运行的公式做三件事:第一,拒绝访问 Homebrew 前缀之外的路径,除非公式自己的允许清单里明确要求;第二,丢掉 CAP_SYS_ADMIN 这类大多数编译用不着的能力;第三,限制设备访问,禁止公式去探测 /dev 下的内容。整个过程对你的工作流完全透明,只有在公式越权时才会触发失败。
这很容易让人把它和容器混淆。但实际上,沙盒没有命名空间隔离,没有独立的挂载表,也没有默认挂载 seccomp 过滤器。它靠的是 cgroup v2 和 capability 边界收缩——代码仍然以你的用户身份在跑,只是内核在资源与权限通路上加了限定。一个足够执着的公式,还是能在这些限制内造成破坏,只不过爆炸半径被实实在在压缩了。想做到彻底隔绝,你还得用上虚拟机或者真正的容器,但那样操作代价就大了。
发现这个功能后,我马上在几台共享的 Linux 构建机上验证了检查方法。装完公式,用 pgrep -f <公式名> 找到进程号,再 cat /proc//cgroup,如果输出里显示 homebrew.sandbox 切片,就说明沙盒已生效。有同事担心这会打断一些需要大范围访问的公式,比如编译内核模块或探测硬件的场景。好在 Homebrew 留了退路:一行 HOMEBREW_NO_SANDBOX=1 brew install <公式> 就能跳过防护。只不过用之前要提醒自己——沙盒之所以存在,正是因为你要跑的代码并非自己一行行审过的。
在 macOS 那边这件事则完全不同。Homebrew 6.0 的沙盒只对 Linux 生效,macOS 依旧依赖系统完整性保护(SIP)和传统 Unix 权限模型。毕竟两个平台的内核设施差异太大,Linux 有 cgroup v2 这么趁手的工具,macOS 却要另起炉灶。
站在开发者角度,Homebrew 6.0 这一步把威胁模型悄悄往前推了一把。它没有彻底解决共享环境里的信任难题,却把攻击者在公式里埋坑的门槛抬高了不少。如果你正在管着多用户的 Linux 编译机,不妨先用常见的公式测一轮,确认新的限制不会打断原有的构建假设,再全面铺开。日常安装里,你几乎感觉不到它的存在,但内核的 cgroup 切片每时每刻都在替你把关:那些惦记着 /home 下 dotfiles 的恶意写入,还没出手就被挡在外面了。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.