Ігнорувати недійсний самопідписаний сертифікат ssl в node.js за допомогою https.request?


308

Я працюю над невеликим додатком, який входить у мій локальний бездротовий маршрутизатор (Linksys), але у мене виникають проблеми з самопідписаним сертифікатом ssl маршрутизатора.

Я запустив wget 192.168.1.1 і отримав:

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

У вузлі помилка, що потрапляє, це:

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

Мій поточний зразок коду:

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

Як я можу зробити так, щоб node.js зробити еквівалент "--no-check-сертифікат"?

Відповіді:


599

Недорога і небезпечна відповідь:

Додайте

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

в коді, перш ніж дзвонити https.request()

У цьому запитанні відповідає більш безпечний спосіб (рішення вище робить увесь процес вузла небезпечним)


2
Працювало як шарм для мене! Я розмістив цей код одразу після того, як я включив усе до самого верху мого основного js програми.
Xedecimal

Це також працювало для комбінації NodeJS & SailJS. Я додав його у верхній частині local.js
Майкл Корк.

38
Не використовуйте це і не «відхиляйте несанкціоновану» у виробничих умовах, оскільки це відключає всі види перевірок безпеки.
Джейсон Уолтон

3
У мене виникли проблеми із запуском тестів, використовуючи мокку на моєму самопідписаному сервері https вузла, і додаю це безпосередньо перед тим, як будь-які блоки опису змусили мої тести пройти.
artis3n

Це, мабуть, не найбезпечніший спосіб усунення проблеми. Дивіться stackoverflow.com/questions/20433287/…
Метт Пеннінгтон

166

У налаштуваннях запиту спробуйте включити наступне:

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

Працювали для мене. Я використовую restler, і я бачу, що він не пересилав параметри за замовчуванням, тому мені довелося виправити його.
Олів'є Амблет

2
Для цього вам потрібно надати явний екземпляр спеціального агента. Створіть об’єкт параметрів та встановіть агент: 'options.agent = new https.Agent (options);' Тоді просто зателефонуйте "https.request (варіанти)"
Макс

14
Ну, це працювало для мене лише з rejectUnauthorizedможливістю і нічого іншого
mcont

@mcont я підтверджую, просто rejectUnauthorizedбуло досить добре все інше ootb. Використання в межах розширення коду проти. Ще краще дозволити конфігурацію PEM, я зроблю це наступним ...
escape-llc

61

Не вірте всім, хто намагається вас ввести в оману.

У своєму запиті просто додайте:

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

Якщо ви ввімкнете несанкціоновані сертифікати, ви взагалі не будете захищені (піддані дії MITM за не підтвердження ідентичності), і робота без SSL не буде великою різницею. Рішення полягає в тому, щоб вказати сертифікат CA, який ви очікуєте, як показано в наступному фрагменті. Переконайтесь, що загальна назва сертифіката ідентична адресі, яку ви зателефонували у запиті (Як зазначено у хості):

Що ви отримаєте тоді:

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

Будь ласка, прочитайте цю статтю (розкриття: повідомлення в блозі, написане автором цієї відповіді) тут, щоб зрозуміти:

  • Як працюють сертифікати CA
  • Як генерувати сертифікати CA для тестування легко, щоб імітувати виробниче середовище

7
Це працює і є правильним способом виправлення проблеми "Помилка: самопідписаний сертифікат у ланцюжку сертифікатів."
RohanRasane

1
чому ви ставите fs.readFileSync всередині дужок, а не зберігати їх як рядок?
Lelo

Лело: дужки перетворюють його на масив. ca: очікує масив certs. Цей файл повинен бути розділеним комою списком цертів, часто люди використовують внутрішню функцію, щоб перетворити файл PEM у масив. Для cet, що підписався власноруч, один серт "повинен" працювати.
JohnDavid

53

Додайте таку змінну середовища:

NODE_TLS_REJECT_UNAUTHORIZED=0

наприклад з export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(з великою подякою Хуанрі)


Це працювало для мене при спробі бігуwebdriver-manager update
Ешлі

3
встановити NODE_TLS_REJECT_UNAUTHORIZED = 0 для windows
Felipe SS

Це було чудовим рішенням для мого середовища для розробників
Девід

14

Додавання до відповіді @Armand:

Додайте таку змінну середовища:

NODE_TLS_REJECT_UNAUTHORIZED = 0, наприклад, з експортом:

експортувати NODE_TLS_REJECT_UNAUTHORIZED = 0 (велике спасибі Хуанрі)

Якщо ви користуєтесь Windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Дякуємо: @ wogle08


12

Ви також можете створити екземпляр запиту з типовими параметрами:

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

3

Для meteorJS можна встановити за допомогою 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

Або ви можете спробувати додати роздільну здатність локального імені ( hostsфайл, знайдений у каталозі etcв більшості операційних систем, деталі відрізняються) приблизно так:

192.168.1.1 Linksys 

і далі

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

буду працювати.


3
правда, це може відповісти на питання, але я думаю, що наступною помилкою буде DEPTH_ZERO_SELF_SIGNED_CERT в цьому випадку.
Олів'є Амблет

1
тож як можна обійти DEPTH_ZERO_SELF_SIGNED_CERT? Я зараз стикаюся з цим.
reza

3
@reza: додайте це до своїх параметрів:rejectUnauthorized: false
Obay

1
Я знаю, що це трохи старе, але для подальшого використання (щоб це зробити правильно), вам потрібно отримати PEM-кодування самопідписаного сертифіката і включити його в параметри як CA (ви, мабуть, також потрібні встановити значення агента, але це може бути помилковим). Оскільки сертифікат є власноручним підписом, він виступає як власний КА, і тому його можна використовувати для перевірки. Однак я також хотів би поставити під сумнів, чи дійсно варто це зробити на маршрутизаторі, оскільки прошивку, ймовірно, можна буде завантажити, і тому приватний ключ може бути легко порушений.
Джонатан Грей
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.