Jak dodać niestandardowy certyfikat CA Root do sklepu CA używanego przez pip w systemie Windows?

85

Właśnie zainstalowałem Python3 z python.org i mam problem z instalacją pakietów z pip. Zgodnie z projektem w sieci znajduje się urządzenie do inspekcji pakietów typu man-in-the-middle, które sprawdza wszystkie pakiety (w tym SSL), rezygnując z wszystkich połączeń SSL z własnym certyfikatem. Część obiektu zasad grupy wypycha niestandardowy certyfikat główny do magazynu kluczy systemu Windows.

Jeśli używam języka Java, muszę uzyskać dostęp do zewnętrznych witryn https, muszę ręcznie zaktualizować cacerts w JVM, aby ufać certyfikatowi Self-Signed CA.

Jak to zrobić w Pythonie? W tej chwili, gdy próbuję zainstalować pakiety przy użyciu pip, co zrozumiałe, otrzymuję wspaniałe [SSL: CERTIFICATE_VERIFY_FAILED]błędy.

Zdaję sobie sprawę, że mogę je zignorować, używając --trusted-hostparametru, ale nie chcę tego robić dla każdego pakietu, który próbuję zainstalować.

Czy istnieje sposób na zaktualizowanie magazynu certyfikatów urzędu certyfikacji, z którego korzysta Python?

Eric B.
źródło
5
@rfkortekaas Wszystkie te opcje obejmują dodanie czegoś nowego do procesu. Python musi korzystać z domyślnego magazynu zaufania przechowywanego gdzieś w systemie. Chciałbym zmodyfikować ten magazyn zaufania. Nie chcę dodawać dodatkowych zmiennych, różnych magazynów CA, itp. W Javie jvm polega na własnym magazynie zaufania (niezależnym od systemu operacyjnego). Podejrzewam, że Python musi robić coś podobnego, ponieważ mój certyfikat główny znajduje się w moim sklepie Windows i nie jest rozpoznawany przez Pythona.
Eric B.

Odpowiedzi:

98

Urzędy certyfikacji z podpisem własnym pip/conda

Po dokładnym udokumentowaniu podobnego problemu z Gitem ( Jak sprawić, by git zaakceptował certyfikat z podpisem własnym? ), Znowu jesteśmy za korporacyjną zaporą ogniową z serwerem proxy, który daje nam „atak” MitM , któremu powinniśmy zaufać i:

NIGDY nie wyłączaj całej weryfikacji SSL!

Stwarza to złą kulturę bezpieczeństwa. Nie bądź tą osobą.

tl; dr

pip config set global.cert path/to/ca-bundle.crt
pip config list
conda config --set ssl_verify path/to/ca-bundle.crt
conda config --show ssl_verify

# Bonus while we are here...
git config --global http.sslVerify true
git config --global http.sslCAInfo path/to/ca-bundle.crt

Ale dokąd to dotrzemy ca-bundle.crt?


Uzyskaj aktualny pakiet CA

cURL publikuje wyciąg z urzędów certyfikacji dołączony do przeglądarki Mozilla Firefox

https://curl.haxx.se/docs/caextract.html

Zalecam otwarcie tego cacert.pempliku w edytorze tekstu, ponieważ będziemy musieli dodać nasz samopodpisany CA do tego pliku.

Certyfikaty to dokument zgodny ze standardem X.509, ale można je zakodować na dysk na kilka sposobów. Poniższy artykuł jest dobrą lekturą, ale w krótkiej wersji mamy do czynienia z kodowaniem base64, które często jest nazywane PEM w rozszerzeniach plików. Zobaczysz, że ma format:

----BEGIN CERTIFICATE----
....
base64 encoded binary data
....
----END CERTIFICATE----

https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them


Uzyskanie naszego certyfikatu z podpisem własnym

Poniżej znajduje się kilka opcji, jak uzyskać nasz certyfikat z podpisem własnym:

  • Poprzez OpenSSL CLI
  • Za pośrednictwem przeglądarki
  • Za pomocą skryptów w języku Python

Uzyskaj nasz certyfikat z podpisem własnym przez OpenSSL CLI

/unix/451207/how-to-trust-self-signed-certificate-in-curl-command-line/468360#468360

echo quit | openssl s_client -showcerts -servername "curl.haxx.se" -connect curl.haxx.se:443 > cacert.pem

Uzyskaj nasz urząd certyfikacji z podpisem własnym za pośrednictwem przeglądarki

Dzięki tej odpowiedzi i powiązanemu blogowi pokazuje kroki (w systemie Windows), jak wyświetlić certyfikat, a następnie skopiować do pliku przy użyciu opcji kodowania base64 PEM.

Skopiuj zawartość tego wyeksportowanego pliku i wklej go na końcu cacerts.pempliku.

Dla spójności zmień nazwę tego pliku cacerts.pem-> ca-bundle.crti umieść go w łatwym miejscu, na przykład:

# Windows
%USERPROFILE%\certs\ca-bundle.crt

# or *nix
$HOME/certs/cabundle.crt

Uzyskaj nasz urząd certyfikacji z podpisem własnym za pośrednictwem języka Python

Dzięki wszystkim genialnym odpowiedziom w:

Jak uzyskać certyfikat SSL odpowiedzi z żądań w Pythonie?

Złożyłem poniższe, aby spróbować pójść o krok dalej.

https://github.com/neozenith/get-ca-py


Wreszcie

Ustaw konfigurację w pip i conda, aby wiedziała, gdzie znajduje się ten magazyn urzędu certyfikacji z naszym dodatkowym urzędem certyfikacji z podpisem własnym.

pip config set global.cert %USERPROFILE%\certs\ca-bundle.crt
conda config --set ssl_verify %USERPROFILE%\certs\ca-bundle.crt

LUB

pip config set global.cert $HOME/certs/ca-bundle.crt
conda config --set ssl_verify $HOME/certs/ca-bundle.crt

NASTĘPNIE

pip config list
conda config --show ssl_verify

# Hot tip: use -v to show where your pip config file is...
pip config list -v
# Example output for macOS and homebrew installed python
For variant 'global', will try loading '/Library/Application Support/pip/pip.conf'
For variant 'user', will try loading '/Users/jpeak/.pip/pip.conf'
For variant 'user', will try loading '/Users/jpeak/.config/pip/pip.conf'
For variant 'site', will try loading '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/pip.conf'

Bibliografia

Josh Peak
źródło
6
Jedna z najlepszych odpowiedzi wszechczasów
Kevin Pauli,
pip config set global.trusted-host XXXXX.com
zzzz zzzz
W systemie Windows działa u mnie przy użyciu formatu .pem dla certyfikatu.
Daniel Argüelles
1
@ DanielArgüelles tak, to prawda. Najczęściej można uniknąć scalania pakietu urzędów certyfikacji, ale miałem wystarczająco dużo czasu, gdy potrzebny jest pełny pakiet, aby pip lub conda mogły weryfikować certyfikaty dla innych serwerów. Ostatecznie pakiet jest nadal plikiem tekstowym z zawartością wielu plików PEM. Cieszę się, że zadziałało i nie musisz wyłączać weryfikacji! : D
Josh Peak
42

Biegać: python -c "import ssl; print(ssl.get_default_verify_paths())" aby sprawdzić bieżące ścieżki, które są używane do weryfikacji certyfikatu. Dodaj certyfikat główny swojej firmy do jednego z nich.

Ścieżka openssl_capath_envwskazuje na zmienną środowiskową: SSL_CERT_DIR.

Jeśli SSL_CERT_DIRnie istnieje, musisz go utworzyć i wskazać prawidłowy folder w systemie plików. Następnie możesz dodać swój certyfikat do tego folderu, aby go używać.

rfkortekaas
źródło
11
w moim systemie Windows zwraca to „/ usr / local / ssl / certs”, który nie jest dostępny w systemie Windows.
Colin Talbert,
1
W końcu udało mi się to zrobić po tym, jak zostałem wciągnięty do innego projektu i podobnie jak @ColinTalbert wskazuje na nieistniejący folder /usr/local/ssl/certs.
Eric B.
Zredagowałem moje pytanie i mam nadzieję, że to rozwiązuje sprawę.
rfkortekaas
1
@rfkortekaas Aktualizacja SSL_CERT_FILE lub SSL_CERT_DIR nie działała. Właśnie utworzyłem nowe pytanie SO dotyczące tego problemu, ponieważ może to nie być po prostu kwestia tego, jak zaktualizować plik PEM, ale raczej, jak uzyskać dostęp do Pythona do właściwych ścieżek w cygwin / Windows.
Eric B.
1
Próbowałem. Skończyło się na utworzeniu pliku pip.conf ~/.config/pip/pip.confz niezbędnymi ustawieniami. Zobacz tę odpowiedź .
Eric B.
7

Nie najlepsza odpowiedź, ale możesz ponownie wykorzystać już utworzony pakiet ca, korzystając z --certopcji pip, na przykład:

pip install SQLAlchemy==1.1.15 --cert="C:\Users\myUser\certificates\my_ca-bundle.crt"
aturegano
źródło
4

W systemie Windows rozwiązałem to, tworząc plik pip.ini w% APPDATA% \ pip \

np. C: \ Users \ asmith \ AppData \ Roaming \ pip \ pip.ini

W pip.ini umieściłem ścieżkę do mojego certyfikatu:

[global]
cert=C:\Users\asmith\SSL\teco-ca.crt

https://pip.pypa.io/en/stable/user_guide/#configuration zawiera więcej informacji o pliku konfiguracyjnym.

Alex
źródło
Cześć Alex, w jaki sposób „umieściłeś” ścieżkę do swojego certyfikatu w pliku pip.ini? Z wiersza poleceń? Czy wpisałeś ścieżkę do pliku w czymś takim jak notatnik i zapisałeś ją jako plik tekstowy? Używam monitu anaconda, ale myślę, że jest podobny do systemu Windows.
spacedustpi
Utworzyłem plik tekstowy za pomocą Notatnika, a następnie zmieniłem rozszerzenie pliku z „txt” na „ini”.
Alex
Ach. W porządku. Czy musisz też wpisać „[gobal]” nad ścieżką? Czy wiesz, gdzie mogę znaleźć samouczek dotyczący tego typu rzeczy? Dzięki.
spacedustpi
Tak, musisz też wpisać „[global]”. Przepraszam, nie znam żadnego samouczka, ale pip.pypa.io/en/stable/user_guide/#configuration ma więcej informacji.
Alex
Dzięki, wypróbowałem to w obie strony i tak, „[globalnie]” nie boli.
spacedustpi
1

Alternatywnym rozwiązaniem w systemie Windows jest zainstalowanie python-certifi-win32, które umożliwi Pythonowi korzystanie z magazynu certyfikatów systemu Windows.

pip install python-certifi-win32
nt86
źródło
0

Myślę, że rozwiązanie NT86 jest najbardziej odpowiednie, ponieważ wykorzystuje podstawową infrastrukturę systemu Windows (magazyn certyfikatów). Ale nie wyjaśnia, jak zainstalować python-certifi-win32 na początek, ponieważ pip nie działa.

Sztuczka polega na tym, --trustedhostaby zainstalować python-certifi-win32, a następnie pip automatycznie użyje magazynu certyfikatów systemu Windows do załadowania certyfikatu używanego przez proxy.

Krótko mówiąc, powinieneś zrobić:

pip install python-certifi-win32 -trustedhost pypi.org

a potem powinieneś być gotowy

TonyM
źródło
-1

Otwórz Anaconda Navigator.

Przejdź do Plik \ Preferencje.

Włącz weryfikację SSL Wyłącz (niezalecane)

lub Włącz i wskaż ścieżkę certyfikatu SSL (opcjonalnie)

Zaktualizuj pakiet do określonej wersji:

Wybierz opcję Zainstaluj w prawym górnym rogu

Wybierz pakiet kliknij haczyk

Zaznacz do aktualizacji

Zaznacz do instalacji określonej wersji

Kliknij Zastosuj

itsergiu
źródło