Перейти к содержимому
ecdsa.com
requests / urllib3 (Python)Python: пакет cryptography

Сообщение об ошибке

Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

Также выводится как

  • requests.exceptions.SSLError: HTTPSConnectionPool(host='api.example.com', port=8443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

Хост, порт и путь URL берутся из вашего запроса. Самая внутренняя причина бывает разной («self-signed certificate in certificate chain», «Hostname mismatch…», «certificate has expired»), а в конце строки стоит место в исходном коде, например «(_ssl.c:1082)')))».

requests / urllib3 (Python) — requests.exceptions.SSLError wrapping urllib3 MaxRetryError

Что это означает

Библиотека requests запросила у urllib3 соединение, при TLS-рукопожатии сертификат не прошёл проверку, и urllib3 сдалась (по умолчанию requests не делает повторных попыток, так что сразу после первой). Полезная часть — внутри скобок: здесь OpenSSL не нашёл издателя в пакете сертификатов CA, который использует requests, а по умолчанию это копия корневых сертификатов Mozilla из certifi, а не хранилище операционной системы.

Почему это происходит

Как исправить

  1. 1.

    Передайте нужный пакет сертификатов через verify=

    verify принимает путь к файлу пакета сертификатов CA или к каталогу CA с хешированными именами файлов; проверки имени хоста и срока действия остаются включёнными.

    python
    import requests
    
    # A CA file (or a directory prepared with c_rehash) for this call
    requests.get("https://api.example.com/", verify="/etc/ssl/certs/ca-certificates.crt")
  2. 2.

    Задайте REQUESTS_CA_BUNDLE для процесса

    Если указать в этой переменной системный пакет сертификатов (предварительно установив туда ваш CA), каждый вызов requests в этом процессе будет доверять тем же корневым сертификатам, что curl и инструменты ОС.

    bash
    # For every requests call in the process (also honoured: CURL_CA_BUNDLE)
    export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt   # Debian/Ubuntu system bundle
    python3 app.py
  3. 3.

    Используйте хранилище доверенных сертификатов операционной системы

    Вызов truststore.inject_into_ssl() при запуске позволяет requests проверять сертификаты средствами ОС, поэтому корневые сертификаты, развёрнутые ИТ-отделом, работают без сопровождения отдельных пакетов сертификатов.

    python
    # pip install truststore==0.10.5 — requests then verifies with the OS trust store
    import truststore
    truststore.inject_into_ssl()
    
    import requests
    requests.get("https://api.example.com/")
  4. 4.

    Настройте сессию (Session) один раз

    В приложениях укажите в Session.verify пакет сертификатов с публичными корневыми сертификатами и корневым сертификатом компании и используйте эту сессию повторно.

    python
    import requests
    
    session = requests.Session()
    session.verify = "/etc/ssl/private-ca/corp-ca-bundle.pem"   # public roots + company root
    session.get("https://api.example.com/")

Связанные ошибки

Открыть всю базу ошибок подписей