CentOS 7 的生命周期在 2024 年 6 月 30 日已经正式画上句号。如果你还在维护存量服务器,面临的第一个棘手问题不是系统无法启动,而是执行常规的 yum update 时发现官方源已经失效,大量高危 CVE 漏洞处于未修复状态。更麻烦的是,CentOS 8 更早停止支持,CentOS Stream 又并非传统意义上的稳定版。对于生产环境,重装系统迁移到 Rocky Linux 或 AlmaLinux 固然是长远之计,但在业务窗口期到来之前,必须先把现有的高危漏洞堵上。这里的核心思路是:切换至 CentOS Vault 归档源进行存量修复,并结合手动打补丁的方式处理那些归档源也不再更新的“残留”高危漏洞。

现状诊断:快速摸清家底

在动手修复之前,不要盲目操作。先通过一套标准化命令把当前系统的漏洞暴露面摸清楚。执行 rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | grep -iE 'kernel|openssl|openssh|bash|glibc|polkit|sudo',这条命令会列出系统中最容易出问题的核心组件版本。接着,用 yum updateinfo list cves 或者直接读取 /var/log/yum.log 来确认最近一次成功更新的时间。如果你看到最后更新时间停留在 2024 年 6 月前后,说明系统已经断更很久了。对于仍然在安全机构监控范围内的资产,可以导出已安装软件包清单 rpm -qa --qf "%{NAME}\n" > /tmp/pkg_list.txt,然后批量比对公开的 CVE 数据库,重点标记出 CVSS 评分大于 7.0 的漏洞。这一步不是为了凑报告,而是为了让你清楚哪些漏洞是必须立刻解决的,比如涉及权限提升的 PwnKit(CVE-2021-4034)或者远程代码执行的 OpenSSL 漏洞。

修复前置条件:正确切换至 Vault 归档源

很多人发现 yum 报错 404 后就束手无策,其实 CentOS 官方把停止维护的发行版内容全部归档到了 vault.centos.org。你需要做的不是寻找野路子源,而是精确修改 repo 文件指向归档地址。以 CentOS 7 为例,先备份原有配置:cp -r /etc/yum.repos.d /etc/yum.repos.d.bak。然后执行以下批量替换脚本,将 mirrorlist 注释掉,把 baseurl 指向 vault,并排除掉快速镜像的干扰。

sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo

执行完毕后,务必运行 yum clean all && yum makecache 重建缓存。如果这一步报错,多半是 vault 路径中包含了类似 $releasever 的变量没有正确解析,你需要手动检查 /etc/yum/vars 或者直接在 repo 文件里把路径写死为 http://vault.centos.org/7.9.2009/(以最终版本号为准)。源切换成功后,不要急着全量更新。全量更新在生产环境风险极大,可能导致依赖链断裂。你应该先执行 yum check-update 查看待更新列表,然后采用分类分批修补的策略。

高危漏洞批量修复的优先级策略

面对几百个待更新包,眉毛胡子一把抓必然出问题。建议按照“内核与驱动 -> 系统核心库 -> 远程服务组件 -> 本地提权工具”的顺序来操作。内核修复是收益最高但风险也最高的环节。对于 CentOS 7 末期内核,很多高危漏洞如 Dirty Pipe(CVE-2022-0847)的修复包含在 kernel-3.10.0-1160 之后的版本中。你可以直接执行 yum update kernel kernel-headers kernel-tools 来安装最新归档内核。注意,不要卸载旧内核,保留 2 到 3 个已知良好的旧版本内核,防止新内核导致硬件驱动不兼容。修改 /etc/default/grub 中的 GRUB_DEFAULT=saved 并执行 grub2-mkconfig -o /boot/grub2/grub.cfg,这样即使新内核启动失败,也能在启动菜单回滚。

接下来是 glibc 和 OpenSSL 这两个“基建”库。很多上层应用依赖它们,修复时必须特别注意 soname 的变化。在 CentOS 7 末期,官方并没有通过 yum 推送最新的 OpenSSL 3.x,而是通过补丁方式将 1.0.2k 版本的安全修复 backport 回来。你通过 vault 源更新到 openssl-1.0.2k-26.el7_9 这类版本即可覆盖大部分已知的 TLS 握手降级漏洞。更新完毕后,不要忘记重启所有依赖动态链接库的服务,或者直接安排一次计划重启。你可以用 lsof | grep libssl | awk '{print $1}' | sort | uniq 找出所有还在使用旧版 OpenSSL 库的进程,然后针对性重启。

处理 Vault 源也无法覆盖的“钉子户”漏洞

这是最棘手的部分。CentOS 7 在停止维护前,某些软件包版本已经定格,但后续又爆发了新的高危漏洞。例如,Sudo 的某些特定逃逸漏洞或者 Polkit 的深层逻辑缺陷,可能并没有在 CentOS 7 的归档更新中得到完全修复,因为 Red Hat 当时评估后认为影响有限或者修复代价过大。对于这类残留漏洞,不能依赖 yum。你需要根据 CVE 编号寻找源码或 SRPM 进行二次编译。以修复高风险本地提权漏洞为例,如果确认 Polkit 版本过低且无官方包,可以从 CentOS 官方归档下载对应版本的 SRPM 包:wget http://vault.centos.org/7.9.2009/os/Source/SPackages/polkit-0.112-26.el7.src.rpm。然后搭建一个临时的编译环境 yum-builddep polkit,接着提取补丁。去相应的安全公告页面下载针对该 CVE 的补丁文件,手动打入 SPEC 文件并重新打包。这种操作虽然繁琐,但能确保系统的完整性不被野包破坏,且完全兼容现有的 RPM 体系。

还有一个容易被忽视的残留漏洞重灾区是容器环境依赖。很多运维只在宿主机上跑更新,却忘了内部运行的 Docker 容器基础镜像也是 CentOS 7。你需要进入容器内部执行同样的 vault 源切换操作,或者直接重新构建镜像。在 Dockerfile 中,将 RUN yum update 替换为带有 vault 源切换逻辑的脚本,确保新生成的镜像不再包含已知高危组件。

自动化批量修复脚本框架

如果你管理着几十台甚至上百台 CentOS 7 机器,逐台登录操作不现实。可以基于 Ansible 或简单的 SSH 批量工具来执行。下面给出一段轻量化的 Shell 批量修复框架,核心逻辑是只修复高危漏洞列表里的包,避免全量更新。

#!/bin/bash
# 定义高危包列表
HIGH_RISK_PKGS="kernel openssl-libs openssh-server bash glibc sudo polkit"

# 备份当前 repo
cp -r /etc/yum.repos.d /etc/yum.repos.d.bak.$(date +%Y%m%d)

# 强制切换至 vault 源
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo
yum clean all && yum makecache fast

# 仅更新高危相关包,保留旧内核
for pkg in $HIGH_RISK_PKGS; do
    echo "正在处理: $pkg"
    yum update -y $pkg 2>&1 | tee -a /var/log/cve_fix.log
done

# 检查是否有服务需要重启
needs-restarting -r
echo "修复完成,请检查 /var/log/cve_fix.log 并安排重启。"

这段脚本在执行前务必在测试环境验证。其中 needs-restarting 命令来自 yum-utils 包,它能告诉你哪些进程因为库更新需要重启。对于 OpenSSH 的更新要格外小心,建议在更新前确保有带外管理卡或者 VNC 控制台,防止 sshd 重启失败导致断连。在批量推送时,建议分批执行,先跑 10% 的节点观察 24 小时,确认业务无异常再全量铺开。

修复后的验证与长效防御机制

补丁打完之后,必须验证漏洞是否真的被关闭了。不能只看 RPM 版本号,因为存在 backport 导致版本号不变但漏洞已修复的情况,也存在版本号升了但修复不完整的情况。推荐使用开源工具如 Vulners 的审计脚本或者本地搭建的漏洞扫描器进行复扫。执行 yum updateinfo list cves 如果不再显示对应的高危 CVE 编号,说明 yum 层面的元数据认定修复完成。对于手动编译修复的组件,需要编写专门的 PoC 验证脚本。例如,验证 PwnKit 漏洞是否修复,可以直接尝试执行 pkexec /bin/bash,看是否会触发 segfault 或者直接获取 root 权限。如果系统正确拒绝或崩溃,说明补丁生效。

修复只是治标,对于还在跑 CentOS 7 的机器,必须建立一套“临终关怀”机制。第一,开启严格的本地防火墙白名单,只放行必要的业务端口,将 SSH 等管理端口通过堡垒机收敛。第二,部署 HIDS(主机入侵检测系统),监控 /bin、/sbin、/usr/lib 等目录的文件完整性,任何对系统二进制的篡改都要告警。第三,将 yum 源锁定在 vault,并内网化。你可以用 Nginx 反代 vault.centos.org,在内网搭建一个静态文件归档源,这样既能保证下载速度,又能避免未来 vault 域名变更或彻底下线带来的风险。第四,尽快制定迁移时间表。CentOS 7 的内核版本停留在 3.10,这个内核本身已经不再具备接收现代安全架构升级的能力,比如 eBPF 的某些安全模块就无法在 3.10 内核上运行。用 Rocky Linux 9 或者 AlmaLinux 9 进行原地升级或者逐步替换,是解决残留漏洞的最终方案。

最后要提醒的是,不要因为 CentOS 停止支持就盲目安装网上来路不明的“一键修复脚本”或者第三方野源。很多野源为了兼容性,会替换掉系统的核心库,导致 RPM 数据库损坏,后续再想迁移系统都变得极其困难。坚持使用官方 vault 源加 SRPM 重编译,虽然操作门槛高一些,但这是保持系统血统纯正、避免供应链投毒的唯一途径。对于残留的高危漏洞,只要按照上述分类分批、先核心后外围、先测试后生产的步骤来操作,完全可以在不中断业务的前提下,将安全风险降到最低。