错误信息
npm error code UNABLE_TO_VERIFY_LEAF_SIGNATURE
也可能输出为
- npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
- npm error request to https://registry.example.com/lodash failed, reason: unable to verify the first certificate
npm 10 及更高版本打印“npm error code UNABLE_TO_VERIFY_LEAF_SIGNATURE”;npm 9 及更早版本打印“npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE”。较新的 Node.js 版本会在原因行后追加“; if the root CA is installed locally, try running Node.js with --use-system-ca”。
npm (Node.js) — registry request over HTTPS
含义
注册表(或它前面的代理)只发送了自己的证书,Node.js 找不到签发它的证书。没有颁发者,就根本无法检查叶子证书的签名。这是服务器配置问题:握手中缺少中间证书,而 Node.js 不会通过下载来补上它。
原因
只配置了叶子证书的私有注册表
常见Nexus、Artifactory、Verdaccio 或它们前面的反向代理安装的是 cert.pem,而不是完整证书链。
只出示叶子证书的代理
偶见有些执行 TLS 检查的代理发送的证书由某个中间证书签发,却没有附带该中间证书。
来自未知私有 CA 的叶子证书
偶见如果 Node.js 不认识叶子证书之上的任何证书,也会出现同样的代码;信任该 CA(及其中间证书)即可解决。
修复方法
- 1.
统计握手中的证书数量
如果只有深度 0,且其颁发者是中间证书,就可以确认缺少中间证书。
bash openssl s_client -connect registry.example.com:443 -servername registry.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' - 2.
在注册表上提供完整证书链
为注册表前面终止 TLS 的组件配置叶子证书和中间证书。这样可以一次性为 npm、yarn、pnpm、Docker 以及其他所有客户端修复问题。
text # Registry behind nginx: serve leaf + intermediate(s) ssl_certificate /etc/nginx/tls/registry.example.com.fullchain.pem; ssl_certificate_key /etc/nginx/tls/registry.example.com.key; - 3.
变通办法:在客户端信任中间证书
包含中间证书及其根证书的 cafile 能让 npm 在服务器修复之前验证叶子证书;cafile 会替换 npm 的默认根证书,因此如果同一个 npm 还要使用 registry.npmjs.org,也要加入公共根证书。
bash # Until the registry is fixed: trust the intermediate (plus its root) on the client cat issuing-ca.pem corp-root-ca.pem > /etc/ssl/private-ca/registry-ca.pem npm config set cafile /etc/ssl/private-ca/registry-ca.pem