AppEngine urlfetch проверить сертификат=False / None не соблюдается

в AppEngine developer appserver я получаю такую ошибку:

SSLCertificateError: Invalid and/or missing SSL certificate for URL ...

когда я делаю такую выборку в https сервер с самозаверяющим сертификатом (почти всегда localhost порт-перенаправляется по ssh на виртуальную машину):

result = urlfetch.fetch(url=url, method=method, payload=payload,
                        deadline=DEADLINE, validate_certificate=None)

не следует ожидать сбоев SSL для недействительных сертификатов, где validate_certificate is 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, но я ищу обходной путь.

вот что я попытался обойти это:

  1. добавить сертификат на брелок для входа в систему Mac (работает в браузере, а не с Python)

  2. добавить сертификат app-engine-python/lib/cacerts/cacerts.txt и/или ./lib/cacerts/urlfetch_cacerts.txt (хотя это, вероятно, требует проверки поворота on для его работы, так как это, по-видимому, единственный случай, когда они используются), например,

    $ Эхо >> /usr/местные/доли/приложение-двигатель-питон/Либ/cacerts в/urlfetch_cacerts.txt

    $ в openssl x509-на-тему -в сервере.ЭЛТ >> /usr/местные/доли/приложение-двигатель-питон/Либ/cacerts в/urlfetch_cacerts.txt

  3. отключить проверку SSL HTTPs с помощью PEP-0476 обходной путь, т. е.

    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 больше не является практичным вариантом.

A предпочтительное обходное решение не будет включать исправление кода AppEngine при каждом обновлении appserver разработки.


EDIT

обратите внимание, что встроенные сертификаты Mac OpenSSL хранятся в /System/Library/OpenSSL под SIP/rootlessness, что, откровенно говоря, является болью для мук и стоящей особенностью, чтобы сохранить, если мы можем.

я проверил, что сертификат проверяется с помощью openssl s_client -connect localhost:7500 -CAfile server.pem.

он был добавлен в брелок и в /usr/local/etc/openssl/certs С hash.# формат, в котором хэш происходит от openssl x509 -subject_hash -in server.pem (или доморощенный 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) показывает 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 ссылки на openssl homebrew я побежал:

xcrun otool-L /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_ssl.so

возвращает

./Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-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 / local/etc/openssl / certs

но, очевидно, по какой-то причине python не использует openssl homebrew алгоритм поиска сертификатов.

поэтому я остаюсь в недоумении, почему стандартная библиотека Python не проверяет сертификаты, которые находятся в каталоге OpenSSL, указанном в документах, а также В Связке ключей (в обоих .pem и .p12 форматы, с "всегда доверять" для Secure Sockets Layer (SSL)).

2 ответов


это dev_appserver ошибка вызвана httplib.HTTPSConnection изменение поведения (проверка сертификата включена по умолчанию) в недавнем выпуске Python (я верю 2.7.9).

как ошибка во внутренней dev_appserver код (файл google_appengine/google/appengine/api/urlfetch_stub.py из AppEngine SDK), который запускается независимо от тестируемого приложения, нет никакого способа сделать исправление, которое переживет обновление SDK.

единственное постоянное решение, я думаю, будет включить validate_certificate и добавить CA сертификат к . В качестве временного исправления вы можете исправить urlfetch_stub.py С решение #3.


Я столкнулся с той же проблемой в Windows. Я использовал старую версию Python (2.7). Когда я обновился до Python 2.7.11, проблема ушла.