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

当我尝试用npm安装包时,它不起作用。 经过漫长的等待,我最终得到一个错误'隧道套接字无法build立,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) 

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

怎么了?


当我碰巧使用https代理时,我相信这不是问题。 我已经configuration了环境variableshttps_proxy (按照npm 用户指南 )。 我知道环境variables是正确的,因为Python包pipe理器pip正确地遵循它。

我相信这个问题涉及SSL证书,因为如果我用wget下载这个URL,我会得到一个关于证书的明确错误

 $ 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. 

我怎样才能解决这个问题? 不妥协的安全。


我以前也在我的networking浏览器中得到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 

TL; DR – 运行这个,不要禁用你的安全性:

 #For Windows npm config set cafile = "<path to your certificate file>" #For MacOS/Linux npm config set cafile "<path to your certificate file>" #Check the 'cafile' npm config get cafile 

全文

我不得不在Windows下的公司防火墙后面使用npm,pip,maven等 – 这并不好玩。 我会尽可能保持这个平台不可知论/意识到。

HTTP_PROXY&HTTPS_PROXY

HTTP_PROXYHTTPS_PROXY是许多软件使用的环境variables来知道你的代理在哪里。 在Windows下,许多软件也使用你的操作系统指定的代理,这是完全不同的东西。 这意味着你可以让Chrome(使用Internet选项中指定的代理)连接到URL,但是npm,pip,maven等不能正常工作,因为它们使用HTTPS_PROXY(除非它们使用HTTP_PROXY – 请参阅后面的内容)。 通常环境variables看起来像这样:

 http://proxy.example.com:3128 

但是你得到了一个403 ,这表明你没有对你的代理进行validation。 如果是代理上的基本身份validation,则需要将环境variables设置为以下格式:

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

可怕的NTLM

有一个HTTP状态代码407(需要代理身份validation),这是更正确的方式说它是代理,而不是拒绝您的请求的目标服务器。 该代码困扰了我最长的时间,直到在谷歌的很多时间后,我学会了我的代理使用NTLM身份validation 。 HTTP基本身份validation不足以满足我的公司霸主所安装的任何代理。 我诉诸在我的本地机器上使用Cntlm (未经身份validation),然后让它处理与上游代理的NTLM身份validation。 然后,我必须告诉所有不能执行NTLM的程序使用本地机器作为代理 – 这通常与设置HTTP_PROXYHTTPS_PROXY一样简单。 否则,对于NPM使用(如@Agusbuild议):

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

“我们需要解密所有的HTTPSstream量,因为病毒”

在这个设置完成之后,大约一年的时间,公司霸主决定更换代理。 不仅如此,它将不再使用NTLM! 确定一个勇敢的新世界。 但是由于那些恶意软件的作者现在正在通过HTTPS提供恶意软件,所以他们可以保护我们可怜的无辜用户的唯一方法就是在每个连接上扫描威胁,然后到达我们的中间。 正如你所想象的那样,我被安全的感觉所克服了。

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

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

我认为这就是让我知道让npm在代理/防火墙后工作的一切。 可能有人觉得有用。

编辑 :这是一个非常常见的build议,通过使用HTTPregistry或设置NODE_TLS_REJECT_UNAUTHORIZEDclosures此问题的HTTPS。 这些不是好主意,因为你打开自己的中间人或redirect攻击。 在执行软件包安装的计算机上快速欺骗DNSlogging,您会发现自己从任何地方信任软件包。 使HTTPS工作看起来像很多工作,但强烈build议。 当你负责将不可信的代码放入公司时,你就会明白为什么。

使用http版本库解决了这个问题:

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

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

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

另外在节点文档信息

我几天前遇到了类似的SSL问题。 问题是您的npm不会为https://registry.npmjs.org使用的证书设置根证书。;

解决scheme:

  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下载根证书: https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crthttps://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt

注意:不同的程序可能会使用不同的方式来pipe理根证书,所以不要混合使用浏览器。

分析:

首先解决你的wget https://registry.npmjs.org/coffee-script问题。 你的片段说:


        错误:无法validationregistry.npmjs.org的证书,
        由/ C = US / ST = CA / L =奥克兰/ O = npm / OU = npm发行 
       证书颁发机构/CN=npmCA/emailAddress=i@izs.me:
       无法在本地validation发行人的权限。

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

  1. 你的wget程序没有这个域的根证书。 根证书通常随系统提供。
  2. 域名不会将根证书打包到他的证书中。

所以解决办法是明确设置https://registry.npmjs.org根证书。 我们可以使用openssl来确定原因是什么问题。

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


    连(00000003)
    深度= 1 / C = US / O = DigiCert公司/ OU = www.digicert.com / CN = DigiCert高保证CA-3
    validation错误:num = 20:无法获取本地颁发者证书
    validation返回:0
     ---
    证书链
      0 s:/ C = US / ST = California / L =旧金山/ 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不打包根证书。 所以我们Google DigiCert High Assurance EV Root CA证书。

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

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

从这个问题

问题在于你的代理。 由于安装包的位置提供程序会创build自己的证书,并且不会从已接受的授权机构购买经过validation的证书,因此您的代理不允许访问目标主机。 我假设您在使用Chrome浏览器时绕过代理。 所以没有检查。

这个问题有一些解决scheme。 但都意味着你相信包提供商。

可能的解决scheme:

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