複数の URL からアクセスできる Web サイトがあり、そのうち 2 つは SSL SNI を使用して提供される SSL 証明書を持っています (全体は nginx を使用して提供されます)。
このセットアップは、両方の証明書が有効である限り、ブラウザーと Web サイトを監視する Python 2.7.11 コードで正常に機能しました。
最近、証明書の 1 つが期限切れになりました。これは、何にも使用されていないものです (受信トラフィックにも監視にも使用されていません)。これは、Web サイトにアクセスするブラウザーには影響しませんでしたが、監視用の Python スクリプトで次のようなエラーが発生し始めました。
2016-12-24 02:09:49,351 - foo.__main__(140582120666944) - app_monitoring.py:90 - ERROR - Call to <lambda> Failed 1 times
Traceback (most recent call last):
File "devops/monitoring/app_monitoring.py", line 88, in call_with_retry
func(*args, **kwargs)
File "devops/monitoring/app_monitoring.py", line 116, in <lambda>
test_func=lambda: yapi_calls.test_api_on_all_datasets(Flags.yapi_url)),
File "/usr/src/app/system_tests/yapi_calls.py", line 158, in test_api_on_all_datasets
datasets = send(yapi_url, 'list_datasets', {})
File "/usr/src/app/system_tests/yapi_calls.py", line 48, in send
return gcloud.get_yapi(yapi_url).execute(api_call, req)
File "/usr/src/app/cloudapi/yapi.py", line 23, in execute
return self._execute(api_call, req, True)
File "/usr/src/app/cloudapi/yapi.py", line 36, in _execute
headers=headers)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 631, in new_request
redirections, connection_type)
File "/usr/local/lib/python2.7/dist-packages/httplib2/__init__.py", line 1609, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/usr/local/lib/python2.7/dist-packages/httplib2/__init__.py", line 1351, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/usr/local/lib/python2.7/dist-packages/httplib2/__init__.py", line 1272, in _conn_request
conn.connect()
File "/usr/local/lib/python2.7/dist-packages/httplib2/__init__.py", line 1059, in connect
raise SSLHandshakeError(e)
SSLHandshakeError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
注: 有効な証明書が 1 つと期限切れの証明書が 1 つあります。問題は、有効な証明書を使用して URL を通過しても、期限切れの証明書が原因で例外がスローされることです。
で確認しrequests
たところ、期限切れの URL にアクセスすると予期される SSL エラーが発生しましたが、「適切な」URL に問題なくアクセスできました。したがって、これは SNI 証明書の httplib2 処理に固有の問題であると思われます。
残念ながら、requests
これは外部ライブラリであるため、このフローで切り替えることはできません (スタック トレースに表示されるように - oauth2client
)。
新しい有効な SNI 証明書をインストールする (または非 SNI 証明書に切り替える) 以外に、これについて他にできることはありますか?
更新: この場合に有効な回避策を見つけました。
nginx で SSL SNI を提供する場合、デフォルトの証明書を設定する必要があります。この場合、デフォルトの証明書は有効期限が切れたものであることがわかりました。デフォルトの証明書を有効なものに変更すると、エラーはなくなりました。
この回避策により、httplib2 SSL SNI 実装にバグがあると思われます。要求されたドメインの証明書でなくても、デフォルトの証明書の検証が必要なようです。