Como corrigir erro de certificado SSL ao executar Npm no Windows?


88

Quando tento instalar um pacote com o npm, ele não funciona. Depois de uma longa espera, eventualmente recebo um erro 'não foi possível estabelecer o soquete de tunelamento, 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)

No entanto, quando eu navego para o mesmo URL no meu navegador (Google Chrome), ele carrega bem (consulte a nota de rodapé). https://registry.npmjs.org/coffee-script

O que há de errado?


Embora eu use um proxy https, tenho certeza de que esse não é o problema. Configurei a variável de ambiente https_proxy(de acordo com o guia do usuário npm ). Eu sei que a variável de ambiente está correta, porque o gerenciador de pacotes Python a pipsegue corretamente.

Acredito que o problema esteja relacionado aos certificados SSL, porque se eu baixar esse URL com wget, recebo um erro explícito sobre certificados

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

Como posso consertar isso? Sem comprometer a segurança.


Eu costumava obter erros de certificado SSL em meu navegador da web também, até instalar o certificado 'npmCA' como uma 'autoridade de certificação raiz confiável' nas Opções de Internet do Painel de controle (captura de tela insira a descrição da imagem aqui)


Editar: tentei uma solução alternativa insegura por https://npmjs.org/doc/config.html#strict-ssl

npm set strict-ssl false

No entanto, ainda atinge o tempo limite com o mesmo erro

$ 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

Isso é semelhante ao problema que estou tendo: stackoverflow.com/questions/11773509/…
nwinkler


Inserir "npm set strict-ssl false" resolveu um problema
MrD

Respostas:


142

TL; DR - Basta executar e não desabilitar sua segurança:

Substituir certificados existentes

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

# Check the 'cafile'
npm config get cafile

ou estender certificados existentes

Defina esta variável de ambiente para estender certificados predefinidos: NODE_EXTRA_CA_CERTSpara"<path to certificate file>"

História completa

Tive que trabalhar com npm, pip, maven etc. atrás de um firewall corporativo no Windows - não é divertido. Tentarei manter esta plataforma agnóstica / ciente sempre que possível.

HTTP_PROXY e HTTPS_PROXY

HTTP_PROXY& HTTPS_PROXYsão variáveis ​​de ambiente usadas por muitos softwares para saber onde está o seu proxy. No Windows, muitos softwares também usam o proxy especificado do sistema operacional, o que é uma coisa totalmente diferente. Isso significa que você pode fazer com que o Chrome (que usa o proxy especificado nas Opções da Internet) se conecte à URL perfeitamente, mas npm, pip, maven etc. não funcionam porque usam HTTPS_PROXY (exceto quando usam HTTP_PROXY - veja mais tarde). Normalmente, a variável de ambiente seria semelhante a:

http://proxy.example.com:3128

Mas você está recebendo um 403 que sugere que você não está sendo autenticado no seu proxy. Se for uma autenticação básica no proxy, você desejará definir a variável de ambiente para algo no formato:

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

O temido NTLM

Há um código de status HTTP 407 (autenticação de proxy necessária), que é a maneira mais correta de dizer que é o proxy, e não o servidor de destino, que está rejeitando sua solicitação. Esse código me atormentou por muito tempo, até que depois de muito tempo no Google, descobri que meu proxy usava autenticação NTLM . A autenticação HTTP básica não era suficiente para satisfazer qualquer proxy que meus overlords corporativos tivessem instalado. Recorri ao uso do Cntlm em minha máquina local (não autenticado) e, em seguida, fiz com que ele tratasse da autenticação NTLM com o proxy upstream. Então eu tive que dizer a todos os programas que não podiam fazer NTLM para usar minha máquina local como o proxy - que geralmente é tão simples quanto configurar HTTP_PROXYe HTTPS_PROXY. Caso contrário, para uso npm (como @Agus sugere):

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

"Precisamos descriptografar todo o tráfego HTTPS por causa dos vírus"

Depois que essa configuração começou a funcionar (desajeitadamente) por cerca de um ano, os senhores supremos corporativos decidiram mudar o proxy. Não só isso, mas não usaria mais NTLM! Um admirável mundo novo com certeza. Mas, como os criadores de softwares mal-intencionados agora distribuíam malware via HTTPS, a única maneira de proteger os pobres usuários inocentes era interceptar todas as conexões para verificar se há ameaças antes mesmo que elas chegassem até nós. Como você pode imaginar, fui dominado pela sensação de segurança.

Para encurtar a história, o certificado autoassinado precisa ser instalado no npm para evitar SELF_SIGNED_CERT_IN_CHAIN:

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

Como alternativa, a NODE_EXTRA_CA_CERTSvariável de ambiente pode ser definida para o arquivo de certificado.

Acho que é tudo que sei sobre como fazer o npm funcionar por trás de um proxy / firewall. Que alguém ache útil.

Editar : é uma sugestão muito comum para desligar o HTTPS para este problema usando um registro ou configuração HTTP NODE_TLS_REJECT_UNAUTHORIZED. Essas não são boas ideias porque você está se abrindo para mais ataques man-in-the-middle ou de redirecionamento. Uma rápida falsificação de seus registros DNS na máquina que está fazendo a instalação do pacote e você vai confiar em pacotes de qualquer lugar. Pode parecer muito trabalhoso fazer o HTTPS funcionar, mas é altamente recomendado. Quando você é o único responsável por permitir a entrada de código não confiável na empresa, entenderá por quê.

Edição 2 : tenha em mente que a configuração npm config set cafile <path>faz com que o npm use apenas os certificados fornecidos naquele arquivo, em vez de estender os existentes com ele.

Se você deseja estender os certificados existentes (por exemplo, com um certificado de empresa), usar a variável de ambiente NODE_EXTRA_CA_CERTSpara vincular ao arquivo é o caminho a percorrer e pode lhe poupar muito trabalho. Veja how-to-add-custom-certificate-authority-ca-to-nodejs


9
No Windows, tive que usar barras: npm config set cafile "C: /dev/Firefox/mycert.cer"
John Jesus

4
** Sem sinal de igual= npm config set cafile "<path to your certificate file>"
Moti Winkler

3
Esta é uma resposta incrível - eu não poderia resumir melhor minhas próprias dores de cabeça sobre proxy + zscalar
Jpnh

7
riu tanto por causa de "Como você pode imaginar, fui dominado pela sensação de segurança." :)
Mario B de

3
Como obtenho o arquivo do certificado?
Aditya

36

Este problema foi corrigido para mim usando a versão http do repositório:

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

52
Essa é uma solução muito ruim!
KiT O

4
@HaBo Acho que ele quis dizer que isso não é seguro.
gabeio

3
@KiTO É uma solução ruim, concordou. Mas por que devo mexer com os problemas de certificado quando apenas quero instalar alguns pacotes?
Ich

17
Essa resposta está correta. Há alguns casos em que você está por trás de uma bagunça de proxy corporativo com sua própria cadeia de certificados em cima de outras e não há outra maneira (além de desabilitar certificados) do que esta (especialmente quando eles não estão lhe concedendo direitos de administrador). Isso soa como um bug do npm, que não carrega corretamente as configurações adequadas do sistema. Mas por uma questão de compatibilidade cruzada, eles não corrigirão o npm, então este é o resultado disso. Pessoas que dizem que é uma resposta ruim, não têm ideia do que estão falando.
kenorb

3
@kenorb está incorreto, você pode refazer os passos que seu proxy executa e adicionar esses certificados autoassinados à sua rede com cafile.
dardo

15
npm config set strict-ssl false

resolveu o problema para mim. Neste caso, meu agente e o depósito de artefatos estão atrás de uma sub-rede privada na nuvem aws


7

Estou tendo o mesmo problema, superei usando

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

Além disso, informações em node-doc


6

Aconteceu de eu encontrar esse problema de SSL semelhante há alguns dias. O problema é que seu npm não define o certificado raiz para o certificado usado por https://registry.npmjs.org .

Soluções:

  1. Use wget https://registry.npmjs.org/coffee-script --ca-certificate=./DigiCertHighAssuranceEVRootCA.crtpara consertar o problema wget
  2. Use npm config set cafile /path/to/DigiCertHighAssuranceEVRootCA.crtpara definir o certificado raiz para seu programa npm.

você pode baixar o certificado raiz em: https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt

Aviso: programas diferentes podem usar maneiras diferentes de gerenciar o certificado raiz, portanto, não misture navegadores com outros.

Análise:

vamos resolver seu wget https://registry.npmjs.org/coffee-scriptproblema primeiro. seu snippet diz:

        ERRO: não é possível verificar o certificado de registry.npmjs.org,
        emitido por / C = US / ST = CA / L = Oakland / O = npm / OU = npm 
       Autoridade de certificação/CN=npmCA/emailAddress=i@izs.me:
       Não foi possível verificar localmente a autoridade do emissor.

Isso significa que seu programa wget não pode verificar https://registry.npmjs.orgo certificado de. Existem dois motivos que podem causar este problema:

  1. Seu programa wget não possui o certificado raiz deste domínio. O certificado raiz geralmente é fornecido com o sistema.
  2. O domínio não inclui o certificado raiz em seu certificado.

Portanto, a solução é definir explicitamente o certificado raiz para https://registry.npmjs.org. Podemos usar o openssl para ter certeza de que o motivo abaixo é o problema.

Experimente openssl s_client -host registry.npmjs.org -port 443a linha de comando e obteremos esta mensagem (primeiras linhas):

    CONECTADO (00000003)
    profundidade = 1 / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert High Assurance CA-3
    verificar erro: num = 20: não foi possível obter o certificado do emissor local
    verificar retorno: 0
    ---
    Cadeia de certificados
     0 s: / C = US / ST = Califórnia / 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
    ---

Esta linha verify error:num=20:unable to get local issuer certificategarante que https://registry.npmjs.orgnão empacota o certificado raiz. Então, nós DigiCert High Assurance EV Root CAcertificamos o Google root.


Se você puder fornecer apenas o arquivo de base de texto (como para compilações do Jenkins), este certificado pode ser convertido em pem: openssl x509 -inform DER -outform PEM -in DigiCertHighAssuranceEVRootCA.crt -out DigiCertHighAssuranceEVRootCA.pem
Audrius Meskauskas de

4

Eu estava tendo o mesmo problema. Após algumas pesquisas, percebi que muitos scripts de pós / pré-instalação tentariam instalar várias dependências e, algumas vezes, repositórios específicos são usados. A melhor maneira é desabilitar a verificação de certificado do módulo https para nodejs que funcionou para mim.

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

Desta questão


2
Como já mencionado, isso não resolverá o problema do SSL, apenas o contornará. A maneira adequada de resolver isso é configurar adequadamente cada pacote (git, npm, node) para confiar no certificado de assinatura adequado. Se você estiver atrás de uma procuração corporativa, claro.
Aaron C

0

O problema está no seu proxy. Como o provedor de localização do pacote de instalação cria seu próprio certificado e não compra um certificado verificado de uma autoridade aceita, seu proxy não permite acesso ao host de destino. Presumo que você ignore o proxy ao usar o navegador Chrome. Portanto, não há verificação.

Existem algumas soluções para este problema. Mas tudo indica que você confia no provedor do pacote.

Soluções possíveis:

  1. Conforme mencionado em outras respostas, você pode fazer um http:// acesso que pode contornar o seu proxy. Isso é um pouco perigoso, porque o homem no meio pode injetar malware em seus downloads.
  2. O wgetsugere que você use uma bandeira --no-check-certificate. Isso adicionará uma diretiva de proxy ao seu pedido. O proxy, se entender a diretiva, não verifica se o certificado do servidor é verificado por uma autoridade e passa a solicitação. Talvez haja uma configuração com npm que faz o mesmo que o sinalizador wget.
  3. Você configura seu proxy para aceitar CA npm. Não conheço seu proxy, então não posso dar uma dica.


0

Se você tiver controle sobre o servidor proxy ou puder convencer seus administradores de TI, poderá tentar excluir explicitamente o registry.npmjs.org da inspeção SSL. Isso deve evitar que os usuários do servidor proxy tenham que desativar a verificação estrita-ssl ou instalar uma nova CA raiz.


-1

Isso é o que você pode fazer para evitar npm e usar fios em máquinas de janelas.

yarn config set "strict-ssl" false
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.