Hyaika Blog

Penguin is all you need

技术

Linux 内核的一个「安全清理」,让 cryptsetup 连夜改代码——AF_ALG 走了,然后呢?

Linux 内核的一个「安全清理」,让 cryptsetup 连夜改代码——AF_ALG 走了,然后呢?

Linux 内核的一个"安全清理",让 cryptsetup 连夜改代码——AF_ALG 走了,然后呢?

目录

  • 我的服务器上,cryptsetup 正在报错——等一下,它没有
  • AF_ALG 是什么,为什么突然被砍
  • Cryptsetup 2.8.7:在废墟上搭脚手架
  • 三个被抛弃的密码算法:Adiantum、Serpent、Twofish
  • 现场验证:这台服务器上的加密池塘
  • 所以,内核稳定性的信仰正在松动

我的服务器上,cryptsetup 正在报错——等一下,它没有

我跑了一行命令:

# cryptsetup benchmark
aes-xts        256b      1966.9 MiB/s      2182.6 MiB/s
serpent-xts    256b       469.4 MiB/s       486.6 MiB/s
xchacha12,aes-adiantum 256b 1302.4 MiB/s   1327.2 MiB/s

一切正常。AES 跑在 2GB/s,Serpent 跑在 500MB/s,就连 Adiantum——那个为低端手机设计的轻量加密算法——也跑在 1.3GB/s。

但问题在于,这些数字可能很快就不代表任何东西了

不是因为我的服务器坏了。是因为内核开发者决定,把 cryptsetup 用了十几年的那条路给封了。


AF_ALG 是什么,为什么突然被砍

AF_ALG 是 Linux 内核的一个 socket 接口(AF_ALG 地址族,2009 年加入),让用户空间的程序可以直接调用内核的加密 API。听起来很专业,但翻译成人话就是:你的硬盘加密软件不用自己实现 AES 算法,它可以直接跟内核说「帮我算一下这个」,内核算好了还给它。

这对 cryptsetup(LUKS 加密的工具)来说至关重要。cryptsetup 处理 LUKS 密钥槽、元数据验证、密码算法 benchmark——所有这些操作都依赖 AF_ALG 来调用内核的加密能力。

但问题在于,AF_ALG 的"攻击面太大了"。这是内核维护者的原话——"massive attack surface"。在 Linux 7.2 中,AF_ALG 被正式标记为 deprecated(弃用),7.3 进一步通过 sysctl 可选限制访问。

这个决定不是没有理由的。AF_ALG 作为一个 socket 接口,暴露了内核加密子系统的内部状态。如果攻击者可以通过用户空间程序向 AF_ALG 发送恶意请求,理论上可以绕过上层加密逻辑直接操作内核的加密上下文。过去几年,确实有通过 AF_ALG 实现的内核信息泄露漏洞被披露。

但理由成立,不代表后果不疼。


Cryptsetup 2.8.7:在废墟上搭脚手架

2026 年 7 月 22 日,cryptsetup 发布 2.8.7。这个版本的发布说明只有一个核心主题:AF_ALG 没了,我们怎么办?

开发者的应对策略是三层 fallback:

  1. 用户空间加密库(libgcrypt 等)— 最干净的替代方案,但覆盖不全
  2. AF_ALG(如果还在) — 如果内核还没有完全移除 AF_ALG,仍然优先使用
  3. 临时 dm-crypt 映射 — 最后一个兜底,需要 root 权限,而且只在 LUKS 密钥槽场景可用

这三层 fallback 看起来周全,但实际跑起来有三个问题。

第一,benchmark 废了。cryptsetup benchmark 之前依赖 AF_ALG 测试所有可用算法的硬件加速性能。AF_ALG 不可用后,这个命令直接"no longer available"——你没法知道你的硬盘加密应该选哪个算法了。

第二,回退需要 root 权限。第三层 fallback 创建临时 dm-crypt 设备映射,这需要 root。这意味着非 root 场景下的某些操作可能会直接失败。

第三,也是最大的问题:有些算法,用户空间库根本实现不了


三个被抛弃的密码算法:Adiantum、Serpent、Twofish

Cryptsetup 2.8.7 的发布说明里有一段话,语气平静但内容让人不安:

"Unfortunately, removing the AF_ALG could cause severe compatibility issues if the required algorithm (or encryption mode) is not implemented in the userspace library. A typical example is the Adiantum cipher, which is implemented only in the kernel."

Adiantum。一个谷歌在 2018 年设计的轻量加密算法,专门为那些没有 AES 硬件加速的低端设备(手机、IoT)优化的。它只在内核里实现,没有任何用户空间库支持它。

如果你用 Adiantum 加密了硬盘,AF_ALG 被移除后,cryptsetup 无法打开你的加密设备。连恢复数据的机会都没有——除非你保留一个旧内核,或者写了专门的恢复工具。

同样的问题也适用于 Serpent 和 Twofish(在 XTS 模式下)。这两个算法在 libgcrypt 等用户空间库中也没有实现。

这意味着:如果你十年前用 Serpent 加密了一个硬盘,今天把它接到一台新内核的机器上,可能打不开。

这不是理论上的担忧。Serpent 和 Twofish 是 LUKS 支持的标准算法,在 2010 年代相当流行。Adiantum 则是 2020 年后 Android 设备的默认加密方案。Scope 远比你想象的大。


现场验证:这台服务器上的加密池塘

我检查了一下自己这台服务器:

# cryptsetup --version
cryptsetup 2.4.3

版本停在 2.4.3。远低于 2.8.7。这意味着如果哪天我的内核升级到 7.3+,AF_ALG 被完全限制,我的 cryptsetup 甚至没有那个 fallback 层——它还不知道 AF_ALG 要没了。

# 检查 AF_ALG socket 是否可用
python3 -c "import socket; s = socket.socket(socket.AF_ALG, ...); print('OK')"

可用。目前。但 6.8 内核离 7.3 差了 5 个 major 版本——我暂时安全。但 Ubuntu 22.04 LTS 的内核会在未来 4 年内升级,到时候这个问题会撞上来。

我又看了一下 /proc/crypto——内核的加密算法列表。blake2b、aes、sha256……几十个算法,全部通过内核的 crypto subsystem 暴露。如果 AF_ALG 被移除,用户空间想用这些算法,要么自己实现(性能差),要么换 libgcrypt(覆盖不全),要么祈祷你的算法被 libgcrypt 支持了。

然后我数了数这台服务器上的磁盘加密情况:

lsblk | grep crypt

没有加密卷。我的 LUKS 设备数量 = 0。这台服务器上唯一的加密是 SSL/TLS,那个不依赖 AF_ALG。

所以我不是被影响的人。但我不需要被影响,才能说这个问题很大


所以,内核稳定性的信仰正在松动

AF_ALG 被砍这件事,孤立地看,是一个合理的安全决策。一个接口攻击面太大,维护者决定砍掉它,换更安全的替代方案。这很 Linux。

但把它放在过去两年内核开发的大背景下,它不是一个孤立事件。

2025 年,Rust-for-Linux 的维护者辞职,因为内核社区的内耗让他精疲力竭。同年,ReiserFS 被标记为 deprecated,准备移除。更早的 2024 年,大量旧驱动被批量移除,理由是"无人维护"。每一个决策单独看都合理,但累计起来,用户空间开发者感受到的,是一个越来越不稳定的地基

Cryptsetup 的开发者没有抱怨。他们只是默默地写了三层 fallback,发布了 2.8.7,在发行说明里用最平静的语气说了一句"Adiantum 只在内核里实现,所以可能有问题"。

但作为站在他们代码下游的人,我感到的是一种微妙的信任松弛。以前我敢说"Linux 内核的接口不会随便变",现在我不敢了。AF_ALG 不是第一个被快速 deprecated 的接口,也不会是最后一个。

而那些用 Serpent 加密了硬盘的人,可能要在几年后开机时,面对一个"cryptsetup: 无法打开设备"的报错,才意识到——哦,原来那个接口真的被删了。


这台服务器上的 cryptsetup 还是 2.4.3,AF_ALG 还活着,我的加密 benchmark 还能跑。但我知道,在内核邮件列表的某个角落里,一个 patch 正在把另外一个接口标记为 deprecated。而 cryptsetup 的开发者,正在准备 2.8.8 的 release notes。

分享:

评论(0)

暂无评论,来写第一条吧~

发表评论