Fedora 开发邮件列表中最近在讨论向 Fedora 36 的 RPM 包中添加 fs-verity 文件完整性信息的事情。这个功能提供了一种方法来将 RPM 包中的文件安装为只读文件,如果这些文件中的数据发生了变化,就不再允许读取或进行其他操作。该提案的主要应用场景目前并不是很清晰,这也引发了一些疑问以及讨论参与者的质疑。
fs-verity and RPM
Fs-verity 是在一些文件系统已经支持的一个内核功能。它提供了一种方法来让人可以确认磁盘上的文件的内容不会改变。它为每个被保护的文件创建了 Merkle 树,这个树中包含了文件中每个数据块的 hash 值。当一个文件被 fs-verity 保护时,它会被标记为只读属性,每个读操作都会检查读取的数据块是否与树中存储的 hash 值可以匹配得上。如果不匹配的话操作就会失败。此外,树本身也可以采用密钥签名,从而确保文件系统不会有任何改变,也就是不会发生直接对块设备进行操作或者修改映像文件等操作。
Fedora 项目经理 Ben Cotton 代表这个功能的作者 Davide Cavalca, Boris Burkov, Filipe Brandenburger, Michel Alexandre Salim, 和 Matthew Almond 来发布了增加 fs-verity 支持的 Fedora 修改提案。该提案有几个要点。首先,Koji build system 需要能够为 RPM 包中的每个文件创建 Merkle 树并签名。树本身不会被添加到 RPM 包中,只有每个文件的签名过的 top-level hash 数据会放在 RPM 包中。
在安装的时候,RPM 有一个可选的 fs-verity 插件,可以确保安装 Fedora key,并为其安装的每个文件都启用 fs-verity。然后,文件系统将重新计算并建立 Merkle 树,比对 RPM metadata 中的签名数据来进行检查,并将这个树与文件一起存储下来。此后,对文件的每一次访问都将根据这个树来进行核对,这意味着各种操作(如 read()、mmap()、execve()等)要能正常执行的话,磁盘上的数据块就一定没有变化过。
该提案主要集中在 build 方面。”具体来说,默认安装和启用 fs-verity rpm 插件明确不包含在这个提案之内。” 在安装时创建 Merkle 树的开销,”根据经验性测试中没有看到软件包的安装速度有什么显著降低”,但为每一个 Koji build 都创建 Merkle 树当然会有一些(不确定的)成本。Merkle 树只有在启用 RPM fs-verity 插件的情况下才会被存储下来,并且使得安装文件大小增加大约 1/127(0.8%)。如果提案最终被采纳的话,所有的 RPM 包都会增加这些额外的签名过的元数据,但是整体来说这个开销也是基本可以忽略的。”在绝大多数情况下,我们预计 RPM header packing 的 size 只会增加一点甚至完全没有增加”。
Reaction
Kevin Fenzi 对该提案有一些问题。他想知道在 build 时会用哪些密钥来给 Merkle 树签名,以及谁会负责修改 RoboSignatory 组件(该组件为 Koji 提供签名)来完成这些功能。此外,目前只有 ext4、F2FS、以及 Linux 5.15 开始的 Btrfs 才支持 fs-verity。其他文件系统如 XFS 该怎么办?
Cavalca 回答说,功能开发者计划负责 RoboSignatory 的修改,但在代码 review、testing 和部署(deployment)方面需要大家的一些帮助和建议。他们将研究是否可以使用 Fedora package-signing key:
fs-verity 在软件包签名时需要一个 RSA 密钥/证书对(key/cert pair)来进行文件签名。在软件包安装时,该证书会被加载到相应的内核 keyring (密钥库)中。在测试的时候,我们一直使用一个专用的密钥对。我实际上也不确定软件包签名密钥是否被利用来做这个事情,因为它是一个 GPG 密钥,但这是我们后面打算调查的方向。
除此之外,如果文件系统本身不支持 fs-verity,那么该插件就会失败,也就不会具有这个保护功能了。他说,如果有需要的话,也可以针对 XFS 增加 fs-verity 支持。
Josh Boyer 询问了为 Fedora 添加 fs-verity 支持跟另一个类似的功能(为 RPM 添加 IMA 签名的提案,被拒绝的部分原因就是因为它对 RPM 大小有影响)。完整性测量架构(IMA,Integrity Measurement Architecture ) 是一个内核机制,可用于检测文件是否被篡改,但 Salim 说,fs-verity 对 RPM size 的影响要比 IMA 小很多。并且我们希望那些不安装 RPM 插件的用户也 “基本上不会被这个改动所影响”。该提案中比较了这两种完整性机制,还认为运行时的影响也更加小一些:
因为 fsverity 是在 block read 操作时进行的,所以它的 runtime cost 运行成本会很小(因为它只需要验证正在被访问的 block 就好),而且它可以确保在任何时间都没有进行过文件改动。
IMA 的工作方式是将文件作为一个整体进行测量,并在文件被读取或执行时跟签名进行比较。它的运行时间成本比 fsverity 高(因为它需要一次性验证整个文件),而且它不能检测在此之后修改此文件的情况。
该提案还说,IMA 提供了一个很丰富的策略系统(policy system),可以与其他安全机制(如 SELinux)结合起来。在未来将两者结合起来可能会是有意义的。但是 Boyer 以及其他一些人很希望了解 fs-verity 会给 Fedora 及其使用场景带来什么好处。Boyer 说,提案中列出的好处在很大程度上都可以由 IMA 来实现,所以他想再听到更多的解释。Cavalca 说,这个具体提案 “主要是关于建立必要的基础设施的”。此外他描述了一个潜在的使用场景:
例如,假如我们将一个应用设备放在了一个不可靠的地方,你可能无法阻止恶意访问者能触碰到这台设备(这可能是一台服务器,也可能是互联网接入点或学校的一个多媒体信息亭)。在这种情况下,fs-verity 可以用来确保并且保持系统可靠(system trust)性。
Cavalca 继续说,与大多数安全解决方案一样,fs-verity 不是一个一击必杀的武器,但它会是一个有价值的方案的一个组成部分:
一旦为某个特定文件启用了 fs-verity(在 RPM 的情况下,这个动作在软件包安装的时候就完成了),它就不能再被禁用,并且该文件就变得无法再进行修改了。人们仍然可以进行 rename() 或者 unlink() 等操作(这也是 rpm 在对这个 package 进行升级时用来替换这些文件的必需 API),但其实际内容无法被篡改了。
这在哪些情况会有用呢?例如,fs-verity 可以发现攻击者在对存储设备进行 out-of-band 访问(例如他们从 colo’d 服务器上取出一个硬盘,或从嵌入式设备上取出 SD 卡,或他们采用 liveusb 光盘启动,或者直接从 host 上来访问虚拟机的镜像文件)。
假设这种情况出现了,攻击者改变了设备上的/bin/ls 文件的几个 block 数据,使其运行恶意代码。当你再次启动你的系统时,它将在 exec() 的时候报错,因为 Merkle 树的数据匹配不上了。
但是,由于攻击者可以简单地替换这些文件,或者添加新的文件,所以设计中仍然缺失一部分,正如 Zbigniew Jędrzejewski-Szmek 指出的:
如果 fs-verity 验证使得我无法直接修改或替换 /usr/bin/foo 或 /usr/lib/systemd/system/foo.service,那么如果我直接添加 /etc/systemd/system/foo.service 来做我想做的操作,难道也会被阻止吗?
他问,是否有 Linux 安全模块(LSM)可以强制执行一些 policy 来确保系统完整性。除此之外,如果攻击者能够替换像 /bin/ls 这样的二进制文件,那么他们也可能会在内核 keyring 中添加新的密钥,使他们的二进制文件能够通过 fs-verity 检查:
如果密钥是从文件系统中加载的,那么我是否可以直接放入一个恶意密钥,就像每次发行版升级时也都会发布一些新的密钥?
Florian Weimer 提出了另外两个问题,他认为是 “无法解决的(unsolvable)”。攻击者可以把来自不相关的 Fedora 软件包的二进制文件拿进来用,这些文件是已经被正确签名的。或者他们也可以改变系统配置从而在启动时禁用这个功能。他基于这些问题认为,真正想要这种类型的保护的人不太可能会使用添加到 RPM 文件中的签名:
在我看来,这两个无法解决的问题的结合表明,任何想要部署这种功能的人最好使用他们自己的信任根,而这种方法也将包括他们特定版本的密钥管理。但这也意味着,预先计算的文件签名对他们来说并不[特别]有用。反正他们在部署前就必须丢弃它们。
Burkov 同意目前功能尚不完善,但他提到 Roberto Sassu 的一封邮件中有提到正在进行一些将 fs-verity 与 IMA 整合的工作,这可能会最终解决其中一些问题。但是,Lennart Poettering 同样指出了一些当前的 threat model 还完全不清晰的地方,也就是这些保护措施并没有真正针对 Fedora 用户可能遇到的问题来设计:
这保护的是文件内容,而不是[metadata],对吗?如果我今天看到一个启用了 fs-verity 的 inode,里面有 libssl.so 的数据,而且是一个有漏洞的版本,我给它做了一个 hardlink,然后它被替换成一个 fix 版本(名字稍有变化)。那么你打算如何来确保我无法欺骗你用新的名字来加载我的旧文件副本?
[……]对 RPM 包版本之间的 downgrade 操作有任何保护吗?是否会用什么方式来保护二进制文件和库文件的组合?我的意思是,我们发布的程序几乎全部都是由大量的 ELF 对象组成的,你可能需要对它们的组合进行签名,但这个 model 看起来完全没有提供这个功能?
有一些领域需要进一步研究,Burkov 说,但 threat model 并没有真正确定,因为这个提案只是希望实现基础功能:
简短的回答是,这个提案本身并没有提供 practical threat model (实际针对的威胁模型),我们把它看作是一个支持过程中的一个步骤,也就是需要一个现实 path 来对 rpm 内容进行广泛地签名验证。另外,它确实给了水平很高的用户们一个机会可以自己搭建这样的东西。
Poettering 对这一提案进一步表示了疑惑,他指出:”经验告诉我们,没有使用者的基础设施功能通常是行不通的。”。但是,即使解决了这一点,它所提供的保护也不是特别有用。”如果我可以让 ‘ping’ 和 ‘poweroff’ 的二进制文件都由 Fedora 签名,但然后交换这两者那么签名机制就无法检测出来了,那为什么还要这样做?”
还有人提出了其他担忧。例如,Stephen John Smoogen 出于一些事务性的理由来表示反对。任何改动提案都需要在 Fedora 36 的大规模 rebuild 之前完成,目前计划日期是 1 月 19 日。由于假期即将到来,那些需要 review 和对这类更改进行签字认证的人甚至都不太可能有足够时间完成这些工作。”即使这些改动是微不足道的,但是这么短的时间窗口要完成这些内容还是太紧张了。” 他建议,Fedora 37 可能是一个更加现实的目标。
在这个改动的 wiki 页面中已经更新了更多的内容,包括对讨论中受到的许多问题和担忧的回应。但是,如果没有一个真正的使用案例能确保 Fedora 某些实际用户集受益,那么这看起来像是一个很快就会消失的功能。也许现在需要的是和那些致力于 IMA 工作的人联合起来,提出一个综合的计划,能确保提供一个 threat model 以及真正的使用案例。例如,IMA 提案指出 Fedora IoT 版可能会需要用到该功能,这与 Android 中现有的 fs-verity 的使用更为一致。Boyd 明确表示,Red Hat 很有兴趣能在 Fedora 中看到 IMA 支持,因此如果配合起来合作,可能可以更加发挥协作作用。这种方法可能会在 Fedora 社区得到更多赞同票。
全文完
来源:LNW搬运工
By Jake Edge
December 14, 2021
DeepL assisted translation
https://lwn.net/Articles/878281/