web-dev-qa-db-fra.com

Ignorer un certificat SSL auto-signé non valide dans node.js avec https.request?

Je travaille sur une petite application qui se connecte à mon routeur sans fil local (Linksys), mais je rencontre un problème avec le certificat ssl auto-signé du routeur.

J'ai couru wget 192.168.1.1 et j'ai:

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/[email protected]':
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'.

Dans le noeud, l'erreur interceptée est la suivante:

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

Mon exemple de code actuel est:

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

Comment puis-je obtenir que node.js fasse l'équivalent de "--no-check-certificate"?

263
Geuis

Réponse pas chère et peu sûre:

Ajouter

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

dans le code, avant d'appeler https.request()

Une manière plus sécurisée (la solution ci-dessus rend le processus de nœud non sécurisé dans son ensemble) reçoit une réponse dans cette question

531
Juanra

Dans vos options de requête, essayez d’inclure les éléments suivants:

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

Ne croyez pas tous ceux qui essaient de vous induire en erreur.

Dans votre demande, ajoutez simplement:

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

Si vous activez des certificats non autorisés, vous ne serez pas du tout protégé (exposé à MITM pour ne pas valider l'identité), et travailler sans SSL ne fera pas beaucoup de différence. La solution consiste à spécifier le certificat de l'autorité de certification que vous attendez, comme indiqué dans l'extrait suivant. Assurez-vous que le nom commun du certificat est identique à l'adresse que vous avez appelée dans la demande (comme spécifié dans l'hôte):

Ce que vous obtiendrez alors est:

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

Veuillez lire cet article (divulgation: publication sur un blog écrite par l'auteur de cette réponse) afin de comprendre:

  • Comment fonctionnent les certificats de CA
  • Comment générer facilement des certificats CA Certs afin de simuler un environnement de production
53
Hesham Yassin

Ajoutez la variable d'environnement suivante:

NODE_TLS_REJECT_UNAUTHORIZED=0

par exemple. avec export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(avec un grand merci à Juanra)

42
Armand

Ajout à la réponse de @Armand:

Ajoutez la variable d'environnement suivante:

NODE_TLS_REJECT_UNAUTHORIZED = 0 p. Ex. avec exportation:

export NODE_TLS_REJECT_UNAUTHORIZED = 0 (merci à Juanra)

Si vous utilisez Windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Merci à: @ weagle08

12
IamStalker

Vous pouvez également créer une instance de demande avec les options par défaut:

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

Pour meteorJS, vous pouvez définir avec 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);
});
3
digz6666

Ou vous pouvez essayer d’ajouter une résolution de nom local (fichier hosts situé dans le répertoire etc dans la plupart des systèmes d’exploitation, les détails diffèrent), comme par exemple:

192.168.1.1 Linksys 

et ensuite

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

marchera.

1
piaf