Httpie: HTTPie ignora los certificados del sistema

Creado en 9 jun. 2016  ·  20Comentarios  ·  Fuente: httpie/httpie

HTTPie ignora los certificados del sistema

http --debug -j https://example_using_my_ca.com

HTTPie 0.9.3
HTTPie data: /home/lukas/.httpie
Requests 2.10.0
Pygments 1.6
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] linux

>>> requests.request(**{'allow_redirects': False,
 'auth': None,
 'cert': None,
 'data': '',
 'files': DataDict(),
 'headers': {'Accept': b'application/json',
             'Content-Type': b'application/json',
             'User-Agent': b'HTTPie/0.9.3'},
 'method': 'get',
 'params': ParamsDict(),
 'proxies': {},
 'stream': True,
 'timeout': 30,
 'url': 'https://example_using_my_ca.com',
 'verify': True})

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 578, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 351, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 814, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py", line 289, in connect
    ssl_version=resolved_ssl_version)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/ssl_.py", line 308, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib/python3.4/ssl.py", line 365, in wrap_socket
    _context=self)
  File "/usr/lib/python3.4/ssl.py", line 601, in __init__
    self.do_handshake()
  File "/usr/lib/python3.4/ssl.py", line 828, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 403, in send
    timeout=timeout
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 604, in urlopen
    raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/http", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.4/dist-packages/httpie/core.py", line 115, in main
    response = get_response(args, config_dir=env.config.directory)
  File "/usr/local/lib/python3.4/dist-packages/httpie/client.py", line 48, in get_response
    response = requests_session.request(**kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 585, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 477, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

Como referencia, curl funciona bien: curl https://example_using_my_ca.com

bug

Todos 20 comentarios

¿Tendría sentido usar ssl.get_default_verify_paths () para obtener las rutas predeterminadas?

Propondría el siguiente comportamiento:

Si a --verify se le pasa un parámetro que no sea no o yes, pasa el parámetro a las solicitudes.

Si --verify se establece en yes:
1) si REQUESTS_CA_BUNDLE está configurado, pase True para verificar las solicitudes.
2) se establece la variable de entorno elif ssl.get_default_verify_paths (). Openssl_cafile_env, páselo a las solicitudes de verificación
4) la variable de entorno elif ssl.get_default_verify_paths (). Openssl_capath_env está configurada para pasar eso a las solicitudes de verificación
5) elif ssl.get_default_verify_paths (). Capath no es None, páselo a las solicitudes de verificación
6) de lo contrario, pase True a las solicitudes de verificación

pero tenga en cuenta que ssl.get_default_verify_paths está disponible solo desde python3.4

@luv no solo está disponible en 3.4+ y 2.7.10+, sino que no funciona en todas las plataformas. Es por eso que las solicitudes están trabajando en su propio problema para resolver esto para las personas. Deje de comentar constantemente sobre httpie. Esta es una preocupación que existe en las solicitudes y no en la OMI de httpie.

@ sigmavirus24 wtf man? No tengo idea de lo que quieres decir con comentar constantemente, pero lo que sea, veo que ni siquiera eres un colaborador de httpie. Asumo que solo un troll estúpido: /

un vistazo rápido al código fuente de curl para ver cómo se ve una implementación funcional ...

Sin tener en cuenta todos esos ifdefs de amiga y VMS y el soporte para muchas bibliotecas ssl diferentes, en realidad es bastante estúpido y no está usando métodos de búsqueda de openssl X509_ * (como, por ejemplo, usado en get_default_verify_paths () en el módulo SSL de Python).

En su lugar, curl simplemente itera sobre un montón de ubicaciones conocidas en el momento de la compilación (consulte este m4dness https://github.com/curl/curl/blob/master/acinclude.m4#L2560) y luego admite explícitamente la anulación con (CURL_CA_BUNDLE y ) Variables de entorno SSL_CERT_DIR y SSL_CERT_FILE en tiempo de ejecución (nuevamente sin usar cosas como X509_get_default_cert_file_env ()). Eso es.

Entonces, ¿qué hay de implementar el mismo enfoque en Python puro? (Sí, parece rápido y sucio como el infierno, ¡pero funciona para curl!) Pero agregando soporte para Windows (ssl.enum_certificates?) Y OS X (no estoy seguro aquí, pero Python parece usar la biblioteca openssl proporcionada por Apple en OS X 10.6+ ¡Así que eso ya debería estar bien!).

@luv, gracias por el informe, pero sea más respetuoso con los demás miembros. @ sigmavirus24 es un desarrollador central de solicitudes en las que httpie depende de todo HTTP y sin las cuales ni siquiera existiría, por lo que su punto de vista es extremadamente relevante.

tenga en cuenta que esto no se solucionará en las solicitudes hasta la versión 3.0.0 ... ni siquiera SSL_CERT_FILE será compatible debido a posibles problemas de compatibilidad https://github.com/kennethreitz/requests/pull/2903

por cierto. No quise ser irrespetuoso, realmente pensé que estaba tropezando :) Hice todo lo posible para ayudar a encontrar una solución para un problema y alguien que ni siquiera ha contribuido una vez al proyecto (verifiqué los contribuyentes de HTTPie porque estaba realmente sorprendido por una reacción tan hostil) básicamente me estaba diciendo que me callara: /

@luv No te estaba diciendo que te

Finalmente, las contribuciones de código no son la única contribución a un proyecto. Si desea ver todas las contribuciones en un proyecto, puede usar un proyecto como octohatrack . He respondido a varias solicitudes relacionadas con errores en httpie para @jkbrzt porque no tienen tiempo para seguir el desarrollo de las solicitudes. Cuando veo un error relacionado con las solicitudes aquí, respondo porque el 99% de las veces, ya está siendo tratado. Afortunadamente para @jkbrzt , antes me han tratado mal (y algunas veces peor), así que tengo la piel más gruesa.

Como nota al margen, "ellos" tiene tantos caracteres como "él / ella" y se aplica de manera mucho más general, ya que también se puede usar para referirse a una sola persona.

Entonces, ¿estamos arreglando esto?

@jkbrzt Yo llamaría a esto una característica, no un error. Es intencional que las solicitudes funcionen de manera idéntica en Windows, * nixes y BSD y, de hecho, muchas distribuciones del sistema de solicitudes eliminan activamente ese comportamiento y apuntan hacia el paquete / almacén de certificados del sistema. Entonces, si los usuarios necesitan este comportamiento, pueden usar la versión de Requests empaquetada por sus distribuidores de sistema con HTTPie (y posiblemente el HTTPie empaquetado del sistema).

En cuanto a "arreglar esto", depende de su definición de fijo. Esta es una función que se agregará a las solicitudes. En ese momento HTTPie obtendrá el comportamiento de forma gratuita. Si HTTPie, en cambio, considera que esto es una prioridad más alta (que @jkbrzt puede hacer como mejor le parezca), pueden duplicar el esfuerzo de desarrollo para crear una versión que lo haga antes.

Como parece que está usando linux, @luv , puede aprovechar el hecho de que su distribución de linux casi seguramente tiene una versión de Requests que usa el almacén de certificados del sistema en la actualidad. Las solicitudes están empaquetadas en todas las distribuciones de Linux que he comprobado y casi todas esas distribuciones utilizan su almacén de certificados del sistema. Si ese no es el caso, quizás debería presentar un error con el responsable del paquete Requests de esa distribución.

mismo problema con HTTPie instalado a través de apt (ubuntu 14.04lts)

@luv eso es sorprendente porque sé con

Purgué todas las versiones de "solicitudes" y "httpie" para verificar que se usa la distribución ubuntu de httpie y tienes razón, todavía estaba usando httpie de PyPI. Ubuntu httpie falla con "ImportError: no se puede importar el nombre is_windows", que es un problema conocido.

Creo que olvidé ejecutar "pip3 uninstall" y solo ejecuté "pip uninstall", ya que tuve que usar python3 para que el ssl funcionara en primer lugar.

Pido disculpas a 761 personas por enviarles "spam" con una descripción de mi configuración de httpie.

Estoy usando Gentoo Linux. Otras herramientas (openssl s_client, sslclient, curl) detectan el certificado de CA local instalado y funcionan bien, pero httpie falla:

$ openssl s_client -quiet -connect localhost:8082                                              
depth=1 CN = Local CA home.lan
verify return:1
depth=0 CN = localhost
verify return:1
^C
$ http -v https://localhost:8082/                                                              

http: error: SSLError: HTTPSConnectionPool(host='localhost', port=8082): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),)) while doing GET request to URL: https://localhost:8082/

¿Debo actualizar algo para que funcione?

@powerman Esa es una pregunta más apropiada para los redistribuidores gentoo de esos paquetes.

@ sigmavirus24 ¿

@powerman nada ha cambiado. Ninguno es compatible con los paquetes de certificados de su sistema, pero si ha instalado ambos desde el administrador de paquetes de su distribución, es probable que hayan parcheado el software para usarlos. Si usó los paquetes disponibles en Gentoo y no están usando certificados del sistema, entonces es un problema de Gentoo.

Solo voy a agregar un comentario adicional sobre esto: uso un proxy que está diseñado específicamente para que cuando realiza solicitudes SSL, establezca un túnel seguro entre usted y el proxy y luego otro entre el proxy y el destino. Hace esto para que pueda monitorear de forma segura el tráfico que pasa a través de mi proxy para asegurarme de que nadie esté tratando de hacer algo desagradable y ocultarlo. Desafortunadamente, esto significa que el certificado que obtiene httpie no es confiable (porque está en la raíz del sistema, pero no lo usa).

De hecho, puedo reproducir el mismo problema en NixOS.

4+ años después ...

¿Fue útil esta página
0 / 5 - 0 calificaciones