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 缓解方案 [![CI](https://github.com/USER/REPO/actions/workflows/ci.yml/badge.svg)](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报告查看器, 内核命令行, 安全缓解, 应用安全, 本地提权, 漏洞修复, 特权升级, 系统加固, 系统提示词, 网络安全培训, 自动化运维