11

AppEngine 開発者 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_certificateFalse、これは Python の 2.7.9 ポリシーが常に ssl 証明書を検証することの副作用である可能性が非常に高いです。

False(の代わりにNone) forを渡すことvalidate_certificateも機能しないことに注意してください。

この問題は、AppEngine 1.9.18 ~ 1.19.26 を搭載した OS X 10.10.2-4 上の Homebrew/XCode を介して Python 2.7.9-10 で発生します。

Google App Engine ではこれに関する問題 (例: 12096 ) がありますが、回避策を探しています。

これを回避するために私が試みたのは次のとおりです。

  1. 証明書を Mac のログイン キーチェーンに追加します (Python からではなく、ブラウザーで機能します)。

  2. app-engine-python/lib/cacerts/cacerts.txt証明書をand/orに追加します(ただし、これが機能する./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(1149行目あたり)google/appengine/dist27/python_std_lib/httplib.py

XCode 7/OS X El Capital の時点でのダウングレードは実用的なオプションではなくなったため、これは Mac では特に問題になります。

推奨される回避策は、開発アプリケーション サーバーが更新されるたびに適切な AppEngine コードにモンキー パッチを適用しないことです。


編集

Mac 組み込みの OpenSSL 証明書は、 SIP/rootlessness/System/Library/OpenSSLで保護されている に保存されていることに注意してください。これは、率直に言って、いじるのが面倒で、できれば維持する価値のある機能です。

を使用して、証明書が有効であることを確認しましたopenssl s_client -connect localhost:7500 -CAfile server.pem

これは、キーチェーンに追加され、ハッシュが由来する形式/usr/local/etc/openssl/certs(または自作の ssl、つまり) に追加されました。その場合、証明書を検証します (ただし、python は検証しません)。hash.#openssl x509 -subject_hash -in server.pem/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 と 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

_ssl.so自作のPythonの自作の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 (互換バージョン 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アルゴリズムを使用していません。

そのため、ドキュメントとキーチェーンで指定された OpenSSL ディレクトリにある証明書を Python 標準ライブラリが検証しない理由について、私は途方に暮れています ( と の両方.pem.p12形式で、 を「常に信頼」しSecure Sockets Layer (SSL)ます)。

4

3 に答える 3

8

これは、いくつかの最近の Python リリース (私は 2.7.9 を信じています) での動作変更 (デフォルトで証明書チェックがオンになっている) によってdev_appserver引き起こされたバグです。httplib.HTTPSConnection

バグは、テストされたアプリケーションとは独立して実行される内部dev_appserverコード ( google_appengine/google/appengine/api/urlfetch_stub.pyappengine SDK のファイル) にあるため、SDK の更新後も存続する修正を行う方法はありません。

私が考えることができる唯一の永続的な回避策は、 CA証明書を有効にしてファイルにvalidate_certificate追加することです。一時的な修正として、回避策 #3 でパッチを適用できます。urlfetch_cacerts.txturlfetch_stub.py

于 2015-09-30T01:14:53.443 に答える
1

Windowsでも同じ問題に遭遇しました。古いバージョンの Python (2.7) を使用していました。Python 2.7.11 にアップグレードすると、問題はなくなりました。

于 2016-06-11T21:37:52.187 に答える