Подтвердить что ты не робот

Запрос Python, бросающий SSLError

Я работаю над простым script, который включает CAS, проверку безопасности jspring, перенаправление и т.д. Я бы хотел использовать запросы Python Kenneth Reitz, потому что это отличная работа! Тем не менее, CAS требует получить подтверждение через SSL, поэтому мне нужно пройти этот шаг первым. Я не знаю, чего хотят запросы Python? Где должен находиться этот сертификат SSL?

Traceback (most recent call last):
  File "./test.py", line 24, in <module>
  response = requests.get(url1, headers=headers)
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
  File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 209, in request 
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 624, in send
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 300, in _build_response
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
4b9b3361

Ответ 1

Проблема связана с ненадежным сертификатом SSL.

Как и @dirk, упомянутый в предыдущем комментарии, самое быстрое исправление - установка verify=False:

requests.get('https://example.com', verify=False)

Обратите внимание, что это приведет к тому, что сертификат не будет проверен. Это подвергнет ваше приложение угрозам безопасности, таким как атаки "человек посередине".

Конечно, применять суждение. Как уже упоминалось в комментариях, это может быть приемлемо для быстрых/одноразовых приложений/скриптов, но на самом деле не должно переходить на производственное программное обеспечение.

Если просто пропустить проверку сертификата в вашем конкретном контексте неприемлемо, рассмотрите следующие варианты, лучше всего установить параметр verify в строку, которая является путем к файлу .pem сертификата (который следует получить каким-то безопасным способом).

Таким образом, начиная с версии 2.0, параметр verify принимает следующие значения с соответствующей семантикой:

  • True: вызывает проверку сертификата по отношению к собственным доверенным центрам сертификатов библиотеки (Примечание: вы можете увидеть, какие запросы корневых сертификатов используются через библиотеку Certifi, базу данных доверенных сертификатов RC, извлеченную из запросов: Certifi - база данных доверия для людей).
  • False: полностью обходит проверку сертификата.
  • Путь к файлу CA_BUNDLE для запросов, используемых для проверки сертификатов.

Источник: Запросы - проверка SSL-сертификата

Также взгляните на параметр cert в той же ссылке.

Ответ 2

Из запросов документация по проверке SSL:

Запросы могут проверять SSL-сертификаты для HTTPS-запросов, как и веб-браузер. Чтобы проверить SSL-сертификат хостов, вы можете использовать аргумент проверки:

>>> requests.get('https://kennethreitz.com', verify=True)

Если вы не хотите проверять свой сертификат SSL, сделайте verify=False

Ответ 3

Имя файла CA, которое вы можете использовать, можно передать через verify:

cafile = 'cacert.pem' # http://curl.haxx.se/ca/cacert.pem
r = requests.get(url, verify=cafile)

Если вы используете verify=True, то requests использует свой собственный набор CA, у которого может не быть CA, который подписал ваш сертификат сервера.

Ответ 4

$ pip install -U requests[security]

  • Протестировано на Python 2.7.6 @Ubuntu 14.04.4 LTS
  • Протестировано на Python 2.7.5 @MacOSX 10.9.5 (Mavericks)

Когда этот вопрос был открыт (2012-05), версия запросов была 0.13.1. В версии 2.4.1 (2014-09) были введены дополнительные функции "безопасности" с использованием пакета certifi, если он доступен.

Прямо сейчас (2016-09) основной версией является 2.11.1, которая хорошо работает без verify=False. Нет необходимости использовать requests.get(url, verify=False), если установлено с requests[security] дополнениями.

Ответ 5

Я столкнулся с той же проблемой, и сертификат ssl подтвердил ошибку при использовании aws boto3, просмотрев код boto3, я обнаружил, что REQUESTS_CA_BUNDLE не установлен, поэтому я исправил оба вопроса, установив его вручную:

from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')

Для aws-cli, я полагаю, что установка REQUESTS_CA_BUNDLE в ~/.bashrc устранит эту проблему (не проверена, потому что мой aws-cli работает без нее).

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE

Ответ 6

Если у вас есть библиотека, которая полагается на requests, и вы не можете изменить путь проверки (например, с помощью pyvmomi), вам придется найти cacert.pem в комплекте с запросами и добавить свой ЦС. Вот общий подход к поиску местоположения cacert.pem:

окна

C:\>python -c "import requests; print requests.certs.where()"
c:\Python27\lib\site-packages\requests-2.8.1-py2.7.egg\requests\cacert.pem

Linux

#  (py2.7.5,requests 2.7.0, verify not enforced)
[email protected]:~/# python -c "import requests; print requests.certs.where()"
/usr/lib/python2.7/dist-packages/certifi/cacert.pem

#  (py2.7.10, verify enforced)
[email protected]:~/# python -c "import requests; print requests.certs.where()"
/usr/local/lib/python2.7/dist-packages/requests/cacert.pem

кстати. @request-devs, связывая ваши собственные cacerts с запросом, действительно, очень раздражает... особенно тот факт, что вы, похоже, не используете систему ca store, и это нигде не документировано.

Обновление

в ситуациях, когда вы используете библиотеку и не имеете контроля над местоположением ca-bundle, вы также можете явно указать местоположение ca-bundle в качестве своего часового пакета:

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt python -c "import requests; requests.get('https://somesite.com';)"

Ответ 7

Я сталкиваюсь с той же проблемой, используя gspread, и эти команды работают для меня:

sudo pip uninstall -y certifi
sudo pip install certifi==2015.04.28

Ответ 8

Если вы хотите удалить предупреждения, используйте приведенный ниже код.

import urllib3

urllib3.disable_warnings()

и verify=False с помощью метода request.get или post

Ответ 9

Я нашел конкретный подход для решения подобной проблемы. Идея указывает на файл cacert, хранящийся в системе и используемый другими приложениями на основе ssl.

В Debian (я не уверен, что он такой же в других дистрибутивах) файлы сертификатов (.pem) хранятся в /etc/ssl/certs/ Итак, это код, который работает для меня:

import requests
verify='/etc/ssl/certs/cacert.org.pem'
response = requests.get('https://lists.cacert.org', verify=verify)

Чтобы угадать, что выбрать pem, я просматриваю URL-адрес и проверяю, какой сертификат (CA) сгенерировал сертификат.

EDIT: если вы не можете отредактировать код (потому что вы используете третье приложение), вы можете попробовать добавить сертификат pem непосредственно в /usr/local/lib/python2.7/dist-packages/requests/cacert.pem (например, скопировать его в конец файла).

Ответ 10

Если вы не беспокоитесь о сертификате, просто используйте verify=False.

import requests

url = "Write your url here"

returnResponse = requests.get(url, verify=False)

Ответ 11

После нескольких часов отладки я мог заставить это работать только с помощью следующих пакетов:

requests[security]==2.7.0  # not 2.18.1
cryptography==1.9  # not 2.0

с помощью OpenSSL 1.0.2g 1 Mar 2016

Без этих пакетов verify=False не работал.

Я надеюсь, что это поможет кому-то.

Ответ 12

Я столкнулся с той же проблемой. Оказывается, я не установил промежуточный сертификат на своем сервере (просто добавьте его в конец вашего сертификата, как показано ниже).

https://www.digicert.com/ssl-support/pem-ssl-creation.htm

Убедитесь, что у вас установлен пакет ca-сертификатов:

sudo apt-get install ca-certificates

Обновление времени также может решить следующее:

sudo apt-get install ntpdate
sudo ntpdate -u ntp.ubuntu.com

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

Ответ 13

Если вызовы запросов скрыты где-то глубоко в коде, и вы не хотите устанавливать сертификат сервера, то только для отладки только можно выполнить запросы monkeypatch:

import requests.api
import warnings


def requestspatch(method, url, **kwargs):
    kwargs['verify'] = False
    return _origcall(method, url, **kwargs)

_origcall = requests.api.request
requests.api.request = requestspatch
warnings.warn('Patched requests: SSL verification disabled!')

Никогда не используйте в производстве!

Ответ 14

Я боролся с этой проблемой за ЧАСЫ.

Я пытался обновлять запросы. Затем я обновил certifi. Я указал проверить certifi.where() (код делает это по умолчанию в любом случае). Ничего не получилось.

Наконец, я обновил мою версию python до python 2.7.11. Я был на Python 2.7.5, который имел некоторые несовместимости с тем, как проверяются сертификаты. Как только я обновил Python (и несколько других зависимостей), он начал работать.

Ответ 15

В модуле запросов в данный момент возникает проблема, вызывающая эту ошибку, представленную в v2.6.2 - v2.12.4 (ATOW): https://github.com/kennethreitz/requests/issues/2573

Обходной путь для этой проблемы заключается в добавлении следующей строки: requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'

Ответ 16

Как уже упоминалось @Rafael Almeida, проблема, с которой вы столкнулись, вызвана ненадежным сертификатом SSL. В моем случае сертификат SSL был не доверен моему серверу. Чтобы обойти это без ущерба для безопасности, я скачал сертификат и установил его на сервере (просто дважды щелкнув файл .crt, а затем установил сертификат...).

Ответ 17

Я полагаю, слишком поздно для вечеринки, но я хотел вставить исправление для таких странников, как я! Так что на Python 3.7.x у меня сработало следующее

Введите следующее в своем терминале

pip install --upgrade certifi      # hold your breath..

Попробуйте снова запустить скрипт/запросы и посмотреть, работает ли он (я уверен, что он еще не будет исправлен!). Если это не сработало, попробуйте выполнить следующую команду непосредственно в терминале

open /Applications/Python\ 3.6/Install\ Certificates.command  # please replace 3.6 here with your suitable python version

Ответ 18

Это похоже на ответ @rafael-almeida, но я хочу отметить, что по состоянию на запросы 2. 11+ нет 3 значений, которые может принять verify, на самом деле 4:

  • True: проверяет на соответствие запросам внутренних доверенных ЦС.
  • False: полностью обходит проверку сертификата. (Не рекомендуется)
  • Путь к файлу CA_BUNDLE. запросы будут использовать это для проверки сертификатов сервера.
  • Путь к каталогу, содержащему открытые файлы сертификатов. запросы будут использовать это для проверки сертификатов сервера.

Остальная часть моего ответа о # 4, как использовать каталог, содержащий сертификаты для проверки:

Получите необходимые публичные сертификаты и поместите их в каталог.

Строго говоря, вы, вероятно, "должны" использовать внеполосный метод получения сертификатов, но вы также можете просто загрузить их с помощью любого браузера.

Если сервер использует цепочку сертификатов, обязательно получите каждый отдельный сертификат в цепочке.

Согласно документации по запросам, каталог, содержащий сертификаты, должен сначала обрабатываться утилитой rehash (openssl rehash).

(Для этого требуется openssl 1.1. 1+, и не все реализации Windows openssl поддерживают перефразирование. Если openssl rehash не будет работать для вас, вы можете попробовать запустить скрипт rehash ruby на https://github.com/ruby/openssl/blob/master/sample/c_rehash.rb, хотя я не пробовал этого.)

У меня были некоторые проблемы с получением запросов на распознавание моих сертификатов, но после того, как я использовал команду openssl x509 -outform PEM для преобразования сертификатов в формат Base64 .pem, все работало отлично.

Вы также можете просто сделать перефразировку:

try:
    # As long as the certificates in the certs directory are in the OS certificate store, 'verify=True' is fine.
    return requests.get(url, auth=auth, verify=True)
except requests.exceptions.SSLError:
    subprocess.run(f"openssl rehash -compat -v my_certs_dir", shell=True, check=True)
    return requests.get(url, auth=auth, verify="my_certs_dir")

Ответ 19

Невозможно добавить опции, если запросы вызывают из другого пакета. В этом случае добавление сертификатов в пакет cacert является прямым путем, например. Мне пришлось добавить "StartCom Class 1 Primary Intermediate Server CA", для которого я загрузил корневой сертификат в StartComClass1.pem. поскольку мой virtualenv называется caldav, я добавил сертификат с помощью:

cat StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/pip/_vendor/requests/cacert.pem
cat temp/StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/requests/cacert.pem

одного из них может быть достаточно, я не проверял

Ответ 20

У меня была аналогичная или одна и та же проблема проверки сертификатов. Я читал, что версии OpenSSL меньше 1.0.2, запросы которых иногда зависят от проверки сильных сертификатов (см. здесь). CentOS 7, похоже, использует 1.0.1e, который, похоже, имеет проблему.

Я не был уверен, как обойти эту проблему на CentOS, поэтому я решил разрешить более слабые лицензии на 1024 бит CA.

import certifi # This should be already installed as a dependency of 'requests'
requests.get("https://example.com", verify=certifi.old_where())

Ответ 21

Мне пришлось обновить Python 3.4.0 до 3.4.6

pyenv virtualenv 3.4.6 myvenv
pyenv activate myvenv
pip install -r requirements.txt

Ответ 22

В моем случае причина была довольно тривиальной.

Я знал, что проверка SSL работала несколько дней назад и фактически работала на другом компьютере.

Следующим моим шагом было сравнение содержимого и размера сертификата между машиной, на которой работала проверка, и той, на которой ее не было.

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