为什么 nosuid 会让 VPN 辅助程序无法取得 root
加密家目录和 nosuid 挂载是两种不同的属性。辅助程序需要可信的安装路径,以及尊重其特权位的启动环境。
磁盘加密与 nosuid 挂载听起来像是同一个想法的变体,其实两者毫无关系。一个保护静态数据,另一个决定内核在程序启动的那一刻是否尊重特权位。辅助程序无法获得它预期的身份,抱怨的正是后者。以为是前者造成的,会让人去重装从未损坏的客户端。
两种互不相关的属性
磁盘加密回答的是机器关闭时谁能读取磁盘块。挂载选项回答的是有人执行文件时内核对模式位会怎么处理。前者对后者没有任何约束,而一台完全加密的笔记本照样可以在所有限制到位的情况下挂载文件系统。
把两者当成同一件事,才会产生“加密家目录阻止 root 访问”的说法。这个说法之所以流传,是因为两个症状出现在同一台机器上,而不是因为它们同源。
真正抑制这种转换的是什么
execve 的文档描述了带 set-user-ID 的可执行文件如何把新进程的有效身份改成文件所有者。同一页还列出了抑制这一转换的条件,以及组 ID 的对应条件:no_new_privs 设置、以 nosuid 挂载的文件系统,以及正在被跟踪的进程。文件能力在相同条件下同样会被忽略。这四条规则几乎覆盖了所有此类报告。
这份清单解释了为什么 ls 打印的模式位从来不是授权的全貌。它不会告诉你哪一条条件造成了某条具体的失败消息,而程序也可能用同样的措辞报告一个无关的凭证操作。在下结论之前,请记录确切的程序、启动器和错误顺序。
确认受支持软件包安装的可执行文件、它的所有者、真实路径,以及承载它的文件系统策略。下载文件夹里的一份副本不是已安装的辅助程序,无论它的模式位写着什么。
不要做的事
给未经核验的二进制文件加上 set-user-ID 位,然后到处搬动直到限制消失,这不算修复。它是用你无法审计的特权替换你没弄懂的策略,而把同样的手法用在辅助程序上是一条众所周知的提权路径。从挂载中移除 nosuid 更糟,因为它影响的是该文件系统上的每一个程序,而不只是一个。
受支持的路径是由管理员执行的、客户端文档中规定的辅助程序或服务安装,它会把二进制文件放到策略预期的位置。这样只保留一套特权机制,而不是两套。
确认真实的启动环境
在获准的修正之后,要按产品自身的方式运行辅助程序,而不是从 root shell 里运行。以 root 身份成功,对普通用户走的路径毫无证明力,而这两种环境的差别正是这次故障的关键。
然后确认辅助程序存在的目的,也就是它要完成的网络操作。如果辅助程序能启动却 无法配置接口,那只是把问题往后推了一个阶段,并没有解决。
findmnt -no TARGET,OPTIONS /home
getcap /usr/libexec/openvpn-helper 2>/dev/null; ls -l /usr/libexec/openvpn-helper
把挂载选项和辅助程序的所有者记在同一条笔记里。否则下一个排查的人会从头再走一遍加密的猜测。