Error de verificación del certificado SSL3_GET_SERVER_CERTIFICATE en Python al solicitar(solo)*.google.com
python-requests (1)
Encontré una solución. Parece que hay un problema importante en la versión de certifi
que se estaba ejecutando. Descubrí esto de este (muy largo) problema de GitHub: https://github.com/certifi/python-certifi/issues/26
TL; DR
pip uninstall -y certifi && pip install certifi==2015.04.28
Me he encontrado con un error realmente extraño que tiene que ver con SSL y python para google.com (o más generalmente creo que con dominios que tienen múltiples cadenas de certificados). Cuando intento realizar una solicitud a https://*.google.com/whatever
, https://*.google.com/whatever
el siguiente error:
SSLError: ("bad handshake: Error([(''SSL routines'', ''SSL3_GET_SERVER_CERTIFICATE'', ''certificate verify failed'')],)",) while doing GET request to URL: https://google.com/
Lo que he hecho hasta ahora.
He pasado por muchos problemas tratando de hacer que esto funcione y estoy recurriendo a publicar en Stack Overflow ahora que no sé qué hacer. Esto es lo que he intentado:
Noté que la
date
devolvió una fecha que estaba 2 minutos por detrás del tiempo real (potencialmente invalidando mi certificado). Arreglé esto asumiendo que validaría el certificado. Esto no solucionó el problema.Descubrí que Python 2.7.9 realizó una copia de respaldo de algunas bibliotecas SSL de Python 3. Actualicé Python 2.7.6 a 2.7.9 asumiendo las actualizaciones (que incluyen las correcciones enumeradas en este hilo: https://serverfault.com/questions/692110/error-with-python2-as-a-https-client-with-an-nginx-server-and-ssl-certificate-ch ) lo arreglaría. Sin suerte, el mismo error.
Obviamente, establecer
verify=False
funciona, pero no estamos dispuestos a ceder a la seguridad, necesitamosverify=True
para que funcione.curl https://google.com
también funciona como se esperaba. Así es como sé que tiene que ver con Python.
Ambiente
$ python -V
Python 2.7.9
$ pip list | grep -e requests
requests (2.9.1)
$ uname-a # ubuntu 14.04
Linux staging.example.com 3.13.0-48-generic #80-Ubuntu SMP Thu Mar 12 11:16:15 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Ejemplo
Esto solo está sucediendo para los dominios de google sobre https. Aquí hay un ejemplo:
$ ipython
Python 2.7.9 (default, Jan 6 2016, 21:37:32)
Type "copyright", "credits" or "license" for more information.
IPython 4.0.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython''s features.
%quickref -> Quick reference.
help -> Python''s own help system.
object? -> Details about ''object'', use ''object??'' for extra details.
In [1]: import requests
In [2]: requests.get(''https://facebook.com'', verify=True)
Out[2]: <Response [200]>
In [3]: requests.get(''https://stackoverflow.com'', verify=True)
Out[3]: <Response [200]>
In [4]: requests.get(''https://spotify.com'', verify=True)
Out[4]: <Response [200]>
In [5]: requests.get(''http://google.com'', verify=True) # notice the http
Out[5]: <Response [200]>
In [6]: requests.get(''https://google.com'', verify=True)
---------------------------------------------------------------------------
SSLError Traceback (most recent call last)
<ipython-input-6-a7fff1831944> in <module>()
----> 1 requests.get(''https://google.com'', verify=True)
/example/.virtualenv/example/lib/python2.7/site-packages/requests/api.pyc in get(url, params, **kwargs)
65
66 kwargs.setdefault(''allow_redirects'', True)
---> 67 return request(''get'', url, params=params, **kwargs)
68
69
/example/.virtualenv/example/lib/python2.7/site-packages/requests/api.pyc in request(method, url, **kwargs)
51 # cases, and look like a memory leak in others.
52 with sessions.Session() as session:
---> 53 return session.request(method=method, url=url, **kwargs)
54
55
/example/.virtualenv/example/lib/python2.7/site-packages/requests/sessions.pyc in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
466 }
467 send_kwargs.update(settings)
--> 468 resp = self.send(prep, **send_kwargs)
469
470 return resp
/example/.virtualenv/example/lib/python2.7/site-packages/requests/sessions.pyc in send(self, request, **kwargs)
574
575 # Send the request
--> 576 r = adapter.send(request, **kwargs)
577
578 # Total elapsed time of the request (approximately)
/example/.virtualenv/example/lib/python2.7/site-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
445 except (_SSLError, _HTTPError) as e:
446 if isinstance(e, _SSLError):
--> 447 raise SSLError(e, request=request)
448 elif isinstance(e, ReadTimeoutError):
449 raise ReadTimeout(e, request=request)
SSLError: ("bad handshake: Error([(''SSL routines'', ''SSL3_GET_SERVER_CERTIFICATE'', ''certificate verify failed'')],)",)