108

当我尝试使用 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)

但是,当我在我的网络浏览器(谷歌浏览器)中浏览到相同的 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
4

10 回答 10

188

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、ma​​ven 等——这并不好玩。我会尽可能地保持这个平台不可知/感知。

HTTP_PROXY & HTTPS_PROXY

HTTP_PROXY&HTTPS_PROXY是许多软件用来知道你的代理在哪里的环境变量。在 Windows 下,许多软件还使用您的操作系统指定的代理,这是完全不同的事情。这意味着您可以让 Chrome(它使用 Internet 选项中指定的代理)很好地连接到 URL,但 npm、pip、ma​​ven 等由于使用 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链接到文件是可行的方法,并且可以为您节省很多麻烦。请参阅如何添加自定义证书授权 ca-to-nodejs

于 2015-05-20T05:58:43.877 回答
34

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

npm config set registry http://registry.npmjs.org/
于 2013-11-30T20:47:40.363 回答
22
npm config set strict-ssl false

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

于 2019-02-05T15:45:15.710 回答
8

几天前我碰巧遇到了类似的 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 High Assurance CA-3
    验证错误:num=20:无法获取本地颁发者证书
    验证返回:0
    ---
    证书链
     0 秒:/C=US/ST=加利福尼亚/L=旧金山/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
    ---

此行 verify error:num=20:unable to get local issuer certificate确保https://registry.npmjs.org不打包根证书。所以我们谷歌DigiCert High Assurance EV Root CA根证书。

于 2015-05-20T12:12:37.060 回答
7

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

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

node-doc上的附加信息

于 2013-05-13T17:13:26.737 回答
5

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

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

从这个问题

于 2015-02-18T14:52:02.140 回答
0

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

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

可能的解决方案:

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

您需要将证书 .cer 转换为 .pem。对于在 CMD 中运行:

openssl x509 -inform der -in C:\tmp\zScaler.cer -out C:\tmp\zScaler.pem

npm 配置设置 cafile C:\tmp\zScaler.pem

于 2021-12-29T22:53:30.353 回答
-1

这是您可以避免 npm 并在窗口机器中使用纱线的方法。

yarn config set "strict-ssl" false
于 2020-08-27T08:34:15.837 回答
-1

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

于 2020-09-28T07:09:11.567 回答