在AppEngine开发人员应用程序服务器中,我收到如下错误:
SSLCertificateError: Invalid and/or missing SSL certificate for URL ...
当我使用自签名证书(几乎总是https
通过ssh端口转发到vm)对localhost
服务器进行此类提取时:
result = urlfetch.fetch(url=url, method=method, payload=payload,
deadline=DEADLINE, validate_certificate=None)
人们不会指望validate_certificate
为False
的无效证书的SSL失败,尽管这很可能是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发生。
Google App Engine上存在一些问题(例如12096),但我正在寻找解决方法。
以下是我试图解决的问题:
将证书添加到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
使用PEP-0476解决方法禁用ssl HTTPs检查,即
ssl._create_default_https_context = ssl._create_unverified_context
import ssl
/System/Library/OpenSSL
之后或之后(第1149行左右)
醇>
这在Mac上尤其成问题,因为从XCode 7 / OS X El Capital降级不再是一个实用的选择。
每次更新开发应用服务器时,更好的解决方法都不会涉及对AppEngine代码进行猴子修补。
修改
请注意,Mac内置的OpenSSL证书存储在openssl s_client -connect localhost:7500 -CAfile server.pem
中,受google/appengine/dist27/python_std_lib/httplib.py
保护,如果可以的话,坦率地说这很麻烦,值得保留。
我已验证证书是否使用/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
链接到自制程序的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
返回
./地窖/蟒/ 2.7.10_2 /框架/ Python.framework /版本/ 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 /本地/ etc / OpenSSL的/证书
但显然由于某种原因,python没有使用自制程序的openssl算法来查找证书。
所以我仍然不知道为什么Python标准库没有验证文档中指定的OpenSSL目录中的证书以及Keychain(.pem
和.p12
格式,与"始终信任"对于Secure Sockets Layer (SSL)
)。
答案 0 :(得分:8)
这是由dev_appserver
行为更改(默认情况下启用证书检查)导致的httplib.HTTPSConnection
错误,在最近的一些Python版本中(我相信2.7.9)。
由于错误发生在独立于测试应用程序运行的内部dev_appserver
代码(appengine SDK的文件google_appengine/google/appengine/api/urlfetch_stub.py
)中,因此无法在SDK更新后继续进行修复
我能想到的唯一永久性解决方法是启用validate_certificate
并将 CA 证书添加到urlfetch_cacerts.txt
文件中。作为临时修复,您可以使用解决方法#3修补urlfetch_stub.py
。
答案 1 :(得分:1)
我在Windows上遇到了同样的问题。我使用的是旧版本的Python(2.7)。当我升级到Python 2.7.11时,问题就消失了。
答案 2 :(得分:0)
就我而言,解决此问题的解决方法是将... / google-cloud-sdk / platform / lib / third_party / fancy_urllib文件夹复制到项目文件夹。
在_SetupSSL中哭泣urlfetch_stub.py哭泣,导入fancy_urllib调用 ImportError:没有名为fancy_urllib的模块
SW: