错误信息
Warning: Ignoring extra certs from `/etc/ssl/private-ca/corp-root-ca.pem`, load failed: error:80000002:system library::No such file or directory
路径就是该变量的值;原因则各不相同:文件不存在时为“No such file or directory”,文件不可读时为“Permission denied”,文件存在但不是 PEM 格式时则是 OpenSSL 的 PEM 错误。
Node.js start-up — NODE_EXTRA_CA_CERTS could not be read
含义
Node.js 在启动时读取了 NODE_EXTRA_CA_CERTS,但无法加载其中指定的文件,因此会在缺少你额外添加的 CA 证书的情况下启动。进程不会停止;需要这些证书的连接稍后会报错:“unable to get local issuer certificate”或“self-signed certificate in certificate chain”。“load failed:”后面的 OpenSSL 原因说明了为什么加载失败。
原因
路径在宿主机上存在,但在 Node.js 运行的地方不存在
常见变量被复制到了 Dockerfile、CI 配置或 devcontainer 中,而证书文件还留在开发者的机器上;在容器或运行器内部,这个路径并不存在。
相对路径或未展开的 ~
常见./certs/ca.pem 这样的值相对于进程的当前工作目录解析;而 .env 文件或 systemd 单元中的“~/certs/ca.pem”不会经过任何 shell 展开。
文件不可读或格式错误
偶见从 Windows 以 DER 格式(.cer)导出的证书、只有 root 能读取的文件,或者内容不是 PEM 证书的文件。
修复方法
- 1.
检查变量指向的文件
确认对运行 Node.js 的用户而言该路径存在,并且 openssl 能把它作为 PEM 证书读取。
bash echo "$NODE_EXTRA_CA_CERTS" ls -l "$NODE_EXTRA_CA_CERTS" openssl x509 -in "$NODE_EXTRA_CA_CERTS" -noout -subject # must be PEM: -----BEGIN CERTIFICATE----- - 2.
容器:文件要与变量一起提供
把 CA 证书复制到镜像中(或挂载进去),路径与变量中指定的路径相同。
text # Dockerfile: put the file where the variable points, inside the image COPY corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt ENV NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/corp-root-ca.crt - 3.
使用绝对路径
设置变量时就把路径展开,使其不依赖工作目录或 shell 展开。
bash # Absolute path, expanded by the shell before node starts export NODE_EXTRA_CA_CERTS="$HOME/certs/corp-root-ca.pem" - 4.
将 DER 转换为 PEM
NODE_EXTRA_CA_CERTS 要求 PEM 格式。用 openssl x509 -inform der 转换二进制导出的文件;多张证书可以拼接到同一个 PEM 文件中。
bash # A DER (.cer) export from Windows must be converted to PEM first openssl x509 -inform der -in corp-root-ca.cer -out corp-root-ca.pem