Ignorare il certificato SSL autofirmato non valido in node.js con https.request?


309

Sto lavorando a una piccola app che accede al mio router wireless locale (Linksys) ma sto riscontrando un problema con il certificato ssl autofirmato del router.

Ho eseguito wget 192.168.1.1 e ho ottenuto:

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

Nel nodo, l'errore rilevato è:

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

Il mio attuale codice di esempio è:

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);
});

Come posso fare per ottenere node.js per fare l'equivalente di "--no-check-certificate"?

Risposte:


601

Risposta economica e insicura:

Inserisci

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

nel codice, prima di chiamare https.request()

Un modo più sicuro (la soluzione sopra rende insicuro l'intero processo del nodo) viene data risposta a questa domanda


2
Ha funzionato benissimo per me! Ho inserito questo codice subito dopo aver incluso tutto nella parte superiore della mia applicazione principale js.
Xedecimal,

Questo ha funzionato anche per la combinazione NodeJS e SailJS. L'ho aggiunto all'inizio di local.js
Michael Kork.

38
Non utilizzare questo o "rejectUnauthorized" in un ambiente di produzione, in quanto ciò disabilita tutti i tipi di controlli di sicurezza.
Jason Walton,

3
Ho avuto problemi con l'esecuzione dei test usando mocha sul mio server https autofirmato e aggiungendo questo immediatamente prima che qualsiasi blocco descrittivo facesse passare i miei test.
artis3n,

Questo probabilmente non è il modo più sicuro per risolvere il problema. Vedi stackoverflow.com/questions/20433287/…
Matt Pennington il

166

Nelle opzioni di richiesta, prova a includere quanto segue:

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

Ha funzionato per me. Uso restler e vedo che non ha inoltrato le opzioni di default, quindi ho dovuto patcharlo.
Olivier Amblet,

2
Perché ciò funzioni è necessario fornire un'istanza esplicita di un agente personalizzato. Crea l'oggetto opzioni e imposta l'agente: 'options.agent = new https.Agent (opzioni);' Quindi chiama "https.request (opzioni)"
Max

14
Bene, questo ha funzionato per me solo con l' rejectUnauthorizedopzione e nient'altro
mcont

@mcont confermo che rejectUnauthorizedera abbastanza buono tutto il resto ootb. Utilizzo all'interno dell'estensione del codice vs. Meglio ancora consentire la configurazione PEM, lo farò il prossimo ...
escape-llc

61

Non credere a tutti coloro che cercano di ingannarti.

Nella tua richiesta, basta aggiungere:

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

Se attivi certificati non autorizzati, non sarai affatto protetto (esposto a MITM per non convalidare l'identità) e lavorare senza SSL non farà una grande differenza. La soluzione è specificare il certificato CA previsto, come mostrato nel frammento successivo. Assicurarsi che il nome comune del certificato sia identico all'indirizzo chiamato nella richiesta (come specificato nell'host):

Quello che otterrai allora è:

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
    },

Si prega di leggere questo articolo (divulgazione: post sul blog scritto dall'autore di questa risposta) qui per capire:

  • Come funzionano i certificati CA.
  • Come generare CA Certs per i test facilmente al fine di simulare l'ambiente di produzione

7
Funziona ed è il modo giusto di risolvere il problema "Errore: certificato autofirmato nella catena di certificati".
RohanRasane,

1
perché metti fs.readFileSync tra parentesi, invece di memorizzarlo come stringa?
Lelo,

Lelo: le parentesi lo trasformano in un array. ca: prevede una serie di certificati. Questo file dovrebbe essere un elenco separato da virgole di certificati, spesso le persone usano una funzione interna per trasformare un file PEM in un array. Per un cet autofirmato un singolo certificato "dovrebbe" funzionare.
John David

53

Aggiungi la seguente variabile d'ambiente:

NODE_TLS_REJECT_UNAUTHORIZED=0

ad es. con export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(con grande grazie a Juanra)


Questo ha funzionato per me quando ho cercato di correrewebdriver-manager update
Ashley,

3
set NODE_TLS_REJECT_UNAUTHORIZED = 0 per windows
Felipe SS

Questa è stata un'ottima soluzione per il mio ambiente di sviluppo
David

14

Aggiungendo alla risposta @Armand:

Aggiungi la seguente variabile d'ambiente:

NODE_TLS_REJECT_UNAUTHORIZED = 0 ad es. Con esportazione:

export NODE_TLS_REJECT_UNAUTHORIZED = 0 (con grande ringraziamento a Juanra)

Se utilizzi Windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Grazie a: @ weagle08


12

Puoi anche creare un'istanza di richiesta con le opzioni predefinite:

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

3

Per meteorJS è possibile impostare con 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

Oppure puoi provare ad aggiungere nella risoluzione del nome locale ( hostsfile trovato nella directory etcnella maggior parte dei sistemi operativi, i dettagli differiscono) qualcosa del genere:

192.168.1.1 Linksys 

e poi

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

funzionerà.


3
vero che questo potrebbe rispondere alla domanda ma penso che il prossimo errore sarà DEPTH_ZERO_SELF_SIGNED_CERT in questo caso.
Olivier Amblet il

1
quindi come si può aggirare DEPTH_ZERO_SELF_SIGNED_CERT? Ci sto incontrando ora.
Reza,

3
@reza: aggiungi questo alle tue opzioni:rejectUnauthorized: false
Obay

1
So che questo è un po 'vecchio ma per riferimento futuro (per farlo nel modo corretto), è necessario ottenere una codifica PEM del certificato autofirmato e includerlo nelle opzioni come CA (apparentemente è anche necessario per impostare il valore dell'agente ma può essere falso). Poiché il certificato è autofirmato, funge da propria CA e pertanto può essere utilizzato per verificarsi. Tuttavia, vorrei anche chiedermi se varrebbe la pena farlo su un router poiché il firmware potrebbe essere scaricato e quindi la chiave privata potrebbe essere facilmente compromessa.
Jonathan Gray,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.