在AppEngine开发人员应用程序服务器中,我收到如下错误:
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
虽然这很可能是Python中2.7.9策略的副作用,总是验证ssl证书。
注意通过 False
(代替 None
)为 validate_certificate
也不起作用。
这个问题在Python 2.7.9-10上通过OS X 10.10.2-4上的Homebrew / XCode以及AppEngine 1.9.18到1.19.26发生。
存在问题(例如 12096)关于谷歌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
禁用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降级不再是一个实用的选择。
每次更新开发应用程序服务器时,更好的解决方法都不会涉及对AppEngine代码进行猴子修补。
编辑
请注意,Mac内置OpenSSL证书存储在 /System/Library/OpenSSL
,受到保护 SIP /无所归依如果可以的话,坦白地说这是一种痛苦的事情,并且值得保留。
我已验证证书通过使用验证 openssl s_client -connect localhost:7500 -CAfile server.pem
。
它被添加到Keychain和 /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
是一个虚拟的环境 help(ssl)
显示一个 FILE
的 /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py
进一步验证自制软件的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
返回
./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(compatibility版本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的/证书
但显然由于某种原因,python没有使用自制软件的openssl算法来查找证书。
所以我仍然不知道为什么Python标准库没有验证文档中指定的OpenSSL目录中的证书以及Keychain(两者都在 .pem
和 .p12
格式,“永远信任” Secure Sockets Layer (SSL)
)。