Как добавить собственный центр сертификации (CA) в nodejs

Я использую инструмент CLI для создания гибридных мобильных приложений, у которых есть отличная функция загрузки, поэтому я могу протестировать приложение на устройстве, не проходя через хранилище приложений (itionic-cli). Тем не менее, в моей компании, как и многие другие запросы TLS компании, повторно подписаны с собственным сертификатом CA, который у меня есть на моей машине в keychain (OS X). Однако nodejs не использует цепочку ключей для получения доверия к своему списку CA. Я не контролирую приложение ionic-cli, поэтому я не могу просто передать свойство {ca:} в модуль https. Я также вижу, что это проблема для любого приложения node, которое я не контролирую. Можно ли сказать nodejs доверять CA?

Я не был уверен, что это относится к информационной безопасности или к любому другому обмену...

Ответ 1

В настоящее время это невозможно, если вы не компилируете пользовательскую версию nodejs с настраиваемыми сертификатами CA. Hard-baked CA certs является текущим ограничением nodejs, пока кто-то не подает PR и не сливается. Это проблема и для других.

Ниже у меня есть некоторые копии обходных решений, которые могут помочь некоторым людям, но, вероятно, не OP.

Насколько я знаю, OP может:

  • Пользовательские компиляции nodejs
  • отправить PR для nodejs, чтобы исправить проблему.
  • файл или PR с помощью ionic-cli для поддержки пользовательских сертификатов CA: https://github.com/driftyco/ionic-cli (как было предложено @Nate)
  • Принудительная защита (без TLS или молчания, также предложенная @Nate)

Другие, если вы контролируете приложение nodejs, у вас есть больше опций. Вы можете, конечно, указать сертификат ca в каждом запросе. Некоторые умные люди поделились некоторыми обходными решениями в проблеме github https://github.com/nodejs/node/issues/4175. Я еще не пробовал ни одного из них, но не promises, я просто делюсь тем, что я читал.

DuBistKomisch объясняет, как заставить nodejs использовать сертификаты CA операционной системы:

Мое обходное решение - загрузить и проанализировать сертификаты CA системы вручную. Затем, как рекомендовано документами запроса, передать их с помощью опции ca везде мы делаем запрос. Я полагаю, вы могли бы просто глобальный агент, если это работает для вашего использования.

fs.readFileSync('/etc/ssl/certs/ca-certificates.crt')
  .toString()
  .split(/-----END CERTIFICATE-----\n?/)
  // may include an extra empty string at the end
  .filter(function (cert) { return cert !== ''; })
  // effectively split after delimiter by adding it back
  .map(function (cert) { return cert + '-----END CERTIFICATE-----\n'; })

mwain объясняет, как устанавливать сертификаты CA по всему миру, а не по каждому запросу https:

Имели схожие проблемы с этим, внутренние приложения, использующие внутренне подписанный сертификат. Не удалось использовать https.globalAgent и установить массив CA которые определены в конфиге и обновлены на основе env.

const trustedCa = [
    '/etc/pki/tls/certs/ca-bundle.crt',
    '/path/to/custom/cert.crt'
];

https.globalAgent.options.ca = [];
for (const ca of trustedCa) {
    https.globalAgent.options.ca.push(fs.readFileSync(ca));
}

Ответ 2

Node.js 7.3.0 добавлена ​​переменная среды NODE_EXTRA_CA_CERTS для передачи файла сертификата CA. Это будет безопаснее, чем отключить проверку сертификата, используя NODE_TLS_REJECT_UNAUTHORIZED.

$ export NODE_EXTRA_CA_CERTS=[your CA certificate file path]

Ответ 3

Я знаю два модуля npm, которые справляются с этой проблемой при управлении этим приложением:

node-ssl-root-cas связывает его собственные копии корневых центров сертификации узлов, а также позволяет добавлять собственные CA для доверия. Он помещает сертификаты в глобальный агент https, поэтому он будет использоваться только для модуля https, а не для чистых соединений tls. Кроме того, вам потребуются дополнительные шаги, если вы используете настраиваемый агент вместо глобального агента.

syswide-cas загружает сертификаты из предопределенных каталогов (например,/etc/ssl/certs) и использует внутренний API node, чтобы добавить их в доверенный список ЦС в сочетании с корневыми ЦС в комплекте. Нет необходимости использовать параметр ca, поскольку он делает глобальное изменение, которое автоматически влияет на все последующие вызовы TLS. Также возможно добавить CA из других каталогов/файлов, если это необходимо. Было проверено, чтобы работать с node 0.10, node 5 и node 6.

Так как вы не контролируете приложение, вы можете создать обертку script, чтобы включить syswide-cas (или node-ssl-root-cas), а затем потребовать использовать ionic-cli script:

require('syswide-cas'); // this adds your custom CAs in addition to bundled CAs
require('./path/to/real/script'); // this runs the actual script

Ответ 4

Поскольку вы не контролируете приложение и не можете передать параметр ca (обычный способ сделать это), вы можете попросить Node не проверять сертификаты вообще, установив переменную окружения NODE_TLS_REJECT_UNAUTHORIZED. Например:

$ export NODE_TLS_REJECT_UNAUTHORIZED=0

Затем запустите приложение.

Как поясняет @keinabel, когда вы это сделаете, приложение будет доверять любому (поддельному, поддельному, законному) сертификату, открывая вам атаки "человек-в-середине". Правильное и безопасное решение было бы для разработчиков приложений позволить вам указать доверенный ЦС.