Fallo de Discourse al renovar certificado

Continuando la conversación desde aquí:

La primera vez que recibí un recordatorio de Redsift de que mis certificados iban a caducar en una semana. Normalmente, Discourse renueva los certificados con mucha antelación. Esta vez no fue así, antes de empezar a reconstruir (lo que se supone que soluciona el problema), @Falco, ¿hay algo que quieras que compruebe y publique aquí para ayudar a llegar a la raíz de por qué los certificados no se renovaron?

El certificado raíz es ISRGX1 y aquí tienes la información del certificado que caduca:

Nombre Común (CN) E6
Organización (O) Let’s Encrypt
Unidad Organizacional (OU)
Emitido el Miércoles, 16 de julio de 2025 a las 7:36:45 PM
Caduca el Martes, 14 de octubre de 2025 a las 7:36:44 PM

La compilación actual es 3.6.0.beta1-dev (7ee52c8f85)

1 me gusta

Hubo un período de tiempo en el que el endpoint que Let’s Encrypt necesitaba se redirigió. Eso está arreglado si reconstruyes.

5 Me gusta

¿Aproximadamente cuánto tiempo después de actualizar se debe renovar el certificado?

Si la memoria no me falla, los certificados son válidos por 3 meses y ahora intentarán renovarse automáticamente antes de que expiren.

1 me gusta

Sí, sé cómo se supone que funciona.

Pero ha pasado más de un día desde que actualicé el software del foro y el certificado aún no parece haberse actualizado. Le quedan 5 días antes de que expire, por lo que realmente necesita renovarse pronto.

Estoy en la rama estable de Discourse si eso marca la diferencia. ¿Es posible que la corrección del punto final no se haya retroportado?

Para mí, el certificado se actualizó inmediatamente después de la reconstrucción.

¿Recompilaste a través de la web o de la línea de comandos?

1 me gusta

Sí, la explicación estaba aquí:

1 me gusta

Mi foro finalmente ha actualizado su certificado después de que realicé una reconstrucción desde la línea de comandos.

3 Me gusta

Hemos tenido la misma experiencia de que SSL no se renueva.

Sería genial si alguien pudiera verificar que web.ssl.template se comporta correctamente en discourse-docker, me pareció que el puerto 80 en realidad no estaba sirviendo ninguna URL de /.well-known/ utilizada por Let’s Encrypt, todas las URL se estaban redirigiendo a SSL, incluidos los archivos de prueba que coloqué manualmente en /var/www/discourse/public/.well-known/. Tuve que editar /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf directamente dentro del contenedor de la aplicación.

¿Quizás esto comenzó después del commit ae4887a de discourse-docker?

1 me gusta

Hubo otro error en la ruta más conocida en la memoria reciente.

¿Cuándo fue la última vez que hiciste una reconstrucción?

1 me gusta

A mí también. No recibí ninguna advertencia sobre la caducidad del certificado. Entrar en el servidor y lanzar una reconstrucción /var/discourse % ./launcher rebuild solucionó el problema.

2 Me gusta

En mis pruebas en una instalación vanilla de nginx (1.18.0, pero creo que es lo mismo para 1.26.3), una línea de configuración de nginx return 301 https://thehostname$request_uri; fuera de una ubicación anula completamente cualquier bloque location anterior, en lugar de ser un “catch-all”. Creo que /.well-known/ simplemente no se sirve en el puerto 80 a menos que la redirección 301 sea específicamente para otra ubicación, como / al final del bloque server. ¿Podría ser el mismo problema que esta publicación de stackoverflow?

Me alegra que rebuild funcione, pero como el certificado ya se había renovado por mí, no pude confirmar si un rebuild permitiría a los servidores de validación de Let’s Encrypt llegar allí si un certificado hubiera expirado. Quizás un rebuild inicia la renovación del certificado antes de que esa línea de plantilla esté en su lugar o similar, en lugar de arreglar las plantillas, pero no puedo confirmar si esa es la razón por la que rebuild logra que la renovación funcione.

Si crees que esto es un Discourse, entonces quizás deberías responder en el commit de github o abrir un nuevo informe grande.

1 me gusta

Puedo confirmar que la renovación de Let’s Encrypt falla. He estado ejecutando una instalación de Discourse autohospedada durante años, y muy extrañamente la renovación falló dos veces seguidas en los últimos meses. La segunda vez fue esta mañana, y por eso comencé a investigar.

Lo he rastreado hasta las siguientes dos confirmaciones (commits):

Y la línea relevante enlazada:

Hay dos problemas, creo.

Primero, return 301 https://${DISCOURSE_HOSTNAME}$request_uri; se convierte en return 301 https://<NOMBRE DE MI SERVIDOR> sin un $request_uri al final. Lo he verificado en mi instalación autohospedada, y también en la instalación autohospedada de un amigo que se configuró la semana pasada. No entiendo cómo funciona la plantilla de Discourse, así que no sé por qué se elimina.

Segundo, como mencionó @lessLost, la redirección 301 está fuera del bloque location. Creo que una redirección a nivel de servidor anula todos los bloques location. LetsEncrypt usa http para las renovaciones. Sin embargo, cualquier intento de curl -I http://TU_DOMINIO/.well-known/acme-challenge/test devolverá un 301 a https, en lugar de un 404 (que es el comportamiento esperado; queremos un 404, no un 301).

Lo he solucionado manualmente en mi instalación autohospedada, pero espero que cualquier actualización anule mis cambios. Desafortunadamente, no entiendo las plantillas lo suficiente como para enviar una solicitud de extracción (pull request) @pfaffman, o lo haría también.

Editado para añadir:

Creo que esto es un error:

Estoy bastante seguro de que LetsEncrypt usa http por defecto (por razones obvias, si el certificado ha caducado, ¡no puede renovarse!) Pero colocar el 301 a nivel de bloque server fuerza a todas las solicitudes a redirigir a https, lo cual es inconsistente con esta estrategia de renovación.

1 me gusta

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

Esta mañana, aproximadamente 10 minutos después de despertarme, visité mi foro y me di cuenta de que el certificado había expirado de nuevo. (¿Reconstruir fue lo que lo renovó la última vez que me expiró, hace unos 3 meses?)

Creo que han implementado cambios desde entonces que han solucionado este problema, pero como se tarda 3 meses en averiguarlo, el jurado aún no ha emitido su veredicto. Podrías configurar un recordatorio un par de semanas antes de que caduque el certificado actual.

1 me gusta

Esto no es cierto.

  1. Los enlaces que adjunté en el comentario anterior eran de un git blame. Aquí está la última versión del archivo (línea relevante enlazada): discourse_docker/templates/web.ssl.template.yml at 247c71a1e45d32b0b814a8e9d5fdaa4faaf727b9 · discourse/discourse_docker · GitHub
  2. La nueva instalación del sitio de mi amigo fue de hace una semana. La línea 37 de la plantilla anterior dice: return 301 https://${DISCOURSE_HOSTNAME}$request_uri; pero en el contenedor de Discourse Docker, tanto el suyo como el mío /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf dice return 301 https://<tu_sitio_discourse>; Nótese cómo se elimina $request_uri. ¡Algo está causando que eso desaparezca! (No sé qué).
  3. Hice una renovación forzada simulada esta mañana como parte de mi investigación. Falló. Luego cambié /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf. ¡Tuvo éxito!

En realidad, está bien; simplemente editaré manualmente 20-redirect-http-to-https.conf cada vez que actualice Discourse. Para aquellos que encuentren este comentario, el comando a ejecutar es:

cat > /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf << 'EOF'
server {
  listen 80;
  listen [::]:80;

  location ~ /.well-known {
    root /var/www/discourse/public;
    allow all;
  }

  location / {
    return 301 https://<TU_DIRECCION_DEL_FORO>$request_uri;
  }
}
EOF

No estoy totalmente seguro de qué está causando este fallo, pero sé que modificar la configuración anterior lo soluciona. Pero también he modificado las notificaciones para que las renovaciones de letsencrypt ya no fallen silenciosamente, para poder tener alguna advertencia avanzada. ¡Solo pensé que te gustaría saberlo!

4 Me gusta

Gracias por el informe, creo que esto es legítimo.

(para tu información @featheredtoast)

6 Me gusta