Игнорировать недействительный самоподписанный ssl-сертификат в node.js с помощью https.request?


309

Я работаю над небольшим приложением, которое подключается к моему локальному беспроводному маршрутизатору (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-Certificate»?

Ответы:


601

Дешевый и небезопасный ответ:

Добавить

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

в коде, перед звонком https.request()

Более безопасный способ (решение выше делает весь процесс узла незащищенным) дает ответ на этот вопрос


2
Работал как шарм для меня! Я поместил этот код сразу после того, как включил все в самый верх моего основного приложения js.
Шестнадцатое

Это также работает для комбо NodeJS & SailJS. Я добавил его в начало local.js
Майкл Корк.

38
Не используйте это или «rejectUnauthorized» в производственной среде, так как это отключает все виды проверок безопасности.
Джейсон Уолтон

3
У меня были проблемы с запуском тестов с использованием mocha на моем самозаверяющем сервере узлов 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
    },

Работал на меня. Я использую рестлер и вижу, что по умолчанию параметры не пересылаются, поэтому мне пришлось его исправлять.
Оливье Эмблет

2
Чтобы это работало, вам нужно предоставить явный экземпляр пользовательского агента. Создайте объект параметров и установите агента: 'options.agent = новый https.Agent (параметры);' Тогда просто позвоните «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 в скобки, а не храните его в виде строки?
Лело

Лело: скобки превращают его в массив. CA: ожидает массив сертификатов. Этот файл должен представлять собой список сертификатов через запятую, часто люди используют внутреннюю функцию, чтобы превратить файл 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 для окон
Фелипе С.С.

Это было отличное решение для моей среды разработки
Дэвид

14

Добавление к ответу @Armand:

Добавьте следующую переменную среды:

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

export NODE_TLS_REJECT_UNAUTHORIZED = 0 (с большой благодарностью Хуанре)

Если вы используете Windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Благодаря: @ weagle08


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? Я сталкиваюсь с этим сейчас.
Реза

3
@reza: добавьте это к вашим опциям:rejectUnauthorized: false
Obay

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