证书查不出毛病,老服务器就是拉不到更新:一个 KeyUsage 位的坑
先说现象:最气人的是"静默"上个月排查过一件事。我们有个部署在客户机上的自更新脚本(防爆破用的),其中一条更新通道走 HTTPS 下载。有天发现一批机器版本一直不动,日志里既没有"已更新",也没有任何报错——静默失败。
上机手动 curl 一下下载地址,才看到真报错:
curl: (60) Certificate key usage inadequate for attempted operation.
NSS error -8102 (SEC_ERROR_INADEQUATE_KEY_USAGE)
更怪的是:同一个地址,Windows、新系统上 curl 都是 200,就 RHEL/CentOS 7 这批老机器不行。
https://blog.7ehl.com/usr/uploads/2026/10/2399698453.png
证书本身查不出毛病
curl -v 看握手:连接建立、证书链完整、没过期、域名也匹配——每一样都"正常",就是被 key usage 拦下。把证书拉下来看扩展:
https://blog.7ehl.com/usr/uploads/2026/10/2200537457.png
问题就在这:这张免费 DV 证书的 X509v3 Key Usage 标着 critical,但只给了 Digital Signature,没有 Key Encipherment。
为什么只有老机器踩
关键差异在 TLS 栈:
· 老 RHEL/CentOS 7 的 curl 走 NSS 后端。握手用 RSA 密钥交换时,NSS 硬性要求证书带 Key Encipherment 位——没有,直接拒。
· 新系统的 TLS 栈默认走 ECDHE,密钥交换不靠证书加密,根本不看这一位。
所以不是证书"坏了",是同一张合法证书,新老 TLS 栈校验松紧不一样。这也是为什么搜这个问题,答案清一色"加个 -k 就行"——能用,但很少有人说得清为什么只有老机器要加。
修法:回退式拉取 + 验签兜底
1. 拉取改回退式:先 curl -fsS 走正常校验,失败再回退 -k(wget 对应 --no-check-certificate)。目标是别让老机器卡死在传输层。
2. 安全不押在 TLS 一层:更新包带独立 RSA 签名,拉下来先验签,验不过坚决不更新(fail-closed)。TLS 只当传输,防篡改靠签名。
3. 失败必须写日志。这次排查最浪费时间的不是 bug 本身,是"静默"——原版脚本失败一声不吭,看起来就像"从来没触发过"。
另外提醒一句:已经卡住的老机器,新脚本它自己拉不下来,得一次性手动升级或重新部署捞回来——自更新通道修好了,也救不了还没更新过的那批。
一句话总结:下次遇到"证书明明没问题、就老机器拉不动",先看一眼证书的 KeyUsage 有没有 Key Encipherment,再想想对面是不是 NSS。能讲清"为什么只有老机器坏",才算真踩过这个坑。 这个坑我也踩过,根子在 NSS 那套确实比 OpenSSL 严。除了 Key Encipherment,还有个同源的:老客户端(CentOS7、XP 那代 TLS 栈)对 SNI、中间证书链缺失也很敏感——fullchain 少一段,新系统能靠 AIA 自动去补,老机器直接断在握手。
你第 3 点「失败必须写日志」我太认同了,静默失败才是排查噩梦。自更新这种脚本,只要中间一声不吭,出问题就是黑盒,只能靠上机手 curl 才看得见。
页:
[1]