跳到主要内容
ecdsa.com
Node.js tls / https / fetchNode.js crypto 模块

错误信息

self-signed certificate in certificate chain

也可能输出为

  • code: 'SELF_SIGNED_CERT_IN_CHAIN'
  • SELF_SIGNED_CERT_IN_CHAIN

Node.js 16 及更早版本(OpenSSL 1.1.1)写作“self signed certificate in certificate chain”。使用 fetch() 时,它作为“TypeError: fetch failed”的原因出现;npm 将其打印为“npm error code SELF_SIGNED_CERT_IN_CHAIN”。

Node.js tls / https / fetch — code SELF_SIGNED_CERT_IN_CHAIN (OpenSSL X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, 19)

含义

服务器发送的证书链终止于一张自签名根证书,而它不在 Node.js 信任的根证书之列。在公司网络中,这是执行 TLS 检查的代理的典型特征:代理用自己的根证书为每个网站重新签名,并把该根证书放进证书链。Node.js 使用的是内置的 Mozilla 根证书列表,而不是 IT 部门安装代理根证书的操作系统证书存储。

原因

修复方法

  1. 1.

    查看证书链由谁签发

    连接一个公共网站,逐级查看对端证书链。如果最顶端的证书以你的公司或某家安全厂商命名,就信任这个根证书;如果来源不明,在信任任何东西之前先调查清楚。

    bash
    openssl s_client -connect registry.npmjs.org:443 -servername registry.npmjs.org -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'
    # The last line pair shows the root the chain ends in (s: and i: identical)
  2. 2.

    用 NODE_EXTRA_CA_CERTS 添加根证书

    对于该进程的每个 TLS 连接,文件中的证书都会添加到内置根证书之中,包括 npm、yarn 和 fetch 的连接。在进程启动前设置该变量。

    bash
    export NODE_EXTRA_CA_CERTS=/etc/ssl/private-ca/corp-proxy-root.pem
    node app.js
  3. 3.

    使用操作系统的证书存储

    --use-system-ca 或 NODE_USE_SYSTEM_CA=1 让 Node.js 接受操作系统信任的根证书,这样 IT 部门部署的代理根证书无需复制文件即可生效。

    bash
    # Managed machines already trust the proxy root in the OS store
    node --use-system-ca app.js
    NODE_USE_SYSTEM_CA=1 npm run build
  4. 4.

    临时诊断:NODE_TLS_REJECT_UNAUTHORIZED=0

    为整个进程禁用证书验证。只在单次运行中用它确认原因;在经过拦截代理的网络中,它还会掩盖代理之外的任何攻击者。

    bash
    # Temporary diagnostic only: confirms trust is the only problem, then remove it
    NODE_TLS_REJECT_UNAUTHORIZED=0 node app.js

相关错误

浏览完整的签名错误库