¿Cómo agregar un certificado raíz de CA personalizado a la tienda CA utilizada por pip en Windows?

83

Acabo de instalar Python3 de python.org y tengo problemas para instalar paquetes con pip. Por diseño, hay un dispositivo de inspección de paquetes man-in-the-middle en la red aquí que inspecciona todos los paquetes (ssl incluido) al renunciar a todas las conexiones ssl con su propio certificado. Parte del GPO inserta el certificado raíz personalizado en el almacén de claves de Windows.

Cuando uso Java, si necesito acceder a sitios https externos, necesito actualizar manualmente los cacerts en la JVM para confiar en el certificado de CA autofirmado.

¿Cómo logro eso para Python? En este momento, cuando intento instalar paquetes usando pip, comprensiblemente, obtengo [SSL: CERTIFICATE_VERIFY_FAILED]errores maravillosos .

Me doy cuenta de que puedo ignorarlos usando el --trusted-hostparámetro, pero no quiero hacer eso para cada paquete que intento instalar.

¿Hay alguna forma de actualizar el almacén de certificados de CA que usa Python?

Eric B.
fuente
4
@rfkortekaas Todas esas opciones implican agregar algo nuevo al proceso. Python debe hacer uso de un almacén de confianza predeterminado almacenado en algún lugar del sistema. Me gustaría modificar esa tienda de confianza. No quiero agregar variables adicionales, diferentes almacenes de ca, etc. En Java, jvm se basa en su propio almacén de confianza (separado del sistema operativo). Sospecho que Python debe estar haciendo algo similar ya que mi certificado raíz está en mi tienda de Windows y no lo reconoce Python.
Eric B.

Respuestas:

94

Autoridades de certificación autofirmadas pip/conda

Después de documentar extensamente un problema similar con Git ( ¿Cómo puedo hacer que git acepte un certificado autofirmado? ), Aquí estamos nuevamente detrás de un firewall corporativo con un proxy que nos da un "ataque" MitM en el que debemos confiar y:

¡NUNCA desactive todas las verificaciones SSL!

Esto crea una mala cultura de seguridad. No seas esa persona.

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

¿Pero de dónde sacamos ca-bundle.crt?


Obtenga un paquete CA actualizado

cURL publica un extracto de las autoridades de certificación incluidas con Mozilla Firefox

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

Le recomiendo que abra este cacert.pemarchivo en un editor de texto, ya que necesitaremos agregar nuestra CA autofirmada a este archivo.

Los certificados son un documento que cumple con X.509, pero se pueden codificar en disco de varias formas. El artículo a continuación es una buena lectura, pero la versión corta es que estamos tratando con la codificación base64 que a menudo se llama PEM en las extensiones de archivo. Verás que tiene el formato:

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


Obtener nuestro certificado autofirmado

A continuación, se muestran algunas opciones sobre cómo obtener nuestro certificado autofirmado:

  • A través de OpenSSL CLI
  • A través del navegador
  • A través de secuencias de comandos de Python

Obtenga nuestro certificado autofirmado por 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

Obtenga nuestra autoridad de certificación autofirmada a través del navegador

Gracias a esta respuesta y al blog vinculado, muestra los pasos (en Windows) de cómo ver el certificado y luego copiarlo al archivo usando la opción de codificación base64 PEM.

Copie el contenido de este archivo exportado y péguelo al final de su cacerts.pemarchivo.

Para mayor coherencia, cambie el nombre de este archivo cacerts.pem-> ca-bundle.crty colóquelo en un lugar fácil como:

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

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

Obtenga nuestra autoridad certificadora autofirmada a través de Python

Gracias a todas las brillantes respuestas en:

¿Cómo obtener un certificado SSL de respuesta de solicitudes en Python?

He reunido lo siguiente para intentar dar un paso más.

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


Finalmente

Establezca la configuración en pip y conda para que sepa dónde reside esta tienda CA con nuestra CA autofirmada adicional.

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

O

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

ENTONCES

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'

Referencias

Josh Peak
fuente
5
Una de las mejores respuestas de todos los tiempos
Kevin Pauli
pip config set global.trusted-host XXXXX.com
zzzz zzzz
En Windows, me funciona usando el formato .pem para el certificado.
Daniel Argüelles
1
@ DanielArgüelles sí es cierto. La mayoría de las veces puede salirse con la suya sin fusionar el paquete de la Autoridad de certificación, pero he tenido suficientes ocasiones en las que se necesita el paquete completo para que pip o conda puedan validar certificados para otros servidores. En última instancia, un paquete sigue siendo un archivo de texto con el contenido de muchos archivos pem. ¡Me alegro de que haya funcionado y no necesites desactivar la verificación! : D
Josh Peak
42

Ejecutar: python -c "import ssl; print(ssl.get_default_verify_paths())"para comprobar las rutas actuales que se utilizan para verificar el certificado. Agregue el certificado raíz de su empresa a uno de esos.

El camino openssl_capath_envapunta a la variable de entorno: SSL_CERT_DIR.

Si SSL_CERT_DIRno existe, deberá crearlo y apuntarlo a una carpeta válida dentro de su sistema de archivos. Luego, puede agregar su certificado a esta carpeta para usarlo.

rfkortekaas
fuente
11
en mi sistema Windows, esto devuelve '/ usr / local / ssl / certs' que no está disponible en Windows.
Colin Talbert
1
Finalmente logré hacer esto también después de que me llevaron a otro proyecto, y similar a @ColinTalbert, apunta a una carpeta inexistente /usr/local/ssl/certs.
Eric B.
He editado mi pregunta y espero que esto resuelva el caso.
rfkortekaas
1
@rfkortekaas La actualización de las variables SSL_CERT_FILE o SSL_CERT_DIR no funcionó. Acabo de crear una nueva pregunta SO para este problema, ya que puede que no sea simplemente una cuestión de cómo actualizar un archivo PEM, sino de cómo hacer que Python acceda a las rutas correctas en cygwin / Windows.
Eric B.
1
Lo intenté. Terminé creando un archivo pip.conf ~/.config/pip/pip.confcon la configuración necesaria. Vea esta respuesta .
Eric B.
7

No es la mejor respuesta, pero puede reutilizar un paquete de ca ya creado usando la --certopción de pip, por ejemplo:

pip install SQLAlchemy==1.1.15 --cert="C:\Users\myUser\certificates\my_ca-bundle.crt"
aturegano
fuente
4

En Windows, lo resolví creando un archivo pip.ini en% APPDATA% \ pip \

por ejemplo, C: \ Users \ asmith \ AppData \ Roaming \ pip \ pip.ini

En pip.ini puse la ruta a mi certificado:

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

https://pip.pypa.io/en/stable/user_guide/#configuration tiene más información sobre el archivo de configuración.

Alex
fuente
Hola Alex, ¿cómo "pusiste" la ruta de tu certificado en el archivo pip.ini? ¿Desde la línea de comandos? ¿Escribió la ruta del archivo en algo como el bloc de notas y la guardó como un archivo de texto? Estoy usando el indicador de anaconda, pero creo que es similar a Windows.
spacedustpi
Creé un archivo de texto con el Bloc de notas y luego cambié la extensión del archivo de "txt" a "ini".
Alex
¡Ah! Bueno. ¿También tienes que escribir "[gobal]" encima de la ruta? ¿Sabes dónde puedo obtener un tutorial para este tipo de cosas? Gracias.
spacedustpi
Sí, también debe escribir "[global]". Lo siento, no conozco ningún tutorial, pero pip.pypa.io/en/stable/user_guide/#configuration tiene más información.
Alex
Gracias, lo probé en ambos sentidos y sí, "[global]" no hace daño.
spacedustpi
1

Una solución alternativa en Windows es instalar python-certifi-win32 que permitirá a Python usar la Tienda de certificados de Windows.

pip install python-certifi-win32
nt86
fuente
-1

Abra Anaconda Navigator.

Vaya a Archivo \ Preferencias.

Habilitar verificación SSL Deshabilitar (no recomendado)

o Habilite e indique la ruta del certificado SSL (Opcional)

Actualice un paquete a una versión específica:

Seleccione Instalar en la parte superior derecha

Seleccione el paquete haga clic en la marca

Marcar para actualización

Marcar para instalación de versión específica

Haga clic en Aplicar

itsergiu
fuente