aestechno/cve-2026-31431-ansible
GitHub: aestechno/cve-2026-31431-ansible
基于 Ansible 的 CVE-2026-31431 内核本地提权漏洞批量检测与缓解自动化方案,支持 Debian/Ubuntu/RHEL 系列发行版。
Stars: 3 | Forks: 0
# CVE-2026-31431 ("Copy Fail") — Ansible 缓解方案
[](https://github.com/USER/REPO/actions/workflows/ci.yml)
检测并在 Debian / Ubuntu / RHEL 系列集群中应用针对 **CVE-2026-31431** ("Copy
Fail") 的内核命令行缓解方案。
该 CVE 是 Linux 内核 `algif_aead` AF_ALG 接口中的一个本地权限提升漏洞。任何非特权的本地用户
(包括 `www-data`、`mysql` 等服务账户,或遭遇 RCE 的 Web 应用中的进程)
都可以通过几个系统调用将其提权至 root。该漏洞影响了自 2017 年以来发布的所有主要发行版。
## 本方案的功能
- **检测**哪些主机缺少缓解措施。默认为只读模式。
- 当使用 `-e apply_mitigation=true` 调用时,**应用**通用缓解措施 — 将 `initcall_blacklist=algif_aead_init` 追加到内核命令行。
- **绝不自动重启。** 是否重启由运维人员决定。
内核命令行黑名单适用于内建(RHEL 系列)和模块化(Debian/Ubuntu)**两种**配置,
而常被提及的 `modprobe blacklist algif_aead` 应急方案则无法做到。
## 缓解方案的工作原理
`algif_aead_init()` 是在引导时向加密套接字子系统注册 `aead` AF_ALG 算法的内核函数。
命令行参数 `initcall_blacklist=algif_aead_init` 指示内核跳过该 initcall。易受攻击的代码
仍保留在内核二进制文件中,但 `socket(AF_ALG, ..., "aead")` 会返回 `ENOENT`,因此漏洞利用的
第一个系统调用就会失败。没有可触及的攻击面,就没有权限提升。
一旦供应商发布了修复后的内核并且您重新启动进入新内核,该缓解措施便不再需要,可以将其移除。
## 快速开始
```
# 检测(只读) — 生成每台主机的状态报告
ansible-playbook -i inventory check_cve_2026_31431.yml
# 首先在单台主机上暂存缓解措施(不自动重启)
ansible-playbook -i inventory --limit \
-e apply_mitigation=true check_cve_2026_31431.yml
# 通过您常用的机制重启该主机
# 重新检测;确认 "Mitigation active: yes"
# 分批部署到其余的 fleet
```
存在漏洞的主机报告如下所示:
```
═══════════════════════════════════════════
Host: 192.168.1.42
Distro: Ubuntu 24.04
Kernel: 6.8.0-60-generic
Mitigation active: no
Mitigation staged: no
═══════════════════════════════════════════
⚠️ 192.168.1.42: CVE-2026-31431 mitigation is NOT active.
```
## 在安装修补后的内核后进行回退
这不在本方案的范围内。手动操作的一行命令:
```
# Debian / Ubuntu
sudo sed -i 's/ initcall_blacklist=algif_aead_init//' /etc/default/grub
sudo update-grub
sudo reboot
# RHEL 家族
sudo grubby --update-kernel=ALL --remove-args="initcall_blacklist=algif_aead_init"
sudo reboot
```
## 不会失败的运行行为
检测路径是严格只读的(`uname`、读取 `/proc/cmdline`、读取 `/etc/default/grub`、`grubby --info=ALL`)。
探测使用 `failed_when: false`,因此意外输出永远不会中止 Playbook 的运行。
`ignore_unreachable: true` 意味着无法连接的主机将收到清晰的
"UNREACHABLE — treat as VULNERABLE"(不可达 — 视为存在漏洞)警告,而不是导致运行失败。
应用路径被包裹在 `block`/`rescue` 中,因此单台异常主机永远不会
阻止其余主机的运行。对 grub 的编辑是幂等的,并且受 `mitigation_staged` 控制,
因此重复运行是空操作。
## 测试
```
bash tests/run-checks.sh all
```
阶段:`lint` (yamllint + ansible-lint) → `syntax`
(`ansible-playbook --syntax-check`) → `dry-run`(以 `--check` 模式、
使用 `-c local` 针对 `localhost` 执行 playbook,覆盖检测和应用
两条路径)。相同的脚本会在每次推送和拉取请求时,
由 GitHub Actions 矩阵在 `debian:12`、`ubuntu:22.04`、`ubuntu:24.04` 和 `almalinux:9` 容器中被调用。
空运行(dry-run)**不会**验证的内容:
- 它不会修改 grub、运行 `update-grub` 或触发重启。
- CI 容器内的 `/proc/cmdline` 显示的是宿主机的 cmdline,
而不是容器的,因此 CI 输出中的 `mitigation_active` 是无意义的。
CI 证明了 playbook 可以*干净地运行*;但并不能证明主机已
得到缓解。
详见 `tests/README.md`。
## 来源
- [Help Net Security — CVE-2026-31431](https://www.helpnetsecurity.com/2026/04/30/copyfail-linux-lpe-vulnerability-cve-2026-31431/)
- [CloudLinux — 缓解措施与已修复的内核版本](https://blog.cloudlinux.com/cve-2026-31431-copy-fail-mitigation-and-patches)
- [Ubuntu — CVE-2026-31431](https://ubuntu.com/security/CVE-2026-31431)
- [Debian 安全追踪器 — CVE-2026-31431](https://security-tracker.debian.org/tracker/CVE-2026-31431)
- [Tenable 常见问题解答 — Copy Fail](https://www.tenable.com/blog/copy-fail-cve-2026-31431-frequently-asked-questions-about-linux-kernel-privilege-escalation)
- [CERT-EU SA 2026-005](https://cert.europa.eu/publications/security-advisories/2026-005/)
## 致谢
该漏洞由 **Taeyang Lee (Theori)** 发现,并被 **Xint Code Research Team**
武器化为完整的漏洞利用链,正是他们促使安全社区关注此问题。
本方案仅仅是自动化了他们推荐的缓解措施。
## 许可证
Beerware。参见 [`LICENSE`](LICENSE)。TL;DR: 随意使用;
如果我们相遇,请我喝杯啤酒就好。
## 维护者
[AESTECHNO](https://www.aestechno.com) — Hugues Orgitello —
电子设计事务所,法国蒙彼利埃。
标签:AF_ALG, algif_aead, Ansible, CVE-2026-31431, Debian, initcall_blacklist, Linux内核漏洞, Playbook, RHEL, Web报告查看器, 内核命令行, 安全缓解, 应用安全, 本地提权, 漏洞修复, 特权升级, 系统加固, 系统提示词, 网络安全培训, 自动化运维