certificados: emitidos, y las dos trampas del camino

www.feadulta.com, feadulta.com y wp-nuevo.feadulta.com, de Let's Encrypt y
validos hasta el 1-nov. Ya se puede subir la zona a Full (strict).

Lo que funciono es el plan B de Inma, porque la Configuration Rule que propuse
primero no se puede montar en su plan de Cloudflare: custom rule del WAF con
accion Skip para la ruta del reto, mas apagar Always Use HTTPS a nivel de zona
unos minutos.

Dos cosas que costaron tiempo y quedan anotadas:

acme.json escribe "main": "dominio" CON espacio. Un grep sin espacio da vacio
siempre y parece que no hay certificados. Los de hoy llevaban casi una hora
emitidos mientras mi bucle de vigilancia informaba de "sin novedad", y por eso
lanzamos un reintento que no hacia falta. Va el snippet que parsea el JSON.

Y se retira un riesgo que yo mismo habia documentado: el modo Full NO impide el
reto. Se temia que Cloudflare mandara la validacion al 443, donde el handler de
ACME no existe. Es falso y se midio: con Always Use HTTPS apagado, una peticion
HTTP a la ruta del reto a traves de Cloudflare devuelve 404 con 0 bytes y
server: cloudflare, o sea que reenvia al puerto 80 y responde Traefik. Mejor
quitarlo que dejar una advertencia falsa en un documento que va a leer otra
gente.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 09:17:31 -04:00
parent 20528f0c5e
commit d98f99d0ab
2 changed files with 63 additions and 45 deletions
+3 -2
View File
@@ -20,8 +20,9 @@ disabled"*.
| | | | | |
|---|---| |---|---|
| 🔴 **Certificados LE de `www` y el apex** | Sin emitir. El WAF de Cloudflare devuelve **403 a la validación** de Let's Encrypt en `/.well-known/acme-challenge/…`. **No bloquea con la zona en `Full`** (Cloudflare acepta el cert por defecto de Traefik), pero **impide subir a `Full (strict)`**. Se arregla con una excepción del WAF para esa ruta, o pasando a validación **DNS-01** con el token que ya tenemos. Traefik no reintenta solo: hará falta un redeploy. | | **Certificados LE de `www` y el apex** | **Emitidos el 3-ago a las 12:03 UTC**, válidos hasta el 1-nov. Detalle y las dos trampas del camino en `certificados-letsencrypt-cloudflare.md`. **Ya se puede subir la zona a `Full (strict)`.** |
| 🔴 **Backups en Hetzner** | Siguen sin existir. Ahora ahí vive producción, así que ya no es deuda técnica: es el único sitio donde están los datos vivos. | | **Application passwords** | Wordfence las desactiva por defecto y eso dejaba a los bots sin poder publicar (401 en la REST API). Reactivado y **añadido como paso 3e de `post-import-seguridad.sh`**, porque el 3d reinstala Wordfence y volvería a romperse. |
| ✅ **Backups en Hetzner** | Ya existen (verificado por Rafa en otra sesión). |
| 🟡 **CDMON** | Es el rollback. Inma lo está degradando a un plan barato con el correo. Caduca el **07/08**. | | 🟡 **CDMON** | Es el rollback. Inma lo está degradando a un plan barato con el correo. Caduca el **07/08**. |
| 🟡 **`nuevo.feadulta.com`** | Ya no hace falta; retirar el registro cuando se quiera. | | 🟡 **`nuevo.feadulta.com`** | Ya no hace falta; retirar el registro cuando se quiera. |
| 🟡 **Scripts que apuntan a `134.0.10.170` y `/web/`** | Cierra #158. | | 🟡 **Scripts que apuntan a `134.0.10.170` y `/web/`** | Cierra #158. |
@@ -1,17 +1,59 @@
# Los certificados de Let's Encrypt de `www` y el apex no se emiten # Los certificados de Let's Encrypt de `www` y el apex
**Estado: abierto.** Bloqueado a la espera de una regla en Cloudflare, que gestiona Inma. ## ✅ RESUELTO — 3-ago-2026, 12:03 UTC
Fecha: 3-ago-2026, después del cutover. Plan maestro: `rafa/feadulta`#180.
## Resumen para quien tenga prisa ```
www.feadulta.com Let's Encrypt YR2 3-ago-2026 -> 1-nov-2026
feadulta.com Let's Encrypt YR2 3-ago-2026 -> 1-nov-2026
wp-nuevo.feadulta.com Let's Encrypt YR1 3-ago-2026 -> 1-nov-2026
```
Traefik no consigue el certificado de `www.feadulta.com` ni de `feadulta.com`. **No hay nada roto **Lo que funcionó** (el "plan B" de Inma, porque la Configuration Rule que se propuso primero **no
para los visitantes**: Cloudflare presenta su propio certificado, y hacia el origen —con el modo SSL se puede montar en este plan de Cloudflare**):
de la zona en `Full`— acepta el certificado por defecto de Traefik. El único coste es que **la zona
no puede subir a `Full (strict)`** hasta que se resuelva.
La causa es que el reto HTTP-01 de Let's Encrypt acaba llegando por HTTPS y Cloudflare lo bloquea 1. **Custom rule del WAF con acción *Skip*** para `/.well-known/acme-challenge/`.
con un 403. Se arregla con una **Configuration Rule** en Cloudflare acotada a la ruta del reto. 2. **Apagar "Always Use HTTPS" a nivel de zona** durante unos minutos, y volver a encenderlo después.
Con eso el reto se completa por el puerto 80, donde lo atiende Traefik. **Ya se puede subir la zona
a `Full (strict)`.**
### ⚠️ Dos avisos para la próxima, que costaron tiempo
**1. `acme.json` escribe `"main": "dominio"` CON espacio.** Un `grep '"main":"'` da vacío siempre y
parece que no hay certificados. Los certificados de hoy llevaban **casi una hora emitidos** mientras
un bucle de vigilancia mal escrito informaba de "sin novedad". **Parsear el JSON, no grepear:**
```bash
docker exec coolify-proxy cat /traefik/acme.json > /tmp/a.json
python3 -c "
import json
d=json.load(open('/tmp/a.json'))
for r,v in d.items():
if isinstance(v,dict):
for c in (v.get('Certificates') or []): print(c.get('domain',{}).get('main'))
"
```
**2. Se descartó un riesgo que se había anotado aquí: el modo `Full` NO impide el reto.** Se temía
que Cloudflare, al hablar con el origen por HTTPS, mandara la validación al 443 —donde el handler de
ACME no existe— y que HTTP-01 fuera imposible con la zona en `Full`. **Es falso**, y se midió:
con "Always Use HTTPS" apagado, una petición HTTP a la ruta del reto a través de Cloudflare devuelve
**404 con 0 bytes y `server: cloudflare`**, es decir, Cloudflare **sí reenvía al puerto 80** y
responde el handler de Traefik.
---
*Lo que sigue es el diagnóstico, que se conserva porque explica cómo se llegó hasta aquí y contiene
un par de trampas que conviene no repetir.*
## Resumen del problema (histórico)
Traefik no conseguía el certificado de `www.feadulta.com` ni de `feadulta.com`. **No había nada roto
para los visitantes**: Cloudflare presentaba su propio certificado, y hacia el origen —con el modo
SSL de la zona en `Full`— aceptaba el certificado por defecto de Traefik. El único coste era que la
zona no podía subir a `Full (strict)`.
La causa: el reto HTTP-01 acababa llegando por HTTPS y Cloudflare lo bloqueaba con un 403.
## Lo que dice Let's Encrypt, que es el único testigo que vale ## Lo que dice Let's Encrypt, que es el único testigo que vale
@@ -79,33 +121,11 @@ SSL. **La regla no se puede montar así.**
Es una excepción mínima y acotada: esa ruta no sirve contenido, solo tokens de un solo uso que el Es una excepción mínima y acotada: esa ruta no sirve contenido, solo tokens de un solo uso que el
propio Traefik genera y valida. propio Traefik genera y valida.
### ⚠️ Puede que aun así no salga, y conviene saber por qué antes de intentarlo
Con el modo SSL de la zona en **`Full`, Cloudflare habla con el origen por HTTPS**. Si eso se aplica
también a las peticiones que le entran por HTTP, entonces al apagar "Always Use HTTPS" la petición
de Let's Encrypt llegará igualmente al **443** de Traefik, donde **el handler de ACME no existe** —y
volverá a fallar, ahora con un 404 en vez de un 403.
No se puede determinar desde aquí sin apagar el ajuste: mientras "Always Use HTTPS" esté encendido,
Cloudflare redirige en su borde y **nunca llega a contactar con el origen por el puerto 80**, así que
no hay forma de observar qué puerto usaría.
**Cómo distinguir los dos casos en el siguiente intento**, mirando el error de Traefik:
| lo que reporte Let's Encrypt | qué significa | qué hacer |
|---|---|---|
| sale el certificado | Cloudflare reenvía por el 80 y Traefik atiende | nada más |
| `403` | el *Skip* del WAF no está cogiendo esa ruta | revisar el ámbito de la regla |
| **`404`** | **Cloudflare va al 443 del origen**: HTTP-01 no puede funcionar con la zona en `Full` | **pasar a DNS-01, dejar de quemar validaciones** |
### Sobre los visitantes durante la ventana ### Sobre los visitantes durante la ventana
Apagar "Always Use HTTPS" unos minutos es inocuo, pero **no exactamente por el motivo que parece**. Apagar "Always Use HTTPS" unos minutos resultó inocuo: Cloudflare reenvía al puerto 80 del origen y
Si Cloudflare reenviara por el 80, Traefik devuelve un 302 a HTTPS por su cuenta (medido) y el **Traefik devuelve su propio 302 a HTTPS**, así que el visitante acaba en HTTPS igual. Medido antes
visitante acaba igual. Si Cloudflare va al 443, ese 302 no llega a dispararse y **un visitante que y durante.
entre por `http://` se quedará en `http://`** — con el contenido correcto y cifrado hasta Cloudflare,
pero sin subir a HTTPS. Para una ventana de minutos no tiene consecuencias, pero que nadie se
extrañe si lo ve.
### Alternativa de fondo, para más adelante ### Alternativa de fondo, para más adelante
@@ -148,11 +168,8 @@ Cuesta **unos 7 segundos** de corte: se ha medido dos veces, un único 500 y vue
### Comprobar si ya salió ### Comprobar si ya salió
```bash ⚠️ **No con `grep`** — ver el aviso del principio: el fichero escribe `"main": "dominio"` con
docker exec coolify-proxy cat /traefik/acme.json | grep -oE '"main":"[^"]*feadulta[^"]*"' espacio y un patrón sin espacio da vacío siempre. Parsear el JSON.
```
Hoy sólo aparecen `antiguo.feadulta.com`, `nuevo.feadulta.com` y `gitea.feadulta.com`.
## Cabo suelto ya cerrado por el camino ## Cabo suelto ya cerrado por el camino
@@ -161,7 +178,7 @@ cualquier 404. No era la causa —el reto va por el 80 y ahí ni llega a WordPre
era una trampa para el futuro. Arreglado y desplegado: las rutas de protocolo quedan exentas y el era una trampa para el futuro. Arreglado y desplegado: las rutas de protocolo quedan exentas y el
resto del redirect sigue igual. Lo encontró el Claude de Inma. resto del redirect sigue igual. Lo encontró el Claude de Inma.
## Cuando el certificado salga ## `Full (strict)`
Entonces —y sólo entonces— se puede subir la zona a **`Full (strict)`**, que valida además el Ya se puede: los tres certificados están emitidos. Sube la seguridad porque valida además el
certificado del origen. Hacerlo antes rompe el sitio. certificado del origen. **Comprobar el sitio justo después de cambiarlo.**