Jak naprawić błąd certyfikatu SSL podczas uruchamiania Npm w systemie Windows?


88

Kiedy próbuję zainstalować pakiet z npm, to nie działa. Po długim oczekiwaniu w końcu pojawia się błąd „Nie można ustanowić gniazda tunelującego, 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)

Jednak kiedy przeglądam ten sam adres URL w mojej przeglądarce internetowej (Google Chrome), ładuje się dobrze (patrz przypis). https://registry.npmjs.org/coffee-script

Co się dzieje?


Chociaż korzystam z serwera proxy https, jestem pewien, że to nie jest problem. Skonfigurowałem zmienną środowiskową https_proxy(zgodnie z instrukcją użytkownika npm ). Wiem, że zmienna środowiskowa jest poprawna, ponieważ menedżer pakietów Pythona pippoprawnie ją przestrzega.

Wydaje mi się, że problem dotyczy certyfikatów SSL, ponieważ jeśli pobieram ten adres URL z wget, otrzymuję wyraźny błąd dotyczący certyfikatów

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

Jak mogę to naprawić? Bez narażania bezpieczeństwa.


Kiedyś otrzymywałem błędy certyfikatu SSL w mojej przeglądarce internetowej, dopóki nie zainstalowałem certyfikatu `` npmCA '' jako `` zaufanego głównego urzędu certyfikacji '' w Opcjach internetowych Panelu sterowania (zrzut ekranu wprowadź opis obrazu tutaj)


Edycja: próbowałem niezabezpieczonego obejścia na https://npmjs.org/doc/config.html#strict-ssl

npm set strict-ssl false

Jednak nadal kończy się czas z tym samym błędem

$ 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

Jest to podobne do problemu, który mam: stackoverflow.com/questions/11773509/ ...
nwinkler


Wpisanie „npm set strict-ssl false” rozwiązało problem
MrD

Odpowiedzi:


142

TL; DR - Po prostu uruchom to i nie wyłączaj swoich zabezpieczeń:

Zastąp istniejące certyfikaty

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

# Check the 'cafile'
npm config get cafile

lub rozszerz istniejące certyfikaty

Ustaw tę zmienną środowiskową, aby rozszerzyć wstępnie zdefiniowane certs: NODE_EXTRA_CA_CERTSto"<path to certificate file>"

Pełna historia

Musiałem pracować z npm, pip, maven itp. Za firmową zaporą ogniową pod Windows - to nie jest zabawne. Postaram się, aby ta platforma była agnostyczna / świadoma, jeśli to możliwe.

HTTP_PROXY i HTTPS_PROXY

HTTP_PROXY& HTTPS_PROXYsą zmiennymi środowiskowymi używanymi przez wiele programów, aby wiedzieć, gdzie jest twój serwer proxy. W systemie Windows wiele programów korzysta również z serwera proxy określonego przez system operacyjny, co jest zupełnie inną rzeczą. Oznacza to, że możesz mieć Chrome (który używa serwera proxy określonego w opcjach internetowych) łączący się z adresem URL w porządku, ale npm, pip, maven itp. Nie działają, ponieważ używają HTTPS_PROXY (z wyjątkiem sytuacji, gdy używają HTTP_PROXY - zobacz później). Zwykle zmienna środowiskowa wyglądałaby mniej więcej tak:

http://proxy.example.com:3128

Ale otrzymujesz kod 403, który sugeruje, że nie jesteś uwierzytelniany na swoim serwerze proxy. Jeśli chodzi o uwierzytelnianie podstawowe na serwerze proxy, będziesz chciał ustawić zmienną środowiskową na coś w postaci:

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

Przerażający NTLM

Istnieje kod stanu HTTP 407 (wymagane uwierzytelnienie proxy), który jest bardziej poprawnym sposobem stwierdzenia, że ​​jest to serwer proxy, a nie serwer docelowy, który odrzuca Twoje żądanie. Ten kod nękał mnie przez długi czas, aż po długim czasie spędzonym w Google dowiedziałem się, że mój serwer proxy używa uwierzytelniania NTLM . Podstawowe uwierzytelnienie HTTP nie wystarczyło, aby spełnić wymagania serwera proxy, który zainstalował mój korporacyjny overlords. Zdecydowałem się na użycie Cntlm na moim komputerze lokalnym (nieuwierzytelnionym), a następnie obsłużyłem uwierzytelnianie NTLM za pomocą serwera proxy nadrzędnego. Następnie musiałem powiedzieć wszystkim programom, które nie mogą obsługiwać NTLM, aby używały mojej maszyny lokalnej jako serwera proxy - co jest ogólnie tak proste, jak ustawienie HTTP_PROXYi HTTPS_PROXY. W przeciwnym razie, do użycia npm (jak sugeruje @Agus):

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

„Musimy odszyfrować cały ruch HTTPS, ponieważ wirusy”

Po tym, jak ta konfiguracja nuciła się (niezgrabnie) przez około rok, zwierzchnicy korporacji postanowili zmienić proxy. Nie tylko to, ale nie będzie już używać NTLM! Na pewno nowy wspaniały świat. Ponieważ jednak twórcy złośliwego oprogramowania dostarczali teraz złośliwe oprogramowanie za pośrednictwem protokołu HTTPS, jedynym sposobem, w jaki mogli chronić nas, biednych, niewinnych użytkowników, było pośredniczenie w każdym połączeniu w celu skanowania w poszukiwaniu zagrożeń, zanim jeszcze do nas dotarły. Jak możesz sobie wyobrazić, ogarnęło mnie poczucie bezpieczeństwa.

Krótko mówiąc, certyfikat z podpisem własnym należy zainstalować w npm, aby uniknąć SELF_SIGNED_CERT_IN_CHAIN:

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

Alternatywnie NODE_EXTRA_CA_CERTSzmienną środowiskową można ustawić na plik certyfikatu.

Myślę, że to wszystko, co wiem na temat uruchamiania npm za proxy / firewallem. Niech ktoś uzna to za przydatne.

Edycja : to bardzo powszechna sugestia, aby wyłączyć HTTPS w przypadku tego problemu za pomocą rejestru HTTP lub ustawienia NODE_TLS_REJECT_UNAUTHORIZED. To nie są dobre pomysły, ponieważ otwierasz się na dalsze ataki typu man-in-the-middle lub przekierowania. Szybkie sfałszowanie twoich rekordów DNS na maszynie wykonującej instalację pakietu, a zobaczysz, że ufasz pakietom z dowolnego miejsca. Może wydawać się, że wykonanie protokołu HTTPS wymaga dużo pracy, ale jest wysoce zalecane. Kiedy jesteś osobą odpowiedzialną za wpuszczenie niezaufanego kodu do firmy, zrozumiesz dlaczego.

Edycja 2 : pamiętaj, że ustawienie npm config set cafile <path>powoduje, że npm używa tylko certyfikatów zawartych w tym pliku, zamiast rozszerzać istniejące certyfikaty.

Jeśli chcesz rozszerzyć istniejące certyfikaty (np. O certyfikat firmowy), użycie zmiennej środowiskowej w NODE_EXTRA_CA_CERTScelu połączenia z plikiem jest najlepszym rozwiązaniem i może zaoszczędzić wiele kłopotów. Zobacz, jak dodać-niestandardowy-urząd-certyfikatu-ca-to-nodejs


9
W systemie Windows musiałem użyć ukośników: npm config set cafile "C: /dev/Firefox/mycert.cer"
John Jesus

4
** Bez znaku równości= npm config set cafile "<path to your certificate file>"
Moti Winkler

3
To niesamowita odpowiedź - nie mogłem lepiej podsumować własnych bólów głowy dotyczących proxy + zscalar
Jpnh

7
śmiał się tak mocno z powodu „Jak możesz sobie wyobrazić, ogarnęło mnie poczucie bezpieczeństwa”. :)
Mario B

3
Jak uzyskać plik certyfikatu?
Aditya

36

Ten problem został dla mnie rozwiązany przy użyciu wersji repozytorium http:

npm config set registry http://registry.npmjs.org/

52
To bardzo złe rozwiązanie!
KiT O

4
@HaBo Zgaduję, że ma na myśli to, że jest to niebezpieczne.
gabeio,

3
@KiTO Zgodził się, że to złe rozwiązanie. Ale dlaczego miałbym mieć kłopoty z problemami z certyfikatami, gdy chcę tylko zainstalować niektóre pakiety?
Ich

17
Ta odpowiedź jest poprawna. W niektórych przypadkach jesteś za bałaganem korporacyjnego proxy z własnym łańcuchem certyfikatów ponad innymi i nie ma innego wyjścia (poza całkowitym wyłączeniem certyfikatów) niż ten (zwłaszcza gdy nie dają ci uprawnień administratora). Brzmi to jak błąd npm, który nie ładuje poprawnie odpowiednich ustawień z systemu. Ale ze względu na kompatybilność krzyżową nie naprawią npm, więc jest to wynikiem tego. Ludzie, którzy mówią, że to zła odpowiedź, nie mają pojęcia, o czym mówią.
kenorb

3
@kenorb to niepoprawne, możesz prześledzić kroki wykonywane przez serwer proxy i dodać te certyfikaty z podpisem własnym do swojego łańcucha z cafile.
dardo

15
npm config set strict-ssl false

rozwiązał problem za mnie. W tym przypadku zarówno mój agent, jak i depozyt artefaktów znajdują się za prywatną podsiecią w chmurze aws


7

Mam ten sam problem, przezwyciężam używanie

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

Dodatkowe informacje w node-doc


6

Zdarzyło mi się napotkać ten podobny problem z SSL kilka dni temu. Problem polega na tym, że Twój npm nie ustawia certyfikatu głównego dla certyfikatu używanego przez https://registry.npmjs.org .

Rozwiązania:

  1. Służy wget https://registry.npmjs.org/coffee-script --ca-certificate=./DigiCertHighAssuranceEVRootCA.crtdo rozwiązywania problemu z wget
  2. Służy npm config set cafile /path/to/DigiCertHighAssuranceEVRootCA.crtdo ustawiania certyfikatu głównego dla programu npm.

możesz pobrać certyfikat główny z: https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt

Uwaga: różne programy mogą używać różnych sposobów zarządzania certyfikatem głównym, więc nie mieszaj przeglądarek z innymi.

Analiza:

wget https://registry.npmjs.org/coffee-scriptnajpierw rozwiążmy twój problem. Twój fragment mówi:

        BŁĄD: nie można zweryfikować certyfikatu register.npmjs.org,
        wydane przez / C = US / ST = CA / L = Oakland / O = npm / OU = npm 
       Urząd certyfikacji/CN=npmCA/emailAddress=i@izs.me:
       Nie można lokalnie zweryfikować uprawnień wydawcy.

Oznacza to, że program wget nie może zweryfikować https://registry.npmjs.orgcertyfikatu. Istnieją dwa powody, które mogą powodować ten problem:

  1. Twój program wget nie ma certyfikatu głównego tej domeny. Certyfikat główny jest zwykle dostarczany z systemem.
  2. Domena nie pakuje certyfikatu głównego do swojego certyfikatu.

Tak więc rozwiązanie jest jawnie ustawione dla certyfikatu głównego https://registry.npmjs.org. Możemy użyć openssl, aby upewnić się, że przyczyną poniżej jest problem.

Spróbuj openssl s_client -host registry.npmjs.org -port 443w wierszu poleceń, a otrzymamy ten komunikat (kilka pierwszych wierszy):

    POŁĄCZONO (00000003)
    głębokość = 1 / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert High Assurance CA-3
    błąd weryfikacji: num = 20: nie można uzyskać certyfikatu lokalnego wydawcy
    zweryfikuj zwrot: 0
    ---
    Łańcuch certyfikatów
     0 s: / C = USA / ST = Kalifornia / L = San Francisco / 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 s: / 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
    ---

Ta linia verify error:num=20:unable to get local issuer certificatezapewnia, że https://registry.npmjs.orgnie zawiera certyfikatu głównego. Więc mamy DigiCert High Assurance EV Root CAcertyfikat główny Google .


Jeśli możesz dostarczyć tylko podstawowy plik tekstowy (jak w przypadku kompilacji Jenkinsa), ten certyfikat można przekształcić w pem: openssl x509 -inform DER -outform PEM -in DigiCertHighAssuranceEVRootCA.crt -out DigiCertHighAssuranceEVRootCA.pem
Audrius Meskauskas

4

Miałem ten sam problem. Po pewnym kopaniu zdałem sobie sprawę, że wiele skryptów post / preinstalacyjnych będzie próbowało zainstalować różne zależności, a czasami używane są określone repozytoria. Lepszym sposobem jest wyłączenie sprawdzania certyfikatów dla modułu https dla nodejs, który działał dla mnie.

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"

Z tego pytania


2
Jak już wspomniano, nie rozwiąże to problemu z SSL, tylko go ominie. Właściwym sposobem rozwiązania tego problemu jest odpowiednie skonfigurowanie każdego pakietu (git, npm, węzeł) tak, aby ufał właściwemu certyfikatowi podpisującemu. Jeśli stoisz za wspólnikiem, prawnikiem.
Aaron C

0

Problem leży po stronie twojego proxy. Ponieważ dostawca lokalizacji pakietu instalacyjnego tworzy własny certyfikat i nie kupuje zweryfikowanego od akceptowanego urzędu, serwer proxy nie zezwala na dostęp do docelowego hosta. Zakładam, że podczas korzystania z przeglądarki Chrome omijasz proxy. Więc nie ma sprawdzania.

Istnieje kilka rozwiązań tego problemu. Ale wszystko wskazuje na to, że ufasz dostawcy pakietu.

Możliwe rozwiązania:

  1. Jak wspomniano w innych odpowiedziach, możesz utworzyć plik http:// dostęp, który może ominąć twoje proxy. To trochę niebezpieczne, ponieważ człowiek w środku może wstrzyknąć złośliwe oprogramowanie do pobranych plików.
  2. wgetSugeruje użycie flagi--no-check-certificate . Spowoduje to dodanie dyrektywy proxy do Twojego żądania. Proxy, jeśli rozumie dyrektywę, nie sprawdza, czy certyfikat serwera jest weryfikowany przez urząd i przekazuje żądanie. Być może istnieje konfiguracja z npm, która robi to samo, co flaga wget.
  3. Skonfiguruj serwer proxy, aby akceptował CA npm. Nie znam twojego proxy, więc nie mogę ci podpowiedzieć.


0

Jeśli masz kontrolę nad serwerem proxy lub możesz przekonać administratorów IT, możesz spróbować jawnie wykluczyć register.npmjs.org z kontroli SSL. Powinno to uniknąć konieczności wyłączania sprawdzania ścisłego protokołu SSL lub instalowania nowego głównego urzędu certyfikacji przez użytkowników serwera proxy.


-1

Oto, co możesz zrobić, aby uniknąć npm i użyć przędzy w maszynie okiennej.

yarn config set "strict-ssl" false
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.