В AppEngine Developer appserver появляется такая ошибка:
SSLCertificateError: Invalid and/or missing SSL certificate for URL ...
когда я делаю выборку на сервере https
с самозаверяющим сертификатом (почти всегда localhost
переадресация через ssh на vm):
result = urlfetch.fetch(url=url, method=method, payload=payload,
deadline=DEADLINE, validate_certificate=None)
Нельзя ожидать отказов SSL для недействительных сертификатов, где validate_certificate
- False
, хотя это, возможно, является побочным эффектом политики 2.7.9 в Python, чтобы всегда проверять сертификаты ssl.
Обратите внимание, что передача False
(вместо None
) для validate_certificate
тоже не работает.
Эта проблема возникает на Python 2.7.9-10 через Homebrew/XCode на OS X 10.10.2-4 с AppEngine с 1.9.18 по 1.19.26.
Есть проблемы (например, 12096) об этом в Google App Engine, но я ищу обходной путь.
Вот что я пытался обойти это:
-
Добавить сертификат в цепочку ключей для входа в Mac (работает в браузере, а не с Python)
-
Добавьте сертификат в
app-engine-python/lib/cacerts/cacerts.txt
и/или./lib/cacerts/urlfetch_cacerts.txt
(хотя для его работы, вероятно, потребуется включить проверку, так как это единственный случай, когда они используются), например,$echo → /usr/local/share/app-engine-python/lib/cacerts/urlfetch_cacerts.txt
$openssl x509 -subject -in server.crt → /usr/local/share/app-engine-python/lib/cacerts/urlfetch_cacerts.txt
-
Отключить HTTP-проверки ssl с помощью PEP-0476 обходной путь i.e.
ssl._create_default_https_context = ssl._create_unverified_context
после или после
import ssl
(вокруг строки 1149)google/appengine/dist27/python_std_lib/httplib.py
Это особенно проблематично для Mac с момента понижения с XCode 7/OS X El Capital больше не является практическим вариантом.
Предпочтительное обходное решение не будет включать в себя обезвреживание исправления кода AppEngine каждый раз при обновлении сервера приложений разработки.
ИЗМЕНИТЬ
Обратите внимание, что встроенные сертификаты OpenSSL, хранящиеся в Mac, хранятся в /System/Library/OpenSSL
, который защищен SIP/rootlessness, что, откровенно говоря, является болью для гашения и стоящим чтобы сохранить, если можно.
Я проверил, что сертификат проверяется с помощью openssl s_client -connect localhost:7500 -CAfile server.pem
.
Он добавлен в Keychain и в /usr/local/etc/openssl/certs
с форматом hash.#
, где хеш происходит от openssl x509 -subject_hash -in server.pem
(или homebrew ssl, а именно /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl
). В этом случае /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl s_client -connect localhost:7500
проверяет сертификат (но python все еще не делает).
Я попытался использовать домашнюю версию python и openssl, но безрезультатно. Выполнение следующего в Python, похоже, всегда терпит неудачу;
./pve/bin/python -c "import requests; requests.get('https://localhost:7500')"
Это также не выполняется, если SSL_CERT_FILE
установлен на сертификат сервера (т.е. для дополнительной меры можно ожидать, что он будет работать, поскольку команда openssl
по существу работает так), а также не выполняется, если SSL_CERT_PATH
установлен на /usr/local/etc/openssl/certs
.
Примечание. pve
является виртуальным env, где help(ssl)
показывает a FILE
of /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py
Дальнейшая проверка того, что homebrew Python _ssl.so
ссылки на homebrew openssl Я побежал:
xcrun otool -L /usr/local/Cellar/python/ 2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_ssl.so
который возвращает
./подвал/Python/2.7.10_2/Каркасы/Python.framework/Версии/2,7/Library/python2.7/Библиотека-dynload/_ssl.so:
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib(версия совместимости 1.0.0, текущая версия 1.0.0)
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib(версия совместимости 1.0.0, текущая версия 1.0.0)
/usr/lib/libSystem.B.dylib(версия совместимости 1.0.0, текущая версия 1225.1.1)
Если вы выполняете brew info openssl
, он замечает в CAVEATS
:
Файл CA загрузился с использованием сертификатов из системы Брелок. Чтобы добавить дополнительные сертификаты, поместите файлы .pem в /USR/ локальные/и т.д./OpenSSL/сертификаты
но явно по какой-то причине python не использует алгоритм opensl homebrew для поиска сертификатов.
Итак, я не понимаю, почему стандартная библиотека Python не проверяет сертификаты, которые находятся в каталоге OpenSSL, указанном в документах, так и в цепочке ключей (в форматах .pem
и .p12
), при этом "всегда доверять" "для Secure Sockets Layer (SSL)
).