AppEngine urlfetch validate_certificate = False / None未被遵守

时间:2015-03-04 23:00:38

标签: python google-app-engine ssl-certificate urllib2 google-app-engine-python

在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_certificateFalse的无效证书的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),但我正在寻找解决方法。

以下是我试图解决的问题:

  1. 将证书添加到Mac的登录密钥链(在浏览器中工作,而不是从Python工作)

  2. 将证书添加到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

  3. 使用PEP-0476解决方法禁用ssl HTTPs检查,即

    ssl._create_default_https_context = ssl._create_unverified_context

    import ssl

  4. /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))。

3 个答案:

答案 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:

  • Ubuntu 18.04
  • Python 2.7.17 / 2.7.12
  • Google Cloud SDK 319.0.0