Caddy detrás de Nginx, El problema del SNI
![]()
Caddy está diseñado para trabajar de forma automática con TLS. Gestiona certificados, valida el Host y sirve contenido en función del dominio solicitado. Cuando recibe una conexión HTTPS, utiliza el SNI para decidir qué certificado presentar.
Si Nginx actúa como proxy inverso y se conecta a Caddy mediante HTTPS (por ejemplo, proxy_pass https://backend;), pero no envía el SNI correctamente, pueden ocurrir varios problemas:
- Error de certificado inválido.
- Caddy devuelve el certificado incorrecto.
- Respuesta 502 Bad Gateway en Nginx.
- Fallos en validaciones TLS internas.
Esto sucede porque, por defecto, Nginx no siempre reenvía el nombre del servidor esperado en la negociación TLS con el upstream.
¿Qué hacen estas directivas?
proxy_ssl_server_name on;
Activa el envío del Server Name Indication (SNI) en la conexión TLS hacia el backend.
Sin esta directiva, Nginx establece la conexión HTTPS, pero no indica a Caddy qué dominio está solicitando.
proxy_ssl_name $host;
Define qué nombre de servidor se enviará como SNI.
Usando $host, Nginx enviará el mismo hostname que recibió del cliente original. Esto es lo correcto en la mayoría de arquitecturas multi-dominio o multi-certificado.
Ejemplo completo de configuración
server {
listen 443 ssl;
server_name ejemplo.com;
proxy_ssl_server_name on;
proxy_ssl_name $host;location / {
proxy_pass https://caddy_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Con esta configuración:
- Nginx recibe HTTPS del cliente.
- Nginx se conecta por HTTPS a Caddy.
- Se envía correctamente el SNI.
- Caddy selecciona el certificado adecuado.
- Se evita cualquier problema TLS.
¿Cuándo es obligatorio?
Estas directivas son necesarias cuando:
- Caddy sirve múltiples dominios con certificados distintos.
- Caddy utiliza certificados automáticos (Let’s Encrypt).
- El upstream se define como hostname y no como IP fija.
- Se utiliza validación estricta de certificado en Nginx.
Si en cambio estás usando HTTP interno (sin TLS entre Nginx y Caddy), no es necesario.
Buenas prácticas en esta arquitectura
Si decides poner Caddy detrás de Nginx, asegúrate de:
- No duplicar gestión de certificados innecesariamente.
- Decidir claramente quién termina TLS (edge vs backend).
- Configurar correctamente los headers
X-Forwarded-*. - Ajustar
proxy_ssl_verifysi estás validando certificados internos.
En entornos pequeños puede ser redundante tener ambos servidores haciendo TLS, pero en arquitecturas más complejas (WAF delante, balanceo avanzado, etc.) puede estar totalmente justificado.
Conclusión
Si usas Caddy detrás de Nginx y la conexión al backend es HTTPS, debes añadir obligatoriamente:
proxy_ssl_server_name on;
proxy_ssl_name $host;Sin estas líneas, el handshake TLS puede fallar porque Nginx no envía el SNI correcto, lo que impide que Caddy entregue el certificado adecuado.
Es un detalle pequeño, pero crítico en arquitecturas modernas con múltiples dominios y certificados automáticos.
