在Windows上运行Npm时如何解决SSL证书错误?


88

当我尝试使用npm安装软件包时,它不起作用。漫长的等待后,我最终收到一条错误消息“无法建立隧道套接字,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)

但是,当我在网络浏览器(Google Chrome)中浏览到相同的URL时,它加载正常(请参阅脚注)。https://registry.npmjs.org/coffee-script

怎么了


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

我认为问题与SSL证书有关,因为如果我使用下载该URL wget,则会收到有关证书的显式错误

$ 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”证书安装为“受信任的根证书颁发机构”


编辑:我尝试了每个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

这与我遇到的问题:stackoverflow.com/questions/11773509/...
nwinkler


输入“ npm set strict-ssl false”解决了一个问题
MrD

Answers:


142

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下,许多软件还使用您的OS指定的代理,这是完全不同的事情。这意味着您可以让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(需要代理身份验证),这是更正确的说法是代理而不是目标服务器拒绝了您的请求。该代码使我困扰了最长的时间,直到在Google上花费了很多时间之后,我才知道我的代理使用了NTLM身份验证。HTTP基本身份验证不足以满足我公司霸主安装的任何代理服务器。我求助于在本地计算机上使用Cntlm(未经身份验证),然后让它使用上游代理处理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通信”

在这个设置(嗡嗡作响)徘徊了大约一年之后,公司霸主决定更换代理。不仅如此,它也将不再使用NTLM!可以肯定的是一个勇敢的新世界。但是,由于那些恶意软件的编写者现在正在通过HTTPS传播恶意软件,因此他们可以保护我们可怜的无辜用户的唯一方法是,在每个连接中间进行中间人扫描,以在威胁到达我们之前进行扫描。可以想像,我被安全感所克服。

长话短说,需要将自签名证书安装到npm中,以避免SELF_SIGNED_CERT_IN_CHAIN

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

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

我想这就是我让npm在代理/防火墙后面工作的全部知识。可能有人觉得它有用。

编辑:这是一个非常普遍的建议,可以通过使用HTTP注册表或设置来关闭此问题的HTTPS NODE_TLS_REJECT_UNAUTHORIZED。这些都不是好主意,因为您要面对进一步的中间人攻击或重定向攻击。在执行软件包安装的计算机上快速欺骗DNS记录,您会发现自己可以从任何地方信任软件包。使HTTPS正常工作似乎很繁琐,但强烈建议使用。当您是负责将不受信任的代码允许进入公司的负责人时,您会明白为什么。

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

如果要使用环境变量来扩展现有证书(例如,使用公司证书)NODE_EXTRA_CA_CERTS以链接到文件,则可以这样做,并且可以节省很多麻烦。查看如何将自定义证书权限添加到nodejs


9
在Windows上,我必须使用正斜杠:npm config set cafile“ C:/dev/Firefox/mycert.cer”
John Jesus

4
**无等号= npm config set cafile "<path to your certificate file>"
Moti Winkler

3
这是一个很棒的回应-我无法更好地总结自己关于代理+ zscalar的头痛
Jpnh

7
笑得很厉害,因为“您可以想象,我被安全感所克服。” :)
Mario B

3
如何获得证书文件?
Aditya '18

36

通过使用版本库的http版本为我解决了此问题:

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

52
那是一个非常糟糕的解决方案!
KiT O 2014年

4
@HaBo我猜他的意思是不安全的。
gabeio 2014年

3
@KiTO,这是一个糟糕的解决方案,同意了。但是,当我只想安装一些软件包时,为什么还要麻烦证书问题?
2015年

17
这个答案是正确的。在某些情况下,当您身处公司代理混乱之中,并拥有自己的证书链时,就没有别的选择(尤其是在禁用证书的情况下)(尤其是当它们没有给您管理员权限时)。这听起来像是npm bug,无法从系统正确加载正确的设置。但是出于交叉兼容性的考虑,他们不会修复npm,所以这是它的结果。有人说这是一个错误的答案,他们不知道自己在说什么。
kenorb

3
@kenorb不正确,您可以追溯代理执行的步骤,并使用cafile将这些自签名证书添加到您的链中。
达多


7

我有同样的问题,我克服了使用

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

附加信息在node-doc


6

几天前,我碰巧遇到了类似的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先解决您的问题。您的片段说:

        错误:无法验证registry.npmjs.org的证书,
        由/ C = US / ST = CA / L = Oakland / O = npm / OU = npm发布 
       认证中心/CN=npmCA/emailAddress=i@izs.me:
       无法在本地验证发行人的权限。

这意味着您的wget程序无法验证https://registry.npmjs.org的证书。有两个原因可能导致此问题:

  1. 您的wget程序没有此域的根证书。根证书通常随系统一起提供。
  2. 域不会将根证书打包到其证书中。

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

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

    已连接(00000003)
    depth = 1 / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert高保证CA-3
    验证错误:num = 20:无法获取本地颁发者证书
    验证返回:0
    ---
    证书链
     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高保证CA-3
     1 s:/ C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert高保证CA-3
       i:/ C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert高保证EV根CA
    ---

此行 verify error:num=20:unable to get local issuer certificate确保https://registry.npmjs.org不打包根证书。因此,我们使用GoogleDigiCert High Assurance EV Root CA根证书。


如果您只能提供文本基础文件(如Jenkins版本),则可以将此证书转换为pem:openssl x509 -inform DER -outform PEM -in DigiCertHighAssuranceEVRootCA.crt -out DigiCertHighAssuranceEVRootCA.pem
Audrius Meskauskas

4

我有同样的问题。经过一番挖掘之后,我意识到许多后/预安装脚本将尝试安装各种依赖项,并且有时会使用特定的存储库。更好的方法是为对我有用的nodejs禁用https模块的证书检查。

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

从这个问题


2
如前所述,这不会解决SSL问题,只能通过它。解决此问题的正确方法是正确配置每个软件包(git,npm,node)以信任正确的签名证书。如果您是一家公司的代理人,那一定是不错的选择。
Aaron C

0

问题出在您的代理上。因为您的安装包的位置提供者会创建自己的证书,并且不会从接受的授权机构购买已验证的证书,所以您的代理不允许访问目标主机。我认为您在使用Chrome浏览器时会绕过代理。因此没有检查。

有一些解决此问题的方法。但是,所有这些都暗示您信任包提供者。

可能的解决方案:

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


0

如果您可以控制代理服务器,或者可以说服IT管理员,则可以尝试将SSL.npmjs.org明确排除在SSL检查之外。这应避免代理服务器的用户不必禁用strict-ssl检查或安装新的根CA。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.