Errores de SSL/TLS en navegadores muy antiguos al conectarse a Discourse

Después de configurar mi instancia de Discourse con el soporte predeterminado de Let’s Encrypt, recibí informes de algunos usuarios que indican que su navegador no puede establecer una conexión segura con Discourse. Una captura de pantalla que obtuve de un usuario señala claramente un error de SSL/TLS. Se trata de un error del lado del navegador y los usuarios ni siquiera ven nada de Discourse.

Por el contexto, parece que esos usuarios tienen sistemas operativos o navegadores algo antiguos. Al principio sospeché que el problema era el soporte de TLS 1.2, pero el usuario con el que verifiqué está ejecutando Safari 10.1.2 en macOS (versión desconocida) y, según Can I use... Support tables for HTML5, CSS3, etc, Safari debería soportar TLS 1.2 desde la versión 7.

¿Existe alguna otra razón, además de TLS 1.2, que pueda hacer que un navegador o sistema operativo falle al intentar establecer una conexión segura con una instalación predeterminada de Discourse que utiliza el soporte TLS predeterminado de Let’s Encrypt? Estoy tratando de averiguar qué preguntas debo hacer a mis usuarios para identificar cuál es el problema y en qué extremo debe solucionarse.

Como solución temporal: Según tengo entendido, la configuración predeterminada es redirigir el tráfico que va a http hacia https. ¿Existe alguna manera de realizar una verificación previa, algo como “solo si el navegador soporta TLS 1.2” o “solo si el navegador/sistema operativo es de una versión superior”, y en caso contrario, mantenerse en http?

Esta es la URL, por si tienen alguna idea sobre cómo verificar si algo está configurado incorrectamente: https://forum.stadtteilgenossenschaft-wik.de

Puedes probar tu sitio utilizando la Prueba de Servidor SSL. Los resultados de la prueba incluyen una sección llamada “Simulación de Handshake” que te mostrará las combinaciones de navegador/sistema operativo que funcionan o no.

Con la última imagen de Docker, veo la siguiente configuración TLS:

Puedes enviar a tus usuarios a https://www.ssllabs.com/ssltest/viewMyClient.html para obtener más información sobre sus versiones de navegador y sistema operativo, así como las versiones de TLS compatibles.

¡Gracias por la respuesta detallada!

Ejecuté la Prueba de Servidor SSL y no puedo encontrar nada incorrecto en el resultado:

Son los mismos que los de tu publicación, que yo pueda ver.

Los únicos fallos fueron para versiones antiguas de SO + Safari (Safari 8+9) y versiones antiguas de Windows con IE 11. Este último me preocupa un poco: ¿no debería IE 11 ser compatible con Discourse y también admitir TLS 1.2 de forma predeterminada?

La prueba tampoco incluye una prueba para Safari 10 en el sistema operativo más antiguo aún compatible, así que tal vez eso también falle…

Para los usuarios con versiones antiguas de Windows, probablemente necesiten habilitar los cifrados CBC:

Lo siguiente que deben hacer es enviar a esos usuarios a

para obtener información sobre lo que admite su navegador. La forma más sencilla de compartir su resultado es probablemente que impriman en un archivo PDF y se lo envíen.

Gracias, he recibido una respuesta de mi usuario. Está utilizando un iPod Touch muy antiguo:

Capacidades SSL/TLS de tu navegador
Agente de usuario: Mozilla/5.0 (iPod; CPU iPhone OS 6_1_6 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Versión/6.0 Mobile/10B500 Safari/8536.25

Soporte de protocolos

Tu agente de usuario tiene un buen soporte de protocolos.

Tu agente de usuario soporta TLS 1.2, que es la versión de protocolo recomendada en este momento.

Así que, aunque es antiguo (y soy consciente de que está muy lejos del sistema operativo y navegador mínimos soportados por Discourse), me gustaría permitirle al menos conectarse al sitio y ver cómo se comporta su navegador con el HTML y JavaScript modernos.

Este es el informe detallado de soporte TLS:

Características del protocolo

Protocolos

TLS 1.3 No
TLS 1.2 Sí
TLS 1.1 Sí
TLS 1.0 Sí
SSL 3 Sí
SSL 2 No

Suites de cifrado (en orden de preferencia)

TLS_EMPTY_RENEGOTIATION_INFO_SCSV ( 0xff ) -
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc024 ) DÉBIL 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc023 ) DÉBIL 128
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ( 0xc00a ) DÉBIL 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ( 0xc009 ) DÉBIL 128
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ( 0xc007 ) INSEGURO 128
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc008 ) DÉBIL 112
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ( 0xc028 ) DÉBIL 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ( 0xc027 ) DÉBIL 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ( 0xc014 ) DÉBIL 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ( 0xc013 ) DÉBIL 128
TLS_ECDHE_RSA_WITH_RC4_128_SHA ( 0xc011 ) INSEGURO 128
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc012 ) DÉBIL 112
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc026 ) DÉBIL 256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc025 ) DÉBIL 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ( 0xc02a ) DÉBIL 256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ( 0xc029 ) DÉBIL 128
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ( 0xc004 ) DÉBIL 128
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ( 0xc005 ) DÉBIL 256
TLS_ECDH_ECDSA_WITH_RC4_128_SHA ( 0xc002 ) INSEGURO 128
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc003 ) DÉBIL 112
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ( 0xc00e ) DÉBIL 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ( 0xc00f ) DÉBIL 256
TLS_ECDH_RSA_WITH_RC4_128_SHA ( 0xc00c ) INSEGURO 128
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc00d ) DÉBIL 112
TLS_RSA_WITH_AES_256_CBC_SHA256 ( 0x3d ) DÉBIL 256
TLS_RSA_WITH_AES_128_CBC_SHA256 ( 0x3c ) DÉBIL 128
TLS_RSA_WITH_AES_128_CBC_SHA ( 0x2f ) DÉBIL 128
TLS_RSA_WITH_RC4_128_SHA ( 0x5 ) INSEGURO 128
TLS_RSA_WITH_RC4_128_MD5 ( 0x4 ) INSEGURO 128
TLS_RSA_WITH_AES_256_CBC_SHA ( 0x35 ) DÉBIL 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA ( 0xa ) DÉBIL 112
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ( 0x67 ) DÉBIL 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ( 0x6b ) DÉBIL 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA ( 0x33 ) DÉBIL 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA ( 0x39 ) DÉBIL 256
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0x16 ) DÉBIL 112
TLS_ECDHE_ECDSA_WITH_NULL_SHA ( 0xc006 ) INSEGURO 0
TLS_ECDHE_RSA_WITH_NULL_SHA ( 0xc010 ) INSEGURO 0
TLS_ECDH_ECDSA_WITH_NULL_SHA ( 0xc001 ) INSEGURO 0
TLS_ECDH_RSA_WITH_NULL_SHA ( 0xc00b ) INSEGURO 0
TLS_RSA_WITH_NULL_SHA256 ( 0x3b ) INSEGURO 0
TLS_RSA_WITH_NULL_SHA ( 0x2 ) INSEGURO 0
TLS_RSA_WITH_NULL_MD5 ( 0x1 ) INSEGURO 0
(1) Cuando un navegador soporta SSL 2, sus suites exclusivas de SSL 2 solo se muestran en la primera conexión a este sitio. Para ver las suites, cierra todas las ventanas del navegador y luego abre esta página exacta directamente. No la actualices.

Detalles del protocolo

Indicación de nombre de servidor (SNI) Sí
Renegociación segura Sí
Compresión TLS No
Tickets de sesión No
Encadenamiento OCSP No
Algoritmos de firma SHA384/RSA, SHA256/RSA, SHA1/RSA, SHA256/ECDSA, SHA1/ECDSA
Grupos nombrados secp256r1, secp384r1, secp521r1
Negociación del siguiente protocolo No
Negociación de protocolo de capa de aplicación No
Compatibilidad con el saludo SSL 2 No

Manejo de contenido mixto

Pruebas de contenido mixto
Imágenes Pasivo Sí
CSS Activo Sí
Scripts Activo Sí
XMLHttpRequest Activo Sí
WebSockets Activo Sí
Frames Activo Sí
(1) Estas pruebas podrían causar una advertencia de contenido mixto en tu navegador. Eso es esperado.
(2) Si ves una prueba fallida, intenta recargar la página. Si el error persiste, por favor ponte en contacto.

Disculpa el formato, el usuario copió y pegó el HTML de texto enriquecido por mí y parte de él se pierde al pegarlo en Discourse. Intentaré averiguar cómo arreglar el formato más tarde.

Como dije, me gustaría permitirle al menos establecer una conexión segura para que vea algo, y debería ser posible ya que el navegador soporta TLS 1.2. Pero supongo que tendría que habilitar alguna configuración menos segura para TLS 1.2 para que su navegador sea soportado. No sé lo suficiente sobre los estándares TLS para comparar la salida de ese informe con lo que el servidor soporta y qué tendría que cambiar. ¿Puedes decirme qué falta y qué tendría que cambiar?

Tengo una idea aproximada de lo que quieres decir, pero no tengo ni idea de cómo hacerlo. ¿Podrías indicarme alguna documentación que explique cómo cambiar la configuración TLS del contenedor Docker de Discourse para habilitar estos?

No creo que Safari 6 funcione, incluso si resuelves los problemas de TLS añadiendo suites de cifrado adicionales.

Puedes añadir las suites de cifrado que faltan sobrescribiendo el archivo de configuración de nginx. Añade el siguiente fragmento (no probado, pero debería funcionar) a la sección hooks de app.yml y cambia el valor de ssl_ciphers según tu preferencia.

  after_ssl:
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /ssl_ciphers .*/
        to: ssl_ciphers <your_complete_cipher_list>;

Por cierto: Estoy intentando añadir soporte para certificados de curva elíptica en Discourse, lo que permitiría que funcione con IE11 sin necesidad de configuraciones adicionales.

¡iOS 6?! ¡La última versión de ese sistema se lanzó a principios de 2014! ¡Eso fue hace más de 5 años!

Lo sé, estaba tan sorprendido como tú. No espero que lo apoyes, pero me gustaría que el usuario obtenga al menos algo de HTML y vea qué funciona y qué no.

Gracias @gerhard. Realicé el cambio que describiste en /var/discourse/containers/app.yml (espero que fuera el archivo app.yml correcto) y luego ejecuté /var/discourse/launcher rebuild app, como se indica en los comentarios de app.yml.

Después, volví a ejecutar la prueba en ssllabs.com, pero parece que el resultado no cambió: https://www.ssllabs.com/ssltest/analyze.html?d=forum.stadtteilgenossenschaft-wik.de&s=68.183.214.228&hideResults=on

No estoy seguro de cómo verificar si el cambio de configuración realmente funcionó (aunque no influyó en el resultado de la prueba) o si el cambio de configuración no funcionó.

¡Oh, no leí bien tu publicación, @gerhard! Si lo entiendo correctamente, la configuración que proporcionaste hace explícitos los cifrados utilizados, pero el valor que usaste es básicamente el mismo que el predeterminado, ¿verdad? Entonces, aún tendría que ampliarla con otros cifrados que podrían ser compatibles con navegadores más antiguos.

Sí, exactamente. No quería publicar una solución para agregar cifrados débiles a la configuración. Tendrás que resolverlo tú mismo. :wink:

Pero si vas a hacer esos cambios, mantente atento a la solicitud de extracción que mencioné antes. Si se fusiona, IE11 funcionará sin necesidad de configuraciones adicionales.

Entiendo, no quieres facilitar demasiado que alguien configure su entorno de forma insegura. Respeto eso y tampoco publicaré el código completo.

Esto es lo que he logrado hasta ahora: identifiqué los conjuntos de cifrado que faltan para soportar navegadores y sistemas operativos más antiguos, consultando, por ejemplo, Qualys SSL Labs - Projects / User Agent Capabilities: Safari 6 / iOS 6.0.1 (y también para otros). Dado que los conjuntos de cifrado del cliente se listan por preferencia, simplemente elegí siempre el primero de la lista y me aseguré de soportarlo, asumiendo que si el servidor soporta uno de la lista, eso debería ser suficiente. Estos son los cifrados que identifiqué:

  • ECDHE-ECDSA-AES256-CBC-SHA384 para Safari 6-8
  • ECDHE-RSA-AES256-CBC-SHA384 para IE 11 en Win 7/8.1/Phone 8.1 Update (según @supermathie)
  • ECDHE-RSA-AES128-CBC-SHA256 para IE 11 en Win Phone 8.1

Tomé estos valores y los añadí al final de la lista de ssl_ciphers, separados por dos puntos, asumiendo que “al final de la lista” significa “menos preferido, solo se usará si el cliente no soporta nada más”. Luego ejecuté /var/discourse/launcher rebuild app para aplicar la nueva configuración y volví a ejecutar la prueba en SSL Server Test (Powered by Qualys SSL Labs) después de borrar la caché. Pero los resultados no cambiaron.

Esperaba que ahora funcionara tanto para las pruebas fallidas de IE 11 como para Safari 6-8, pero el handshake sigue fallando. Debo estar omitiendo algo.

Además, uno de mis usuarios usa un iPhone con iOS 9/Safari 9 y para ellos la conexión también falla. Pero según los resultados de las pruebas de SSL Labs, esa conexión ya debería funcionar de forma nativa (como también se puede ver en el resultado de @gerhard arriba).

Así que debo estar omitiendo dos cosas:

  1. ¿Por qué la conexión sigue sin funcionar después de añadir soporte para los cifrados?
  2. ¿Por qué SSLLabs dice que funciona para iOS 9 + Safari 9, pero en realidad no funciona para mi usuario?

Respecto al punto 1: aún no estoy seguro de haber aplicado la configuración correctamente. Aparte de la prueba de SSL Labs, ¿hay otra forma de verificar qué cifrados soporta el servidor para ver si mi cambio de configuración se aplicó correctamente?

Después de examinar más de cerca el resultado de SSLLab, creo que esto no funciona.

Este es el resultado que veo en SSLLabs para mi servidor después de aplicar la configuración y reconstruir:

Según mi comprensión, debería listar muchos más, ya que la configuración tiene muchas más opciones. ¿Significa esto que este cambio de configuración no funcionó?

Creo que los nombres de los cifrados que elegiste son incorrectos. Mapping OpenSSL cipher suite names to IANA names es un buen recurso para mapear entre los cifrados listados por SSL Server Test y los nombres utilizados por OpenSSL (nginx).

En mis pruebas agregué :ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA y, tras una reconstrucción, la prueba se ve así:

¿Quizás haya un error en la prueba? :man_shrugging: No tengo una versión tan antigua de Safari para probar. Solo soportamos Safari 10+. ¿Estás seguro de que sigue fallando debido a un error de TLS?

¡Gracias, lo probaré!

Revisé un poco más los archivos de configuración de Discourse y encontré templates/web.ssl.template.yml. ¿Cuál es la diferencia entre hacer este cambio en los cifrados a través del archivo app.yml y simplemente modificar la lista de ssl_ciphers directamente en templates/web.ssl.template.yml?

La plantilla está bajo control de versiones y app.yml no lo está. Tendrás problemas al actualizar el repositorio si editas la plantilla.

Gracias, ese era el problema y corregir los nombres hace que el handshake funcione para todos los navegadores probados en la lista de SSLLabs. ¡Muchas gracias por tu paciencia!

Ahora, me interesa saber qué ven mis usuarios una vez que superan el error de HTTPS con sus navegadores antiguos. :smiley: