Node.js https 请求 UNABLE_TO_GET_ISSUER_CERT_LOCALLY
Nodejs https request UNABLE_TO_GET_ISSUER_CERT_LOCALLY
OS:debian sid
节点:v0.10.38
我有一个使用身份验证的私人服务请求:
var https = require('https');
var options = {
host: 'private.service.com',
path: '/accounts/' + '123323' + '/orders',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 0,
'Authorization': 'Bearer ' + 'asdsdgcvxcvxcv'
}
};
var request = https.request(options, function (res) {
console.log(res);
});
当我 运行 脚本时,节点抛出此错误:
events.js:72
throw er; // Unhandled 'error' event
^
Error: UNABLE_TO_GET_ISSUER_CERT_LOCALLY
at SecurePair.<anonymous> (tls.js:1381:32)
at SecurePair.emit (events.js:92:17)
at SecurePair.maybeInitFinished (tls.js:980:10)
at CleartextStream.read [as _read] (tls.js:472:13)
at CleartextStream.Readable.read (_stream_readable.js:341:10)
at EncryptedStream.write [as _write] (tls.js:369:25)
at doWrite (_stream_writable.js:226:10)
at writeOrBuffer (_stream_writable.js:216:5)
at EncryptedStream.Writable.write (_stream_writable.js:183:11)
at write (_stream_readable.js:602:24)
同一个脚本几个月来运行良好,我确信身份验证是正确的。今天是第一次遇到这种情况。
导致此错误的原因是什么?
经过一番研究,我发现这是我尝试向其发出 https 请求的服务器的问题。
节点 https 在 private.service 服务器上找不到 ssl ISSUER_CERT,因此抛出该异常。
我使用的解决方案是添加
,因为我确定我可以信任该服务器
rejectUnauthorized: false
https请求的选项,这样节点在证书问题的情况下不会抛出异常。
无论如何,只有当您知道可以信任您的请求的主机时,此解决方案才有效,否则它可能不是最佳解决方案。
SSL 是有原因的。除了其他功能外,它还可以验证您是否真的在与 private.service.com
主机名标识的服务器通信。否则您的客户端软件可能会被中间人攻击欺骗。
首先,当任何人遇到此问题时,他们应该更新系统根 SSL 证书。在 Debian 中,它们包含在 ca-certificates
apt-get 包中。
如果没有帮助,服务器可能使用了颁发者证书,默认情况下全球 PKI 基础设施不信任该证书。在这种情况下,客户端应将证书 public 密钥签名与预共享值进行比较。这被称为 "certificate pinning"。
具体针对您的错误,如果之前有效,则可能是服务器证书已过期。服务器应该更新它。作为临时解决方案,您可以通过 rejectUnauthorized
选项关闭 PKI 验证。但是,您应该将它与固定方法一起使用。在 NodeJS 中,您可以从 res.socket.getPeerCertificate().fingerprint
.
获取服务器证书指纹
当我尝试在 Ubuntu 16 上安装 npm 时,我遇到了同样的错误。
以下命令对我有用。
npm config set registry http://registry.npmjs.org/
经过研究,问题解决了:
npm set strict-ssl=false
希望对您有所帮助。
来自 this GitHub issue,使用以下环境变量:
export NODE_EXTRA_CA_CERTS=/path/to/certfile.crt
在此之后,您可以 运行 任何 npm
命令,nodejs 将信任您的额外证书文件。
.crt
文件是一个包含前缀行、base64 编码证书和后缀行的文件。
如果您手边没有根 CA 证书,您可以使用 openssl
命令从 URL 生成证书文件:
openssl s_client \
-showcerts \
-servername <host> \
-connect <host>:443 2>/dev/null </dev/null | \
openssl x509
其中 <host>
是 url 的主机名。例如,使用 google.com
作为主机,输出如下所示:
-----BEGIN CERTIFICATE-----
MIIIIDCCBwigAwIBAgIQI/1aCHwDN94QFUhXJeIwODANBgkqhkiG9w0BAQsFADBU
(42 more lines)
E+Hv1bJSbOMSNCDzqRM3JUzvM6Y=
-----END CERTIFICATE-----
将其保存为您的 .crt
文件并将其路径添加到 NODE_EXTRA_CA_CERTS
环境变量中,一切就绪。
OS:debian sid
节点:v0.10.38
我有一个使用身份验证的私人服务请求:
var https = require('https');
var options = {
host: 'private.service.com',
path: '/accounts/' + '123323' + '/orders',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 0,
'Authorization': 'Bearer ' + 'asdsdgcvxcvxcv'
}
};
var request = https.request(options, function (res) {
console.log(res);
});
当我 运行 脚本时,节点抛出此错误:
events.js:72
throw er; // Unhandled 'error' event
^
Error: UNABLE_TO_GET_ISSUER_CERT_LOCALLY
at SecurePair.<anonymous> (tls.js:1381:32)
at SecurePair.emit (events.js:92:17)
at SecurePair.maybeInitFinished (tls.js:980:10)
at CleartextStream.read [as _read] (tls.js:472:13)
at CleartextStream.Readable.read (_stream_readable.js:341:10)
at EncryptedStream.write [as _write] (tls.js:369:25)
at doWrite (_stream_writable.js:226:10)
at writeOrBuffer (_stream_writable.js:216:5)
at EncryptedStream.Writable.write (_stream_writable.js:183:11)
at write (_stream_readable.js:602:24)
同一个脚本几个月来运行良好,我确信身份验证是正确的。今天是第一次遇到这种情况。
导致此错误的原因是什么?
经过一番研究,我发现这是我尝试向其发出 https 请求的服务器的问题。
节点 https 在 private.service 服务器上找不到 ssl ISSUER_CERT,因此抛出该异常。
我使用的解决方案是添加
,因为我确定我可以信任该服务器 rejectUnauthorized: false
https请求的选项,这样节点在证书问题的情况下不会抛出异常。
无论如何,只有当您知道可以信任您的请求的主机时,此解决方案才有效,否则它可能不是最佳解决方案。
SSL 是有原因的。除了其他功能外,它还可以验证您是否真的在与 private.service.com
主机名标识的服务器通信。否则您的客户端软件可能会被中间人攻击欺骗。
首先,当任何人遇到此问题时,他们应该更新系统根 SSL 证书。在 Debian 中,它们包含在 ca-certificates
apt-get 包中。
如果没有帮助,服务器可能使用了颁发者证书,默认情况下全球 PKI 基础设施不信任该证书。在这种情况下,客户端应将证书 public 密钥签名与预共享值进行比较。这被称为 "certificate pinning"。
具体针对您的错误,如果之前有效,则可能是服务器证书已过期。服务器应该更新它。作为临时解决方案,您可以通过 rejectUnauthorized
选项关闭 PKI 验证。但是,您应该将它与固定方法一起使用。在 NodeJS 中,您可以从 res.socket.getPeerCertificate().fingerprint
.
当我尝试在 Ubuntu 16 上安装 npm 时,我遇到了同样的错误。 以下命令对我有用。
npm config set registry http://registry.npmjs.org/
经过研究,问题解决了:
npm set strict-ssl=false
希望对您有所帮助。
来自 this GitHub issue,使用以下环境变量:
export NODE_EXTRA_CA_CERTS=/path/to/certfile.crt
在此之后,您可以 运行 任何 npm
命令,nodejs 将信任您的额外证书文件。
.crt
文件是一个包含前缀行、base64 编码证书和后缀行的文件。
如果您手边没有根 CA 证书,您可以使用 openssl
命令从 URL 生成证书文件:
openssl s_client \
-showcerts \
-servername <host> \
-connect <host>:443 2>/dev/null </dev/null | \
openssl x509
其中 <host>
是 url 的主机名。例如,使用 google.com
作为主机,输出如下所示:
-----BEGIN CERTIFICATE-----
MIIIIDCCBwigAwIBAgIQI/1aCHwDN94QFUhXJeIwODANBgkqhkiG9w0BAQsFADBU
(42 more lines)
E+Hv1bJSbOMSNCDzqRM3JUzvM6Y=
-----END CERTIFICATE-----
将其保存为您的 .crt
文件并将其路径添加到 NODE_EXTRA_CA_CERTS
环境变量中,一切就绪。