10 月 23 日,很多 Cloudflare 用户收到一封紧急邮件:
请立即把所有平台上的 Cloudflare One Client 升级到最新稳定版。
起因是印度证书机构 eMudhra 的 8 张中间证书私钥泄露了。但这件事里,最容易被误解的一点是:它不只是"更新浏览器"的问题。
一、先看清楚漏的是什么
泄露的是 8 张中间证书的私钥,不是根证书。
这个区别很重要。信任库里放的是根证书,中间证书是服务器在握手时自己发出来的。所以:
- 你去系统信任库里翻,找不到那 8 张出事的证书 —— 它们本来就不在那儿;
- 但只要根证书还在信任库里,攻击者就能用泄露的中间证书,伪造一条挂在这个根下面的链,你的机器照样会信。
而且这批私钥不是"被偷走"的,是本来就很弱:
priv: 00:00:00: ... :00:04
正常 P-384 私钥应该是 48 字节的随机数,而 eMudhra 这一份就是数字 4。研究人员从 1 开始往回枚举,猜到 4 就命中了 —— 也就是任何人都能算出来。
二、Cloudflare 到底做了什么

官方博客给的时间线是精确到分钟的(全部 UTC):

官方定性也很直接:
这些证书被浏览器、操作系统、以及 Cloudflare 内部广泛信任。因为密钥本身很弱,攻击者可以为任意域名伪造证书、冒充服务器,拦截或篡改流量。这是一起影响整个互联网的严重安全事件。
同时补了一句让客户稍微安心的话:安全审查尚未发现该问题被用于攻击 Cloudflare 自身服务。
三、要升到哪个版本
邮件里最实用的部分是版本号。下面这张按「产品 + 平台」列,左边是产品,右边是要升到的版本:

除了客户端,官方还列了三类需要自己动手的:
- mTLS 客户端认证:检查你上传的 CA / trust store;
- 源站证书:用了 Full (strict) 或 Strict 模式的,检查自定义源站证书;
- Cloudflare Containers(含 Sandboxes):检查容器镜像和依赖里的 trust store。
四、为什么"更新浏览器"不够
官方博客里有一段话,是整篇最值得抄下来的:
对开发者来说,要看 SDK 底下那一层。一个 API 客户端可能把证书验证委托给 HTTP 库、语言运行时、操作系统或自定义信任配置。只更新 SDK 不一定改变底层策略。
举个具体的例子:你升级了某个 Python 包的版本,但它调用的是系统的 OpenSSL 和系统信任库 —— 那真正决定"信不信这张证书"的,还是 `ca-certificates` 那个包。SDK 升了等于没升。
还有一个坑,官方专门提醒:
打上补丁后,你可能会在面板里看到证书错误。千万不要用"关闭验证"来解决 —— 那正好把这次更新要恢复的防护给拆了。
这条我有切身体会。很多教程遇到证书报错,第一反应就是加 `-k` 参数、或者设 `verify=False`。平时这么干只是不安全,在这种事件里这么干,等于主动把自己暴露在伪造证书面前。
五、浏览器为什么能"一键修",服务器不能
官方自己也承认了这件事的不公平:
浏览器厂商只要动一下开关就能修好 —— 当然他们只有一个应用要更新,而不是几百个,但他们确实有个好办法:大多数浏览器用的是快速撤销机制(比如 Chrome 的 CRLSets)。
而服务器上是几百个组件、几百个 trust store,得逐个更。所以 Cloudflare 提到了 upki 项目 —— 让信任库不再是"一张静态的根证书列表",而是能快速接收撤销信息的动态东西。
这件事真正的教训可能在这儿:浏览器侧的吊销早就工业化了,服务端还在手工搬砖。
六、拿自己的机器走一遍
我按官方那四类,把这台 Debian 13 的机器查了一遍。
① 有没有 CF 的客户端
command -v cloudflared
command -v warp-cli
(都没有输出)
两个都没装,所以客户端那部分和我无关。
② 本站证书是谁签的
echo | openssl s_client -connect 127.0.0.1:443 -servername fshier.com 2>/dev/null | openssl x509 -noout -issuer
issuer=C=US, O=Let's Encrypt, CN=YE2
Let's Encrypt 签的,不是 eMudhra,源站这条也安全。
③ 系统信任库里有没有 emSign
ls /etc/ssl/certs/ | grep -iE 'emsign|emudhra'
emSign_ECC_Root_CA_-_C3.pem
emSign_Root_CA_-_C1.pem
emSign_Root_CA_-_G1.pem
有三张。但逐个验过,三张都是自签名根证书:
openssl x509 -in /etc/ssl/certs/emSign_Root_CA_-_G1.pem -noout -subject -issuer
subject=C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign Root CA - G1
issuer=C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign Root CA - G1
issuer 等于 subject,说明是根,不是那 8 张出事的中间证书 —— 这印证了开头那句:中间证书本来就不在信任库里。
④ ca-certificates 有没有更新
apt-cache policy ca-certificates
Installed: 20250419+deb13u1
Candidate: 20250419+deb13u1
装的和候选是同一个版本,Debian 暂时没推送移除这几个根的更新。
所以现在的状态是:
- 入站(别人访问你):不影响;
- 出站(你访问别人):理论上可被伪造的证书冒充,但需要攻击者主动做中间人(DNS 劫持、路由劫持这类),日常风险不高。
结论:不用慌,但 `ca-certificates` 一有更新就该升。
七、你该查的四件事
不用全部做,按你实际用的挑:
① 装了 Cloudflare Tunnel 吗
cloudflared --version
有输出就升到 2026.10.2。这个和很多人有关 —— 把家里 NAS、软路由挂到公网,用 Tunnel 的人不少。
② 装了 WARP / Cloudflare One 吗
warp-cli --version
有输出就按上面表格升。
③ 源站证书是不是 eMudhra 签的
openssl x509 -in /path/to/fullchain.pem -noout -issuer
如果输出里有 `eMudhra` 或 `emSign`,说明你的源站证书挂在那批出事的链上,需要换证书。
④ 有没有自带 trust store 的软件
Docker 镜像、Java 的 `cacerts`、Python 的 `certifi`、Node 的 `NODE_EXTRA_CA_CERTS` —— 这些各自维护自己的列表,不会跟着系统更新。
# 检查 Docker 容器里的 bundle 时间
docker exec 容器名 ls -l /etc/ssl/certs/ca-certificates.crt
时间太老(比如几个月前)就说明它没跟上系统更新。
八、这件事以后会怎么发展
说句实话,这次 eMudhra 事件的处置,暴露的是整个生态的结构性问题:
- 浏览器:3 小时内就能全网生效;
- 操作系统:一天到几天;
- 你的服务器:取决于你有多少个组件、多少个 trust store、多少个镜像 —— 可能永远更不完。
所以 Cloudflare 才在这个时间点推 upki。你我能做的只有一件:把自己那层的清单列清楚,别等出事才现查。
事实与版本号来自 Cloudflare 官方博客(2026-10-20)与官方邮件;本机数据为本文写作时的实测。相关阅读:Windows 上手动阻断 eMudhra 中间证书。

F12笔记






