Desajuste del certificado del nombre de host del correo electrónico que causa sobrecarga de la cola de sidekiq, inestabilidad grave del sitio

He estado autoalojando Discourse durante muchos años, y he tenido varias instancias configuradas y funcionando felizmente en una máquina bastante potente.

Hoy noté que uno de mis foros se había caído. El culpable inicial parecía ser la falta de espacio en disco, lo cual arreglé. Luego reinicié la instancia de Discourse.

Sin embargo, ha seguido cayéndose regularmente desde entonces. Cada vez que la arranco, veo inmediatamente que sidekiq se vuelve loco y una gran cantidad de trabajos de correo electrónico fallidos, que también están haciendo que redis almacene una gran cantidad de estado, lo que creo que fue la causa real del problema de espacio en disco. (Voy a hacer un flush la próxima vez que pueda poner en marcha la máquina, ya que si no lo hago, me quedaré rápidamente sin espacio en esta máquina y ni siquiera podré iniciar Discourse para hacer el flush. Pero el flush no parece reducir mucho el uso del disco de redis).

El mensaje de error indica algo sobre una falta de coincidencia en el nombre del certificado, lo cual me sorprende un poco ya que el servidor de correo que estoy usando es interno y no requiere TLS ni autenticación. Pude verificar en una de mis otras instancias (usando la misma configuración de correo electrónico) que el correo había dejado de funcionar. Todo lo que puedo ver en los registros principales de producción es un error 422, pero cuando envío algo como un restablecimiento de contraseña, veo un error similar en los registros de sidekiq:

Jobs::HandledExceptionWrapper: Wrapped OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (Hostname mismatch)

He podido verificar que puedo enviar correos electrónicos desde la línea de comandos, por lo que esto no parece ser un problema con el servidor de correo en sí, solo algo roto con la configuración de Discourse.

Aquí está la configuración de correo original que funcionaba hasta hace poco:

DISCOURSE_SMTP_ADDRESS: outbound-relays.techservices.illinois.edu
DISCOURSE_SMTP_PORT: 25
DISCOURSE_SMTP_ENABLE_START_TLS: false

Nuevamente, este servidor de correo es interno y no requiere nombre de usuario ni contraseña, y estas configuraciones funcionaban hasta hace poco. He estado experimentando con DISCOURSE_SMTP_OPENSSL_VERIFY_MODE, pero no puedo decir si todavía es compatible. De todos modos, no parece ayudar. Noté algunas configuraciones de correo nuevas que se agregaron desde que configuré estos foros, pero no parecen necesarias dada la configuración de este servidor de correo.

¡Cualquier ayuda sería apreciada! En este punto, honestamente incluso me cuesta estar seguro de lo que está mal o de cómo iterar, ya que reconstruir el contenedor lleva tiempo y el mensaje de error en los registros de producción solo tiene el error 422 y no puedo encontrar dónde buscar la causa raíz real. (Debe estar en algún lugar, ¿verdad? Estoy seguro de que simplemente me lo estoy perdiendo).

1 me gusta

Como actualización, siguiendo el consejo de otro hilo, este comando envía correos electrónicos con éxito desde el interior del contenedor Docker:

echo message | s-nail -r "noreply@myforum.com" -s testing -S "smtp=same.email-service.com:25" my@address.com

Lo que coincide con la configuración de correo electrónico que estaba utilizando cuando comenzó este problema. Tenga en cuenta que también realicé una actualización a la última versión de Discourse a través de un comando de extracción (requerido) el viernes, lo que me hace preguntarme si un commit reciente introdujo este problema.

2 Me gusta

¿Cuándo fue la última vez que reconstruiste el contenedor?

Además, ¿borraste la cola de Redis?

2 Me gusta

Viernes por la mañana, creo. Una actualización normal a través de la interfaz de usuario activó la necesidad de una reconstrucción de la aplicación lanzadora. Cuando examiné los registros de sidekiq más tarde, parecía que la cola de espera comenzó alrededor del momento en que se reconstruyó el contenedor, pero tardó aproximadamente 24 horas en que los registros de Redis consumieran todo el almacenamiento disponible en el host y realmente causaran tiempo de inactividad. Sin embargo, el foro probablemente fue lento antes de ese punto, dado que sidekiq estaba intentando desesperadamente reenviar un número creciente de trabajos de correo electrónico fallidos con un uso del CPU del 100%.

Sí.

Sin embargo, me preocupa que esto no haya reducido el uso del disco de Redis. Tengo una carpeta redis_data que actualmente tiene un tamaño de 29G, incluso después de la limpieza. ¿Quizás Redis es como MongoDB en que puede ser difícil hacer que devuelva las asignaciones de disco? Dado que esto es 1/3 del disco disponible en la máquina, se convertirá en un problema, pero lo pospondré por ahora en favor de simplemente volver a hacer que el correo electrónico funcione.

1 me gusta

Como nota de depuración: ¿Hay alguna forma de enviar un correo electrónico de prueba desde la línea de comandos dentro del contenedor, utilizando el mismo flujo de código que usaría Discourse? (Es decir, no desde la línea de comandos usando otra herramienta, lo cual ya he verificado que funciona). Esto sería útil para la depuración, ya que actualmente enviar un correo electrónico de prueba requiere manipular la interfaz de usuario web y luego buscar en los registros para averiguar qué salió mal. (Y hasta ahora solo he encontrado los errores 422, y nada más útil, excepto en los registros de sidekiq que no se crean cuando se usa el flujo de correo electrónico de prueba). ¿O tal vez la interfaz de usuario de correo electrónico de prueba podría mostrar más información de depuración?

En general, sospecho que la mayoría de las personas configuran Discourse y no llegan a este punto sin que el correo electrónico funcione, ya que es necesario para enviar invitaciones iniciales, etc. Pero encuentro que la depurabilidad es limitada en el caso en que el correo electrónico funcionaba y de repente deja de hacerlo. (Además, la lógica de reintento puede necesitar algunos ajustes, ya que parece demasiado rápido para reintentar en este caso. Es poco probable que un error de certificado se solucione unos segundos después del intento inicial…)

1 me gusta

Quizás consulta Troubleshooting email on a new Discourse install. Creo que quieres

rake emails:test[user@domain]
3 Me gusta

¡Gracias! Esto es útil. Aquí está el resultado:

Testing sending to user@domain using outbound-relays.techservices.illinois.edu:25, username: with plain auth.
======================================== ERROR ========================================
                                    UNEXPECTED ERROR

SSL_connect returned=1 errno=0 state=error: certificate verify failed (Hostname mismatch)

====================================== SOLUTION =======================================
This is not a common error. No recommended solution exists!

Please report the exact error message above to https://meta.discourse.org/
(And a solution, if you find one!)
=======================================================================================

Voy a reconstruir el contenedor ahora para asegurarme de que él y app.yml estén sincronizados. Pero en general, estoy un poco confundido por qué dice que está usando autenticación simple, ya que no se proporciona nombre de usuario ni contraseña en el archivo de configuración app.yml.

¿Vale la pena reclasificar esto como un error? Inicialmente dudé, ya que es correo electrónico y hay muchas maneras en que esto podría estar funcionando mal, muchas de las cuales serían una combinación de mi culpa / cambios externos. Pero, AFAICT, esto representa una configuración que funcionó durante varios años y de repente dejó de hacerlo en una actualización a la última edición de discourse_docker. ¿Es posible que algo en la forma en que se procesan los archivos de configuración haya cambiado recientemente?

Con respecto al mensaje de error: pude obtener un certificado para esa máquina y, de hecho, el certificado enumera otro nombre de host (un CNAME diferente para la misma máquina). Sin embargo, el certificado en sí tiene varios años y también expiró hace aproximadamente un año, pero recién comenzó a generar este error recientemente. Así que eso me hace pensar que no fue un cambio en el certificado lo que está causando el problema.

2 Me gusta

Al conectarme a ese host y probar STARTTLS, obtengo un certificado que no coincide con el nombre de host:

Certificate chain
 0 s:/C=US/ST=California/L=Sunnyvale/O=Proofpoint, Inc./OU=ESP/CN=*.pphosted.com
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte RSA CA 2018
 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte RSA CA 2018
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA

y aún no ha caducado:

notBefore=Jun 12 00:00:00 2020 GMT
notAfter=Sep 14 12:00:00 2022 GMT

Realizar una búsqueda directa e inversa muestra que los servidores de correo se llaman en realidad mx0a-00007101.pphosted.com y mx0b-00007101.pphosted.com.

outbound-relays.techservices.illinois.edu. 22 IN A 148.163.139.28
outbound-relays.techservices.illinois.edu. 22 IN A 148.163.135.28

28.139.163.148.in-addr.arpa name = mx0b-00007101.pphosted.com.
28.135.163.148.in-addr.arpa name = mx0a-00007101.pphosted.com.

Intenta cambiar el nombre de host al que te conectas a uno de esos en lugar del nombre .edu. No es necesario que sea un cambio en el certificado, podría haber sido un cambio en el nombre de host o en el código. Pero el error es correcto: de hecho, hay una discrepancia en el certificado del nombre de host.

4 Me gusta

¡Gracias @RGJ! Lo intentaré.

Sin embargo, me pone un poco nervioso usar esos nombres, dado que podrían estar sujetos a cambios en el futuro y no coinciden con el nombre de host que se proporciona para uso en el campus para este propósito. ¿Hay alguna forma de deshabilitar este error a través de la configuración de app.yml o de alguna otra manera?

1 me gusta

Mi enfoque fue hacer que las cosas volvieran a funcionar primero, y luego averiguar cómo mejorarlo.
Deberías poder establecer DISCOURSE_SMTP_OPENSSL_VERIFY_MODE en false, pero dijiste que ya lo intentaste.

5 Me gusta

Sí, ¡absolutamente! Tiene sentido.

Creo que intenté establecer ese valor en none, pero no en false. Probaré con false.

2 Me gusta

OK, confirmo que false no funciona. Volveré a probar con none.

1 me gusta

También puedo verificar que none no funciona.

Supongo que estoy un poco perplejo aquí en cuanto a si este es un comportamiento razonable. DISCOURSE_SMTP_ENABLE_START_TLS está configurado en false, lo que, al menos para los que no somos expertos en correo electrónico como yo, haría confuso que un certificado juegue un papel en este fallo. Si la máquina no tuviera un certificado en absoluto, ¿ocurriría este mismo problema? (Obviamente, no puedo probar esto). Si no es así, parece aún más extraño.

De todos modos, me conformaré con la solución temporal por ahora, pero algo sobre esto me parece extraño.

1 me gusta

Ciertamente. Puedo imaginar que si un servidor de correo requiere starttls, anulará la configuración de starttls, pero DISCOURSE_SMTP_OPENSSL_VERIFY_MODE aún debería poder evitar un error.

¿Alguien puede reproducir esto?

2 Me gusta

@Geoffrey_Challen ¿cómo lo solucionaste?

Hoy he actualizado mi foro a la versión 2.9.0.beta4 (c99a6b10fb) y ahora tengo el mismo error, discourse no puede enviar correos electrónicos:
SSL_connect returned=1 errno=0 state=error: certificate verify failed (Hostname mismatch)

¡No he cambiado la configuración del VPS ni del correo electrónico!

Mi app.yml:

  DISCOURSE_SMTP_ADDRESS: smtp.mydomain.info
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: info@mydomain.info
  DISCOURSE_SMTP_PASSWORD: "mypassword"
  DISCOURSE_SMTP_ENABLE_START_TLS: false           # (opcional, por defecto true)
  DISCOURSE_SMTP_DOMAIN: mydomain.info             # (requerido por algunos proveedores)
  #DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com    # (dirección para enviar notificaciones)

Lo intenté y nada cambia…

Por favor, ahora no puedo enviar correos electrónicos y no puedo usar TLS, ¿qué puedo hacer?

2 Me gusta

Emita este comando y vea para qué nombre de host es el certificado

openssl s_client -connect  smtp.mydomain.info:25 -starttls smtp -showcerts 2>&1|grep "depth=0"

Reemplazando smtp.mydomain.info con la dirección de su servidor SMTP, por supuesto.

Luego, intente ver si puede acceder al servidor SMTP utilizando ese nombre de host.

3 Me gusta

Gracias por tu ayuda @RGJ

el nombre de host es CN = *.aruba.it, por lo que es diferente de mydomain.info y sí, puedo acceder al servidor SMTP usando el nombre de host y telnet.

Todo funcionó perfectamente antes de ./launcher rebuild app

Pero… tengo DISCOURSE_SMTP_ENABLE_START_TLS: false, ¿por qué sigue buscando el certificado?

1 me gusta

Puedes acceder al host usando un nombre que coincida con el certificado. Puedes pedirle al administrador del servidor que agregue el nombre de host que deseas al certificado.

Esa es una buena pregunta, pero puedes hacer que su respuesta sea irrelevante siguiendo el consejo anterior, o eso creo.

Otra pregunta, creo, es ¿por qué el administrador de correo lo rompió por ti?

Tal vez esa configuración funcionó antes y ahora no. No está claro si es más fácil rastrear ese error o cambiar el nombre de host y ver si eso resuelve tu problema.

1 me gusta

Nadie hizo ningún cambio, estoy seguro, solo ejecuté ./launcher rebuild para instalar este plugin.

Entonces, ¿debería cambiar el nombre de host del VPS a algo que termine en .aruba.it?

1 me gusta

Eso es lo que parece.

Es posible que haya una regresión que haya causado el problema, pero creo que puedes resolver tu problema inmediato cambiando el nombre de host.

2 Me gusta