在 Windows 上运行 Npm 时如何修复 SSL 证书错误?

当我尝试使用 npm 安装包时,它无法工作。经过长时间的等待,我最终得到一个错误‘ tunneling socket could not be create,sutatusCode = 403’。

$ npm install coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm ERR! Error: tunneling socket could not be established, sutatusCode=403
npm ERR!     at ClientRequest.onConnect (c:\Program Files\nodejs\node_modules\npm\node_modules\request\tunnel.js:148:19)
npm ERR!     at ClientRequest.g (events.js:193:14)
npm ERR!     at ClientRequest.EventEmitter.emit (events.js:123:20)
npm ERR!     at Socket.socketOnData (http.js:1393:11)
npm ERR!     at TCP.onread (net.js:403:27)

然而,当我在我的网页浏览器(谷歌浏览器)中浏览同一个网址时,它载入正常(见脚注)

怎么了?


虽然我碰巧使用了 https 代理,但我确信这不是问题所在。我已经配置了环境变量 https_proxy(根据 npm 用户指南)。我知道环境变量是正确的,因为 Python 包管理器 pip正确地遵循了它。

I believe the problem relates to SSL certificates, because if I download that URL with wget, I get an explicit error about certificates

$ wget https://registry.npmjs.org/coffee-script
SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc
syswgetrc = c:/progra~1/wget/etc/wgetrc
--2012-12-17 12:14:07--  https://registry.npmjs.org/coffee-script
Resolving corpproxy... 10.254.215.35
Connecting to corpproxy|10.254.215.35|:8080... connected.
ERROR: cannot verify registry.npmjs.org's certificate, issued by `/C=US/ST=CA/L=Oakland/O=npm/OU=npm Certificate Authority/CN=npmCA/emailAddress=i@izs.me':
Unable to locally verify the issuer's authority.
To connect to registry.npmjs.org insecurely, use `--no-check-certificate'.
Unable to establish SSL connection.

我要怎么解决这个问题? 不影响安全。


我过去也经常在浏览器中出现 SSL 证书错误,直到我在控制面板的 Internet 选项中将“ npmCA”证书安装为“受信任的根认证机构”(截图 < img src = “ https://i.stack.imgur.com/0H57J.png”alt = “ enter image description here”>)


编辑: 我尝试了每个 https://npmjs.org/doc/config.html#strict-ssl没有安全感工作区

npm set strict-ssl false

然而,它仍然会因为同样的错误而超时

$ npm install coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm ERR! Error: tunneling socket could not be established, sutatusCode=403
356022 次浏览

我用

npm config set proxy http://my-proxy.com:1080
npm config set https-proxy http://my-proxy.com:1080

附加信息在 Node-doc

这个问题已经通过使用 http 版本的存储库为我解决了:

npm config set registry http://registry.npmjs.org/

I was having same issue. After some digging I realized that many post/pre-install scripts would try to install various dependencies and some times specific repositories are used. A better way is to disable certificate check for https module for nodejs that worked for me.

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

从这个问题

TL; DR -只需运行此程序,不要禁用您的安全性:

替换现有的证书

# Windows/MacOS/Linux
npm config set cafile "<path to your certificate file>"


# Check the 'cafile'
npm config get cafile

或扩展现有的证书

设定此环境变量以扩展预先定义的证书: NODE_EXTRA_CA_CERTS呼叫 "<path to certificate file>"

完整的故事

我不得不在 Windows 下的公司防火墙后面处理 npm、 pip、 maven 等等——这并不有趣。我会尽可能保持这个平台的不可知性。

HTTP _ PROXY & HTTPS _ PROXY

HTTP_PROXYHTTPS_PROXY是许多软件使用的环境变量,用来了解代理的位置。在 Windows 下,很多软件也使用你的操作系统指定的代理,这是一个完全不同的东西。这意味着你可以让 Chrome (使用你的 Internet 选项中指定的代理)连接到 URL,但是 npm、 pip、 maven 等都不能工作,因为他们使用 HTTPS _ PROXY (除非他们使用 HTTP _ PROXY ——见后文)。通常情况下,环境变量应该是这样的:

http://proxy.example.com:3128

但你得到的是 403表明你没有通过代理认证。如果这是代理上的基本认证,你需要将环境变量设置为类似于表单的形式:

http://user:pass@proxy.example.com:3128

可怕的 NTLM

有一个 HTTP状态码407(需要代理身份验证) ,更准确地说是代理而不是目标服务器拒绝了你的请求。这段代码困扰了我很长一段时间,直到在谷歌上花了很长时间,我才知道我的代理使用的是 NTLM 身份验证。HTTP 基本身份验证不足以满足我的公司霸主安装的任何代理。我在本地机器上使用 中心(未经身份验证) ,然后让它处理上游代理的 NTLM 身份验证。然后,我不得不告诉所有的程序,不能做 NTLM 使用我的本地机器作为代理-这通常是简单的设置 HTTP_PROXYHTTPS_PROXY。否则,对于 npm 的使用(如@Agus 所建议的) :

npm config set proxy http://proxy.example.com:3128
npm config set https-proxy http://proxy.example.com:3128

“我们需要解密所有 HTTPS 通信,因为病毒”

After this set-up had been humming along (clunkily) for about a year, the corporate overlords decided to change the proxy. Not only that, but it would no longer use NTLM! A brave new world to be sure. But because those writers of malicious software were now delivering malware via HTTPS, the only way they could protect we poor innocent users was to man-in-the-middle every connection to scan for threats before they even reached us. As you can imagine, I was overcome with the feeling of safety.

To cut a long story short, the self-signed certificate needs to be installed into npm to avoid SELF_SIGNED_CERT_IN_CHAIN:

npm config set cafile "<path to certificate file>"

或者,可以将 NODE_EXTRA_CA_CERTS环境变量设置为证书文件。

我想这就是我所知道的关于让 npm 在代理/防火墙后工作的一切。希望有人发现它有用。

编辑 : 通过使用 HTTP 注册表或设置 NODE_TLS_REJECT_UNAUTHORIZED来关闭 HTTPS 是一个非常常见的建议。这些都不是什么好主意,因为你正在向更多的中间人攻击或者重定向攻击敞开心扉。快速欺骗您的 DNS 记录在机器上做软件包安装,您会发现自己信任来自任何地方的软件包。让 HTTPS 工作看起来似乎有很多工作要做,但是强烈推荐使用它。当你是那个允许不可信代码进入公司的人时,你就会明白为什么了。

编辑2 : 请记住,设置 npm config set cafile <path>会导致 npm 只使用该文件中提供的证书,而不是使用它来扩展现有的证书。

如果你想扩展现有的证书(例如公司证书) ,可以使用环境变量 NODE_EXTRA_CA_CERTS链接到文件,这样可以省去很多麻烦。见 如何添加自定义证书权威的 ca-to-nodejs

The problem lies on your proxy. Because the location provider of your install package creates its own certificate and does not buy a verified one from an accepted authority, your proxy does not allow access to the targeted host. 我假设你在使用 Chrome 浏览器时绕过了代理,所以没有检查。

这个问题有一些解决方案,但是所有这些都意味着您信任包提供者。

Possible solutions:

  1. 正如在其他答案中提到的,你可以进行 http://访问 可能会绕过你的代理服务器。这有点危险,因为中间的人可以向你的下载中注入恶意软件。
  2. wget建议您使用标志 --no-check-certificate。这将为您的请求添加一个代理指令。如果代理理解该指令,它就不会检查服务器证书是否由权威机构验证并传递请求。也许有一个 npm 配置与 wget 标志相同。
  3. 您将代理配置为接受 CA npm。我不知道您的代理,所以我不能给您提示。

几天前,我碰巧遇到了类似的 SSL 问题。问题是你的 npm 没有为 https://registry.npmjs.org使用的证书设置根证书。

解决方案:

  1. 使用 wget https://registry.npmjs.org/coffee-script --ca-certificate=./DigiCertHighAssuranceEVRootCA.crt修复 wget 问题
  2. 使用 npm config set cafile /path/to/DigiCertHighAssuranceEVRootCA.crt设置 npm 程序的根证书。

你可在以下网址下载根证书: https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt

注意: 不同的程序可能使用不同的管理根证书的方式,所以不要把浏览器和其他程序混在一起。

分析:

让我们先解决你的 wget https://registry.npmjs.org/coffee-script问题。你的代码片段说:



ERROR: cannot verify registry.npmjs.org's certificate,
issued by /C=US/ST=CA/L=Oakland/O=npm/OU=npm
Certificate Authority/CN=npmCA/emailAddress=i@izs.me:
Unable to locally verify the issuer's authority.


这意味着您的 wget 程序无法验证 https://registry.npmjs.org的证书:

  1. 你的 wget 程序没有这个域的根证书,根证书通常和系统一起发布。
  2. The domain does not pack root certificate into his certificate.

因此,解决方案是显式地为 https://registry.npmjs.org设置根证书。我们可以使用 openssl 来确定下面的原因就是问题所在。

在命令行上尝试 openssl s_client -host registry.npmjs.org -port 443,我们将得到以下消息(前几行) :



CONNECTED(00000003)
depth=1 /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=San Francisco/O=Fastly, Inc./CN=a.sni.fastly.net
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---


This line verify error:num=20:unable to get local issuer certificate makes sure that https://registry.npmjs.org does not pack root certificate. So we Google DigiCert High Assurance EV Root CA root Certificate.

npm config set strict-ssl false

帮我解决了这个问题。 在这种情况下,我的代理和工件存储都位于 Aws 云上的一个私有子网络后面

这是你可以做什么,以避免 npm 和使用纱线的窗口机。

yarn config set "strict-ssl" false

如果你可以控制代理服务器,或者你可以说服你的 IT 管理员,你可以尝试明确地将 registry.npmjs.org 从 SSL 检查中排除。这样应该可以避免代理服务器的用户不必禁用 strong-ssl 检查或安装新的根 CA。

您需要将证书.cer 转换为. pem:

Openssl x509-通知 der-in C: tmp zScaler.cer-out C: tmp zScaler.pem

Npm 配置集文件 C: tmp zScaler.pem