Ignore o certificado SSL autoassinado inválido no node.js com https.request?


309

Estou trabalhando em um pequeno aplicativo que efetua login no meu roteador local sem fio (Linksys), mas estou com um problema com o certificado SSL autoassinado do roteador.

Executei o wget 192.168.1.1 e obtive:

ERROR: cannot verify 192.168.1.1's certificate, issued by `/C=US/ST=California/L=Irvine/O=Cisco-Linksys, LLC/OU=Division/CN=Linksys/emailAddress=support@linksys.com':
Self-signed certificate encountered.
ERROR: certificate common name `Linksys' doesn't match requested host name `192.168.1.1'.
To connect to 192.168.1.1 insecurely, use `--no-check-certificate'.

No nó, o erro que está sendo capturado é:

{ [Error: socket hang up] code: 'ECONNRESET' }

Meu código de amostra atual é:

var req = https.request({ 
    host: '192.168.1.1', 
    port: 443,
    path: '/',
    method: 'GET'

}, function(res){

    var body = [];
    res.on('data', function(data){
        body.push(data);
    });

    res.on('end', function(){
        console.log( body.join('') );
    });

});
req.end();

req.on('error', function(err){
    console.log(err);
});

Como posso obter o node.js para fazer o equivalente a "--no-check-certificate"?

Respostas:


601

Resposta barata e insegura:

Adicionar

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

no código, antes de chamar https.request()

Uma maneira mais segura (a solução acima torna todo o processo do nó inseguro) é respondida nesta pergunta


2
Caiu como uma luva para mim! Coloquei esse código logo após incluir tudo na parte superior do meu aplicativo principal js.
Xedecimal

Isso também funcionou para o combo NodeJS e SailJS. Eu o adicionei no topo do local.js
Michael Kork.

38
Não use isso ou "rejectUnauthorized" em um ambiente de produção, pois isso desativa todos os tipos de verificações de segurança.
Jason Walton

3
Eu estava tendo problemas com a execução de testes usando o mocha no meu servidor de nó https autoassinado e adicionando isso imediatamente antes que qualquer bloco de descrição fizesse meus testes passarem.
Artis3n 30/07/2015

Provavelmente, essa não é a maneira mais segura de corrigir o problema. Veja stackoverflow.com/questions/20433287/…
Matt Pennington

166

Nas opções de solicitação, tente incluir o seguinte:

   var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false,
      requestCert: true,
      agent: false
    },

Trabalhou para mim. Eu uso o restler e vejo que ele não encaminhava as opções por padrão, então tive que corrigi-lo.
Olivier Amblet

2
Para que isso funcione, é necessário fornecer uma instância explícita de um agente personalizado. Crie o objeto options e defina o agente: 'options.agent = new https.Agent (options);' Em seguida, basta chamar 'https.request (options)'
Máx

14
Bem, isso funcionou para mim apenas com a rejectUnauthorizedopção e mais nada
mcont:

@ Mccon confirmo apenas rejectUnauthorizedera bom o suficiente tudo ootb. Usando a extensão de código vs. Melhor ainda permitir a configuração do PEM, farei isso a seguir ...
escape-llc

61

Não acredite em todos aqueles que tentam enganar você.

Em sua solicitação, basta adicionar:

ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})]

Se você ativar certificados não autorizados, não estará totalmente protegido (exposto ao MITM por não validar a identidade) e trabalhar sem SSL não fará grande diferença. A solução é especificar o certificado de CA que você espera, conforme mostrado no próximo snippet. Verifique se o nome comum do certificado é idêntico ao endereço que você chamou na solicitação (conforme especificado no host):

O que você receberá então é:

var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})],
      method: 'GET',
      rejectUnauthorized: true,
      requestCert: true,
      agent: false
    },

Leia este artigo (divulgação: postagem do blog escrita pelo autor desta resposta) aqui para entender:

  • Como os certificados da CA funcionam
  • Como gerar o CA Certs para teste facilmente, a fim de simular o ambiente de produção

7
Isso funciona e é a maneira correta de corrigir o problema "Erro: certificado autoassinado na cadeia de certificados".
RohanRasane 02/02

1
por que você coloca fs.readFileSync entre colchetes, em vez de armazená-lo como uma string?
Lelo

Lelo: colchetes transformá-lo em uma matriz. ca: espera uma variedade de certs. Esse arquivo deve ser uma lista separada por vírgula de certs, geralmente as pessoas usam uma função interna para transformar um arquivo PEM em uma matriz. Para um cet autoassinado, um único certificado "deve" funcionar.
JohnDavid 14/02

53

Adicione a seguinte variável de ambiente:

NODE_TLS_REJECT_UNAUTHORIZED=0

por exemplo, com export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(com grandes agradecimentos a Juanra)


Isso funcionou para mim ao tentar executarwebdriver-manager update
Ashley

3
configure NODE_TLS_REJECT_UNAUTHORIZED = 0 para windows
Felipe SS

Esta foi uma ótima solução para o meu ambiente de desenvolvimento #
David David

14

Adicionando à resposta do @Armand:

Adicione a seguinte variável de ambiente:

NODE_TLS_REJECT_UNAUTHORIZED = 0, por exemplo, com exportação:

exportar NODE_TLS_REJECT_UNAUTHORIZED = 0 (com muito obrigado a Juanra)

Se você usa o Windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Obrigado a: @ weagle08


12

Você também pode criar uma instância de solicitação com opções padrão:

require('request').defaults({ rejectUnauthorized: false })

3

Para meteorJS, você pode definir com npmRequestOptions.

HTTP.post(url, {
    npmRequestOptions: {
        rejectUnauthorized: false // TODO remove when deploy
    },
    timeout: 30000, // 30s
    data: xml
}, function(error, result) {
    console.log('error: ' + error);
    console.log('resultXml: ' + result);
});

1

Ou você pode tentar adicionar a resolução de nome local ( hostsarquivo encontrado no diretório etcna maioria dos sistemas operacionais, os detalhes diferem) algo como isto:

192.168.1.1 Linksys 

e a seguir

var req = https.request({ 
    host: 'Linksys', 
    port: 443,
    path: '/',
    method: 'GET'
...

vai funcionar.


3
verdade que isso pode responder à pergunta, mas acho que o próximo erro será DEPTH_ZERO_SELF_SIGNED_CERT nesse caso.
Olivier Amblet

1
Então, como se pode contornar DEPTH_ZERO_SELF_SIGNED_CERT? Estou encontrando isso agora.
Reza

3
@reza: adicione isso às suas opções:rejectUnauthorized: false
Obay

1
Eu sei que isso é um pouco antigo, mas para referência futura (para fazer isso da maneira correta), você precisa obter uma codificação PEM do certificado autoassinado e incluí-lo nas opções como uma CA (você aparentemente também precisa para definir o valor do agente, mas isso pode ser falso). Como o certificado é autoassinado, ele atua como sua própria CA e, portanto, pode ser usado para verificar a si próprio. No entanto, eu também questionaria se realmente valeria a pena fazer em um roteador, pois o firmware provavelmente poderia ser baixado e, portanto, a chave privada poderia ser facilmente comprometida.
Jonathan Grey
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.