Cloudflare delante del apex crearack.com — topología, IP real y TLS
Ejecutado y verificado el 07-07-2026 (sesión Security Center). Origen: insights
a_record_not_proxied+a_record_dangling(el apex entraba directo al Hetzner sin WAF/anti-DDoS y con la IP de origen expuesta). Código asociado: PR #286 (v1.45.13).
Topología (después del cambio)
Visitante → Cloudflare edge (proxy naranja, Full strict, WAF/DDoS)
→ Traefik (Dokploy, Hetzner PROD 116.203.31.166)
→ Daphne --proxy-headers → Django
- Registro A del apex
crearack.com→ proxied (naranja) desde 07-07-2026.wwwya lo estaba (Workerwww-redirect-crearackresponde 301 en el edge). - La zone estaba ya en SSL Full (strict); el origen sirve un cert Let’s Encrypt para
crearack.comrenovado por Traefik (desde s222 pordnsChallenge, ver abajo).
Las 3 piezas que sostienen la IP real (NO tocar sin leer esto)
Daphne corre con --proxy-headers y resuelve la IP del cliente desde el PRIMER valor de X-Forwarded-For (verificado en el source de daphne 4.2.1). Con un proxy más en la cadena, ese primer valor sería falseable por el cliente — reabriría el bypass de /admin cerrado en s104, una capa por debajo del middleware. Lo impiden:
- Transform Rule en la zone
crearack.com(ruleset552d96c5d98d4fcaa58dcd699cbff3ac, phasehttp_request_late_transform, reglaf44fbd6d...): eliminaX-Forwarded-Foren el edge. CF prohíbe sobrescribir ese header, pero al eliminarlo su proxy lo re-añade con solo la IP real del visitante (documentado por CF). Resultado: el XFF que llega al origen es"visitante"— sin basura del cliente. - Traefik (
/etc/dokploy/traefik/traefik.yml, PROD):entryPoints.web/websecure.forwardedHeaders.trustedIPs= los 22 rangos publicados de CF (www.cloudflare.com/ips). Sin esto Traefik descartaría el XFF veraz de CF. Traefik añade el peer al final → Django ve"visitante, cf-edge"y Daphne coge el primero ✓. Backup previo:traefik.yml.bak-20260707. Conexiones directas (no-CF) siguen como antes: XFF del cliente descartado. - Código (v1.45.13, PR #286):
core/auth_api.py::_get_client_ipcogeXFF[0](cogía el último → habría logueado la IP del edge).admin_paths/rate_limit/signals/portalya eran correctos.
Always Use HTTPS = ON (desde 15-07-2026 · s224)
- Estado actual:
always_use_httpsON en la zone → 301 http→https en todo el edge, sin excepciones. La Redirect Rule custom que antes hacía ese trabajo (ruleset3f9451bc, phasehttp_request_dynamic_redirect, regla7366cc7e) se borró por redundante (0 reglas en el ruleset). - Por qué ahora se puede: hasta s222 estaba OFF a propósito, porque encendido rompía el reto HTTP-01 de Let’s Encrypt por el
:80(se redirigía a HTTPS antes de llegar al responder ACME de Traefik). En s222 PROD migró a renovación DNS-01 (TraefikdnsChallenge, providercloudflare) y se cerró el:80— HTTP-01 y su excepción/.well-known/dejaron de usarse, así que la excepción ya no protege nada. - Verificado E2E (15-07):
http://crearack.com/→ 301 → https ✓ ·http://crearack.com/.well-known/test→ 301 → https ✓ (la excepción ya no aplica, correcto) ·http://www.crearack.com/→ 301 https ✓ (el Workerwww-redirectsigue OK) ·https://crearack.com/→ 302/login(web viva) ✓. - El apex además redirige en el origen (308 de Traefik) — doble red.
Verificación E2E del 07-07 (todo en verde)
login 200 vía edge MAD · /admin 302 desde IP del equipo (la guardia de IPs funciona a través de la cadena) · IP real del visitante en logs de Daphne (93.176.x, no la del edge) · WSCONNECT del Agente local por websocket · security.txt del apex 200.
Barrido de superficie externa (12-07-2026 · s219) — F2 confirmado y :443 cerrado
Barrido pasivo con nuestras herramientas (curl/dig/TcpClient/SSH), no con herramienta ofensiva. Veredicto: superficie muy sana. OK: CSP estricta con nonces, X-Frame DENY, nosniff, Referrer/Permissions-Policy, COOP, TRACE→405, puerto 80→301, excepción ACME viva, security.txt en los 3 dominios, cert de origen con SAN solo crearack.com (no filtra internos), DNS sin subdominios candidatos (api/app/stage/dev/vpn/mail → NXDOMAIN), IP de origen ausente del DNS, workspace+esfericlabs tras CF Access.
- Scan TCP de
116.203.31.166: OPEN solo 22/80/443/3000; los 27 restantes (Postgres 5432, Valkey 6379, Docker API 2375/6, RDP 3389, mirror 8090, agent 5050…) FILTERED. El firewall base de Hetzner es sólido. - F2 CONFIRMADO explotable → MITIGADO (Fase 2a): el origen respondía el mismo
302 → /loginde la app en directo saltándose CF. Cerrado el:443directo a solo-CF el 12-07 (ver sección F2). Se mantiene: rate-limit (300) de la app y cabeceras de Django. - ✅ HSTS subido a 1 año + preload (15-07 · s224): el origen (Django) ya emitía
max-age=31536000; includeSubDomains; preload, pero CF lo recortaba a 15768000 (6 meses) sinpreload. Igualado en la zona (security_header) → vía CF ahora llegamax-age=31536000; includeSubDomains; preload(verificado). (El envío a hstspreload.org = decisión manual de Edu, no hecho.) - Higiene menor:
api.insecure: trueen Traefik (dashboard sin auth) — no expuesto (puerto filtrado), default de Dokploy. Enacme.jsonentrada residualEmail: test@localhost.com. Cosméticos.
F2 · cerrar el origen a solo-Cloudflare
✅ Fase 2a EJECUTADA (12-07-2026 · s219) — :443 cerrado
El firewall-CreaRack (Hetzner Cloud, ID 10679994) es COMPARTIDO por 4 servers (prod/staging/DCA/ops) y tenía 80/443 en 0.0.0.0/0. staging y DCA sirven :443 directo (no están tras CF), así que editar la regla compartida los habría roto. Solución: se creó firewall-crearack-prod (ID 11295929) solo para crearack-prod (server 121377067), replicando exactas las reglas (SSH 4 IPs, :80 abierto, ICMP, Dokploy :3000) salvo :443 restringido a los 22 rangos CF; se aplicó a prod y se quitó prod del firewall compartido (los otros 3 siguen igual). Verificado: :443 directo al origen = timeout · SSH ok · :80 directo = 301 · sitio vía CF = 302 vivo. Rollback: re-aplicar firewall-CreaRack a crearack-prod.
✅ Fase 1+2b HECHA (14-07-2026 · s222) — :80 cerrado con DNS-01
Traefik migrado de httpChallenge a dnsChallenge provider cloudflare (emisión DNS-01 real probada) → :80 cerrado en firewall-crearack-prod (SSL mode CF = strict). Con HTTP-01 fuera de juego, la excepción ACME /.well-known/ dejó de hacer falta, lo que habilitó poner always_use_https ON el 15-07 (sección arriba). Detalle: [[project_external_surface_audit_f2]] + concept--infra--hetzner-firewalls.
Otros pendientes de la sesión Security Center
- Vigilar la 1ª renovación LE tras el proxy (~16-08-2026) — task #185.
- ✅ HSTS: subido a 1 año + preload en CF el 15-07 (s224, ver arriba).
- DMARC
p=nonede channelassistance.com (Low, tema aparte).
Rollback (segundos)
- Registro A
crearack.com→ gris (proxied: false). - TLS/HTTPS: hoy
always_use_https= on (sin Redirect Rule). Para volver al esquema viejo (OFF + Redirect Rule con excepción/.well-known/) solo haría falta si se revirtiera DNS-01 → httpChallenge; no es el caso. - (Solo si molestan) Transform Rule y
trustedIPspueden quedarse: son inertes sin tráfico CF→origen. - Firewall F2: re-aplicar
firewall-CreaRackacrearack-prodreabre:443directo.
Límites conocidos (zone en plan Free)
- Subidas máx 100 MB/request vía apex (no tenemos uploads mayores).
- Requests >100 s cortadas por el edge (el SSE del Help emite continuo, no le afecta).
- La cuenta tiene Workers Paid (5 $/mes, para la CPU del Worker del workspace) — eso NO cambia los límites del proxy de la zone.
Token de gestión
Las piezas CF de esta página se gestionan con el token claude-cf-gaps (env var CF_CLAUDE_TOKEN en el perfil de Edu): Security Center Insights, Rulesets/Transform, Zone Settings, Page Rules y Redirección única (Single Redirects, añadido 07-07). El MCP de Cloudflare NO llega a esos scopes (lista OAuth fija). El firewall Hetzner se gestiona con un token HCLOUD_TOKEN de la Hetzner Cloud Console (usar y revocar).
Véase también
- [[concept—infra—ops-server]]