CVE-2026-91403 高危漏洞修复:Rocky Linux 9 多版本 JDK 环境清理实操

前言

近期,OpenJDK 官方披露了 CVE-2026-91403 高危漏洞。该漏洞的根源在于 Java JSSE 组件内置的信任库中,包含了受影响的 eMudhra (emSign) 根/中间证书。一旦攻击者利用泄露的私钥伪造域名证书,那些主动向外部发起 HTTPS 请求的 Java 应用(如支付网关、服务调用方)将面临中间人攻击的严重威胁。

然而,在处理这次漏洞时,我们遇到了两个运维痛点:

  1. 系统机制差异 :在 Rocky Linux 9 等红帽系系统中,底层证书受 RPM 保护,不能像 Ubuntu 那样直接 rm 删除。
  2. 环境复杂:老旧服务器上往往"缝缝补补",同时存在多个系统 JDK、独立部署的 JDK 甚至中间件自带的 JDK。

本文记录了我们在 Rocky Linux 9 环境下,如何通过"系统底层拆解拉黑"、"多版本 JDK 逐个清理"以及"统一业务运行环境"的方式,彻底闭环该漏洞的完整实操过程。


一、 核心修复思路

由于 Rocky Linux 底层证书受保护,我们的修复策略分为两步:

  1. 系统层 :采用"拆解拉黑法"。将系统大证书包拆解,提取目标坏证书放入 blocklist 黑名单目录,触发系统重新生成信任链。
  2. Java 层 :盘点全系统 JDK,清理 cacerts 物理库残留,并将独立安装的 JDK 统一替换为系统自带的最新 OpenJDK,便于后续维护。

二、 完整实操步骤

1. 系统底层证书清理(拆解拉黑法)
bash 复制代码
# 创建系统黑名单目录
sudo mkdir -p /etc/pki/ca-trust/source/blocklist/

# 拆解系统大证书包(利用 awk 将大文件拆分为多个独立的小证书文件)
mkdir -p /tmp/certs_split && cd /tmp/certs_split
sudo awk '/BEGIN CERTIFICATE/ {c++; fn="cert-" c ".pem"} c > 0 {print > fn}' /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

# 遍历拆分出的证书,精准提取 emSign 并丢入黑名单
for f in cert-*.pem; do
  if openssl x509 -in "$f" -noout -subject | grep -qi "emSign"; then
    sudo cp "$f" /etc/pki/ca-trust/source/blocklist/
    echo "✅ 成功拉黑: $f"
  fi
done

# 刷新系统信任库,使黑名单生效
sudo update-ca-trust extract
2. 全系统 JDK 环境盘点
bash 复制代码
# 在多 JDK 共存的服务器上,找出所有 keytool 的路径
find / -name keytool 2>/dev/null

(预期会看到:系统 JDK、独立安装的 JDK、中间件自带的 JDK 等路径)

3. 逐个清理各版本 JDK 的残留证书

系统层的拉黑,部分系统 JDK 会自动同步,但独立部署的 JDK 不会,必须逐一验证并物理清理。

检查系统 JDK (以 17 为例):

bash 复制代码
/usr/lib/jvm/java-17-openjdk-*/bin/keytool -list -cacerts -storepass changeit | grep -i emsign
  • 预期结果 :无输出。如果有残留,使用 sudo keytool -delete -alias "别名" -cacerts -storepass changeit 逐条删。

检查中间件自带 JDK (以 Elasticsearch 为例):

bash 复制代码
/usr/share/elasticsearch/jdk/bin/keytool -list -keystore /usr/share/elasticsearch/jdk/lib/security/cacerts -storepass changeit | grep -i emsign
  • 预期结果 :如果有输出,同样通过 keytool -delete 删掉,然后重启对应服务。
4. 统一业务服务的 JDK 运行环境

说明:原业务可能使用了独立安装的 /opt/jdk1.8,为方便后续统一打补丁管理,建议将其统一替换为系统自带的 OpenJDK。

bash 复制代码
# 备份原 systemd 配置文件
sudo cp /etc/systemd/system/<your-app-name>.service /etc/systemd/system/<your-app-name>.service.bak

# 批量替换启动路径(路径请替换为你的系统 JDK 绝对路径)
sudo sed -i 's|/opt/jdk1.8/jre/bin/java|/usr/lib/jvm/java-1.8.0-openjdk/bin/java|g' /etc/systemd/system/<your-app-name>.service

# 重载配置并重启服务
sudo systemctl daemon-reload
sudo systemctl restart <your-app-name>.service

三、 全系统终极验证

全部操作完成后,执行以下命令进行排查(除了系统信任锚允许残留正常的 C2/G2,其余必须全部无输出!):

1. 验证系统信任锚状态

bash 复制代码
trust list --filter=ca-anchors | grep -i -B 2 -A 2 "emSign"

2. 验证系统 JDK

bash 复制代码
/usr/lib/jvm/java-1.8.0-openjdk/bin/keytool -list -keystore /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/security/cacerts -storepass changeit | grep -i emsign

3. 验证业务独立部署的 JDK

bash 复制代码
/opt/jdk1.8/jre/bin/keytool -list -keystore /opt/jdk1.8/jre/lib/security/cacerts -storepass changeit | grep -i emsign

4. 验证底层大证书包

bash 复制代码
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem | grep -i emsign

四、 验证结果的标准判定

在执行完上述验证命令后,需按以下标准进行确认:

  • 针对大证书包(第 4 条) :终端可能输出 Could not find certificate from <stdin>,这是 openssl 处理 PEM 格式时的正常提示,只要没看到具体的 emSign 证书主体,即视为清理成功。
  • 针对各个 JDK :必须做到完全静默(无任何输出)。如果出现 Warning 提示(如提示使用 -cacerts),但下方没有列出具体别名,也属于安全状态。
  • 服务状态确认 :验证完成后,必须使用 systemctl status <your-app-name> 确认所有的 Java 业务进程已正常拉起,处于 active (running) 状态。

五、 📌 运维避坑指南

在本次多台服务器的清理过程中,总结了以下几条经验,供后续运维参考:

  1. 关于残留的 C2 和 G2 :这两个证书不在此次 CVE 漏洞影响范围内,保留是系统的正常行为,不要去强行删除,以免破坏系统底层依赖。
  2. 关于老旧 JDK :某些早期发布的老版本 JDK(如 1.8.0_211)天生不包含这些坏证书,keytool 查不到残留时,无需强制替换其黑名单文件。
  3. 备份的重要性 :在修改 systemd 配置文件或清理物理文件前,务必保留 .bak 备份,以便在出现未知兼容性问题时能够快速回滚。
  4. 重启提醒 :无论是修改了系统证书库还是替换了 JDK 黑名单,必须重启对应的 Java 业务进程。因为 JVM 只有在启动时才会将信任库加载到内存中,不重启等于没修。
  5. 后续清理 :业务平稳运行 1 个月后,确认无回退需求,可顺手删掉 /etc/systemd/system/*.service.bak 以及 /tmp/certs_split 等临时目录,保持系统干净。

清理前:

清理后:

相关推荐
On The Road :1 小时前
Java 多线程详解:从入门到线程安全
java·python·安全
Shaoshing1 小时前
LeetCode100 49. 字母异位词分组
java·算法
云上先途12 小时前
企业 AI 服务部署周期多久,会不会影响原有业务运转?
大数据·运维·人工智能
划破黑暗的第一缕曙光2 小时前
[C++]:5.STL:string(2)
java·c++·redis
hhhjhl2 小时前
Undici 跨端三方库仓颉适配全流程
java·开发语言·ubuntu
wangchunyu1142 小时前
JAVA JVM内存结构与运行时数据区
java·开发语言·jvm
执伞人ONLY2 小时前
AI知识库自动化知识加工没做对,人工整理永远追不上知识产生
运维·人工智能·自动化
slongzhang_3 小时前
linux 递归删除源码文件|递归删除目录下 *.js,但排除 *.min.js
linux·开发语言·javascript
叼烟扛炮3 小时前
Linux 学习笔记(三十三):线程互斥——互斥锁(Mutex)与死锁
linux·运维·服务器·笔记·学习·1024程序员节