Запросы Python - Как использовать системные ca-сертификаты (debian/ubuntu)?
Я установил самозаверяющий root ca cert в debian /usr/share/ca-certificates/local
и установил их с помощью sudo dpkg-reconfigure ca-certificates
. На данный момент true | gnutls-cli mysite.local
счастлив, а true | openssl s_client -connect mysite.local:443
счастлив, но модуль запросов python2 и python3 настаивает, что он не доволен сертификатом.
python2:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 70, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 497, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)
python3
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/bin/python3.5/site-packages/requests/api.py", line 70, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/bin/python3.5/site-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/bin/python3.5/site-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/bin/python3.5/site-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/bin/python3.5/site-packages/requests/adapters.py", line 497, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)
Почему python игнорирует пакет ca-сертификатов системы и как его интегрировать?
Ответы
Ответ 1
Из fooobar.com/questions/97505/...
Чтобы сделать запросы python использовать пакет ca-сертификатов системы, нужно сказать, чтобы использовать его по своему встроенному пакету
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
Запросы вставляют свои связки здесь, для справки:
/usr/local/lib/python2.7/site-packages/requests/cacert.pem
/usr/lib/python3/dist-packages/requests/cacert.pem
Ответ 2
Я боролся с этим в течение недели или около того недавно. Наконец-то я нашел способ проверить самоподписанный или подписанный лично сертификат в Python. Вам нужно создать свой собственный файл пакета сертификатов. Нет необходимости обновлять неизвестные пакеты сертификатов при каждом обновлении библиотеки или добавлении чего-либо в системное хранилище сертификатов.
Начните с запуска команды openssl, которую вы запускали ранее, но добавьте -showcerts. openssl s_client -connect mysite.local:443 -showcerts
Это даст вам длинный вывод, а вверху вы увидите всю цепочку сертификатов. Обычно это три сертификата, сертификат веб-сайта, промежуточный сертификат и корневой сертификат в указанном порядке. Нам нужно поместить только корневой и промежуточный сертификаты в следующий файл в обратном порядке.
Скопируйте последний сертификат, корневой сертификат, в новый текстовый файл. Возьмите только то, что между, и в том числе:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Скопируйте средний сертификат (он же промежуточный сертификат) в новый текстовый файл под корневым сертификатом. Снова, возьмите строки Начального и Конечного сертификата и все, что между ними.
Сохраните этот текстовый файл в каталог, где находится ваш скрипт Python. Я рекомендую называть его CertBundle.pem
. (Если вы дадите ему другое имя или поместите его где-нибудь еще в структуре вашей папки, убедитесь, что строка проверки отражает это.) Обновите ваш скрипт, чтобы он ссылался на новый пакет сертификатов:
response = requests.post("https://www.example.com/", headers=headerContents, json=bodyContents, verify="CertBundle.pem")
И это оно. Если у вас есть только корневой или только промежуточный сертификат, то Python не сможет проверить всю цепочку сертификатов. Но если вы включите оба сертификата в созданный вами комплект сертификатов, то Python может проверить, что промежуточное звено было подписано корнем, а затем при доступе к веб-сайту он может проверить, что сертификат веб-сайта был подписан промежуточным сертификатом.,
редактировать: исправлено расширение файла для комплекта сертификатов. Также исправлена пара грамматических ошибок.
Ответ 3
Передача сертификатных кортежей должна работать:
certificate_path = os.path.join(CERT_PATH, 'cacert.pem')
certificate_key_path = os.path.join(CERT_PATH, 'cacert.key')
re = requests.get(next_url, cert=(certificate_path, certificate_key_path))
Я использую этот подход;)