Как исправить ошибку сертификата SSL при запуске Npm в Windows?

88

Когда я пытаюсь установить пакет с помощью npm, он не работает. После долгого ожидания я в конечном итоге получаю сообщение об ошибке «Не удалось установить туннельный сокет, sutatusCode = 403».

$ npm install coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm ERR! Error: tunneling socket could not be established, sutatusCode=403
npm ERR!     at ClientRequest.onConnect (c:\Program Files\nodejs\node_modules\npm\node_modules\request\tunnel.js:148:19)
npm ERR!     at ClientRequest.g (events.js:193:14)
npm ERR!     at ClientRequest.EventEmitter.emit (events.js:123:20)
npm ERR!     at Socket.socketOnData (http.js:1393:11)
npm ERR!     at TCP.onread (net.js:403:27)

Однако когда я перехожу к тому же URL-адресу в своем веб-браузере (Google Chrome), он загружается нормально (см. Сноску). https://registry.npmjs.org/coffee-script

Что не так?


Хотя я использую прокси https, я уверен, что проблема не в этом. Я настроил переменную окружения https_proxy(согласно руководству пользователя npm ). Я знаю, что переменная среды верна, потому что диспетчер пакетов Python pipправильно следует за ней.

Я считаю, что проблема связана с сертификатами SSL, потому что, если я загружаю этот URL-адрес с помощью wget, я получаю явную ошибку о сертификатах

$ wget https://registry.npmjs.org/coffee-script
SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc
syswgetrc = c:/progra~1/wget/etc/wgetrc
--2012-12-17 12:14:07--  https://registry.npmjs.org/coffee-script
Resolving corpproxy... 10.254.215.35
Connecting to corpproxy|10.254.215.35|:8080... connected.
ERROR: cannot verify registry.npmjs.org's certificate, issued by `/C=US/ST=CA/L=Oakland/O=npm/OU=npm Certificate Authority/CN=npmCA/emailAddress=i@izs.me':
  Unable to locally verify the issuer's authority.
To connect to registry.npmjs.org insecurely, use `--no-check-certificate'.
Unable to establish SSL connection.

Как я могу это исправить? Без ущерба для безопасности.


Раньше у меня тоже возникали ошибки сертификата SSL в моем веб-браузере, пока я не установил сертификат npmCA в качестве доверенного корневого центра сертификации в настройках Интернета панели управления (снимок экрана введите описание изображения здесь)


Изменить: я пробовал небезопасный обходной путь для https://npmjs.org/doc/config.html#strict-ssl

npm set strict-ssl false

Тем не менее, время ожидания с той же ошибкой

$ npm install coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm ERR! Error: tunneling socket could not be established, sutatusCode=403
Полковник Паник
источник
Это похоже на
мою
1
Здравствуй. См. Также github.com/isaacs/npm/issues/2728
Colonel Panic
Ввод «npm set strict-ssl false» решил проблему
MrD

Ответы:

142

TL; DR - просто запустите это и не отключайте безопасность:

Заменить существующие сертификаты

# Windows/MacOS/Linux 
npm config set cafile "<path to your certificate file>"

# Check the 'cafile'
npm config get cafile

или расширить существующие сертификаты

Задайте эту переменную среды, чтобы расширить предварительно определенные сертификаты: NODE_EXTRA_CA_CERTSдо"<path to certificate file>"

Полная история

Мне приходилось работать с npm, pip, maven и т. Д. За корпоративным брандмауэром под Windows - это не весело. Я постараюсь, чтобы эта платформа была независимой / осведомленной, где это возможно.

HTTP_PROXY и HTTPS_PROXY

HTTP_PROXY& HTTPS_PROXY- это переменные среды, используемые множеством программ, чтобы узнать, где находится ваш прокси. Под Windows многие программы также используют прокси, указанные в вашей ОС, что совсем другое дело. Это означает, что у вас может быть Chrome (который использует прокси-сервер, указанный в ваших настройках Интернета) без проблем подключается к URL-адресу, но npm, pip, maven и т. Д. Не работают, потому что они используют HTTPS_PROXY (кроме случаев, когда они используют HTTP_PROXY - см. Позже). Обычно переменная окружения выглядит примерно так:

http://proxy.example.com:3128

Но вы получаете 403, который предполагает, что вы не проходите аутентификацию через свой прокси. Если это обычная проверка подлинности на прокси-сервере, вам нужно установить переменную среды примерно в следующем виде:

http://user:pass@proxy.example.com:3128

Ужасный NTLM

Существует код состояния HTTP 407 (требуется проверка подлинности прокси), который является более правильным способом сказать, что это прокси, а не целевой сервер, который отклоняет ваш запрос. Этот код мучил меня дольше всего, пока, проведя много времени в Google, я не узнал, что мой прокси-сервер использует аутентификацию NTLM . Базовой аутентификации HTTP было недостаточно, чтобы удовлетворить любой прокси, установленный моими корпоративными властителями. Я прибег к использованию Cntlm на моем локальном компьютере (без аутентификации), а затем попросил его обработать аутентификацию NTLM с помощью прокси-сервера восходящего потока. Затем мне пришлось сказать всем программам, которые не могут использовать NTLM, использовать мою локальную машину в качестве прокси - обычно это так же просто, как установить HTTP_PROXYи HTTPS_PROXY. В противном случае для использования npm (как предлагает @Agus):

npm config set proxy http://proxy.example.com:3128
npm config set https-proxy http://proxy.example.com:3128

«Нам нужно расшифровать весь HTTPS-трафик из-за вирусов»

После того, как эта установка продолжалась (неуклюже) около года, корпоративные властители решили сменить прокси. Не только это, но он больше не будет использовать NTLM! Конечно же, дивный новый мир. Но поскольку эти создатели вредоносного ПО теперь доставляли вредоносное ПО через HTTPS, единственный способ защитить нас, бедных, невинных пользователей, - это использовать посредничество при каждом подключении для сканирования угроз еще до того, как они достигнут нас. Как вы понимаете, меня охватило чувство безопасности.

Короче говоря, самозаверяющий сертификат необходимо установить в npm, чтобы избежать SELF_SIGNED_CERT_IN_CHAIN:

npm config set cafile "<path to certificate file>"

В качестве альтернативы NODE_EXTRA_CA_CERTSпеременная среды может быть установлена ​​в файл сертификата.

Думаю, это все, что я знаю о том, как заставить npm работать за прокси / брандмауэром. Пусть кому-то это пригодится.

Изменить : это действительно распространенное предложение отключить HTTPS для этой проблемы либо с помощью реестра HTTP, либо с помощью настройки NODE_TLS_REJECT_UNAUTHORIZED. Это нехорошие идеи, потому что вы открываете себя для дальнейших атак типа «злоумышленник в середине» или перенаправления. Быстрая подмена ваших DNS-записей на машине, выполняющей установку пакета, и вы обнаружите, что доверяете пакетам откуда угодно. Может показаться, что для того, чтобы HTTPS работал, потребуется много работы, но это настоятельно рекомендуется. Когда вы несете ответственность за то, чтобы разрешить ненадежный код в компанию, вы поймете, почему.

Изменить 2 : имейте в виду, что настройка npm config set cafile <path>заставляет npm использовать только сертификаты, предоставленные в этом файле, вместо того, чтобы расширять с ним существующие.

Если вы хотите расширить существующие сертификаты (например, с помощью сертификата компании), используйте переменную среды NODE_EXTRA_CA_CERTSдля ссылки на файл - это путь, который может сэкономить вам много хлопот. Узнайте, как добавить настраиваемый центр сертификации-ca-to-nodejs

Алекс Тейлор
источник
9
В Windows мне пришлось использовать косую черту: npm config set cafile «C: /dev/Firefox/mycert.cer»
Джон Хесус
4
** Без знака равенства= npm config set cafile "<path to your certificate file>"
Моти Винклер,
3
Это потрясающий ответ - я не мог лучше описать свои головные боли по поводу proxy + zscalar
Jpnh
7
так сильно рассмеялся из-за того, что «Как вы понимаете, меня охватило чувство безопасности». :)
Mario B
3
Как мне получить файл сертификата?
Адитья
36

Эта проблема была исправлена ​​для меня с помощью http-версии репозитория:

npm config set registry http://registry.npmjs.org/
Эхсан
источник
52
Это очень плохое решение!
KiT O 02
4
@HaBo Думаю, он имел в виду, что это небезопасно.
gabeio
3
@KiTO Плохое решение, согласен. Но зачем мне возиться с проблемами сертификата, если я просто хочу установить несколько пакетов?
Ich
17
Это правильный ответ. Бывают случаи, когда вы занимаетесь беспорядком корпоративного прокси с собственной цепочкой сертификатов поверх других, и нет другого пути (кроме отключения сертификатов вообще), кроме этого (особенно когда они не дают вам прав администратора). Это похоже на ошибку npm, которая неправильно загружает правильные настройки из системы. Но ради кросс-совместимости они не исправят npm, так что это результат. Люди, которые говорят, что это плохой ответ, понятия не имеют, о чем говорят.
kenorb
3
@kenorb, это неверно, вы можете проследить шаги, которые делает ваш прокси, и добавить эти самоподписанные сертификаты в свою цепочку с помощью cafile.
dardo
15
npm config set strict-ssl false

решил проблему для меня. В этом случае и мой агент, и хранилище артефактов находятся за частной подсетью в облаке aws.

Анупам Махапатра
источник
7

У меня такая же проблема, я преодолеваю, используя

npm config set proxy http://my-proxy.com:1080
npm config set https-proxy http://my-proxy.com:1080

Дополнительная информация на node-doc

Агус
источник
6

Несколько дней назад я столкнулся с подобной проблемой SSL. Проблема в том, что ваш npm не устанавливает корневой сертификат для сертификата, используемого https://registry.npmjs.org .

Решения:

  1. Используйте, wget https://registry.npmjs.org/coffee-script --ca-certificate=./DigiCertHighAssuranceEVRootCA.crtчтобы исправить проблему с wget
  2. Используйте npm config set cafile /path/to/DigiCertHighAssuranceEVRootCA.crtдля установки корневого сертификата для вашей программы npm.

вы можете скачать корневой сертификат из: https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt

Примечание: разные программы могут использовать разные способы управления корневым сертификатом, поэтому не смешивайте браузер с другими.

Анализ:

давайте wget https://registry.npmjs.org/coffee-scriptсначала исправим вашу проблему. ваш фрагмент говорит:

        ОШИБКА: невозможно проверить сертификат registry.npmjs.org,
        выдано / C = US / ST = CA / L = Oakland / O = npm / OU = npm 
       Центр сертификации/CN=npmCA/emailAddress=i@izs.me:
       Невозможно локально проверить полномочия эмитента.

Это означает, что ваша программа wget не может проверить https://registry.npmjs.orgсертификат. Есть две причины, которые могут вызвать эту проблему:

  1. Ваша программа wget не имеет корневого сертификата этого домена. Корневой сертификат обычно поставляется вместе с системой.
  2. Домен не упаковывает корневой сертификат в свой сертификат.

Таким образом, решение явно задает корневой сертификат для https://registry.npmjs.org. Мы можем использовать openssl, чтобы убедиться, что причина, указанная ниже, является проблемой.

Попробуйте openssl s_client -host registry.npmjs.org -port 443в командной строке, и мы получим это сообщение (первые несколько строк):

    ПОДКЛЮЧЕНО (00000003)
    глубина = 1 / C = США / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert High Assurance CA-3
    ошибка проверки: число = 20: невозможно получить сертификат местного эмитента
    проверить возврат: 0
    ---
    Цепочка сертификатов
     0 с: / C = США / ST = Калифорния / L = Сан-Франциско / O = Fastly, Inc./CN=a.sni.fastly.net
       i: / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert High Assurance CA-3
     1 с: / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert High Assurance CA-3
       i: / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert High Assurance EV Root CA
    ---

Эта строка verify error:num=20:unable to get local issuer certificateгарантирует, что https://registry.npmjs.orgкорневой сертификат не упакован. Итак, мы используем DigiCert High Assurance EV Root CAкорневой сертификат Google .

никто0day
источник
Если вы можете предоставить только базовый текстовый файл (например, для сборок Jenkins), этот сертификат можно преобразовать в pem: openssl x509 -inform DER -outform PEM -in DigiCertHighAssuranceEVRootCA.crt -out DigiCertHighAssuranceEVRootCA.pem
Audrius Meskauskas,
4

У меня была такая же проблема. После некоторого рытья я понял, что многие сценарии после / предварительной установки будут пытаться установить различные зависимости, и иногда используются определенные репозитории. Лучший способ - отключить проверку сертификата для модуля https для nodejs, который работал у меня.

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

Из этого вопроса

haroon
источник
2
Как уже упоминалось, это не решит проблему с SSL, а только обойдет ее. Правильный способ решить эту проблему - правильно настроить каждый пакет (git, npm, node), чтобы доверять правильному сертификату подписи. Если вы находитесь за совместным прокси, конечно.
Aaron C
0

Проблема кроется в вашем прокси. Поскольку провайдер местоположения вашего установочного пакета создает свой собственный сертификат и не покупает проверенный сертификат у признанного центра, ваш прокси не разрешает доступ к целевому хосту. Я предполагаю, что вы обходите прокси при использовании браузера Chrome. Так что проверки нет.

Есть несколько вариантов решения этой проблемы. Но все это означает, что вы доверяете поставщику пакетов.

Возможные решения:

  1. Как упоминалось в других ответах, вы можете сделать http:// доступ, который может обойти ваш прокси. Это немного опасно, потому что человек в середине может внедрить вредоносное ПО в ваши загрузки.
  2. Предлагает wgetвам использовать флаг --no-check-certificate. Это добавит к вашему запросу директиву прокси. Прокси-сервер, если он понимает директиву, не проверяет, подтвержден ли сертификат сервера органом, и передает запрос. Возможно, есть конфиг с npm, который делает то же самое, что и флаг wget.
  3. Вы настраиваете свой прокси для приема CA npm. Я не знаю вашего доверенного лица, поэтому не могу вам намекнуть.
Питер Пауль Кифер
источник
0

установите свойство ниже:

"npm config set strict-ssl false"

Рохит Маурья
источник
0

Если у вас есть контроль над прокси-сервером или вы можете убедить своих ИТ-администраторов, вы можете попытаться явно исключить Registry.npmjs.org из проверки SSL. Это должно избавить пользователей прокси-сервера от необходимости отключать строгую проверку SSL или устанавливать новый корневой центр сертификации.

Thiezn
источник
-1

Вот что вы можете сделать, чтобы избежать npm и использовать пряжу в оконной машине.

yarn config set "strict-ssl" false
Рам Кумар Тапа
источник