Problema
En entornos donde Autoloader (Authelia) protege aplicaciones como Jellyfin a través de un reverse proxy, es frecuente encontrarse con la pantalla de carga infinita y el mensaje Redirection was determined to be unsafe and aborted. El navegador bloquea la redirección porque la URL de destino no pasa las validaciones de seguridad del propio Authelia. El síntoma se manifiesta después de una autenticación exitosa: Authelia muestra su página de login, pero al intentar acceder a la aplicación protegida el flujo se detiene.
Este patrón no es exclusivo de Jellyfin; cualquier servicio que dependa de auth_request en Nginx Proxy Manager (NPM) y que reciba la URL de retorno a través del parámetro rd puede colapsar si la URL no coincide exactamente con lo que Authelia considera “seguro”. El problema suele aparecer cuando se combinan:
- Cloudflare Tunnel (o cualquier túnel que reescriba el esquema/host)
- NPM configurado con
proxy_set_headerpersonalizados - Dominios wildcard y redirecciones entre sub‑dominios
Causa
-
Desajuste entre
authelia_urly el host recibido por Authelia
Authelia valida que la URL de retorno (rd) pertenezca al dominio configurado endefault_redirection_urlo a los dominios listados enaccess_control.rules. Si el proxy envíaHostdistinto (por ejemplo,jelly.sampledomain.comen vez deauthelia.sampledomain.com), la validación falla. -
Esquema incorrecto (http vs https)
Cuando el túnel de Cloudflare termina en NPM con HTTPS pero la petición interna a Authelia se hace por HTTP, la URL construida por NPM ($scheme://$http_host$request_uri) llevahttp. Authelia interpreta que la redirección lleva a un esquema no seguro y la aborta. -
Cabecera
X-Forwarded-Protomal propagada
Si el proxy no reenvíaX-Forwarded-Proto: https, Authelia asume que la petición original fue HTTP y genera una URL de retorno conhttp. Los navegadores modernos bloquean la transición dehttpsahttpen redirecciones automáticas. -
Uso de
auth_request_set $target_url $scheme://$http_host$request_urisin normalizar
$http_hostincluye el puerto si está presente (por ejemplo,jelly.sampledomain.com:443). Authelia no reconoce el puerto y descarta la URL. -
Cloudflare Tunnel elimina la cabecera
CF-Connecting-IPy la reemplaza por la IP del túnel
Cuando NPM confía enreal_ip_header CF-Connecting-IP, la IP del cliente se pierde y la política de “one_factor” puede no aplicarse, provocando un ciclo de redirección.
Solución
1. Normalizar la URL de retorno en NPM
Reemplaza la construcción de $target_url por una versión que fuerce https y elimine el puerto:
set $target_url https://$host$request_uri;
Esto garantiza que Authelia siempre reciba una URL con esquema seguro y sin puerto inesperado.
2. Asegurar la propagación de X-Forwarded-Proto
Añade explícitamente la cabecera antes de la directiva auth_request:
proxy_set_header X-Forwarded-Proto $scheme;
Si el túnel termina en HTTP pero el cliente usa HTTPS, fuerza la variable:
map $http_x_forwarded_proto $forwarded_proto {
default $http_x_forwarded_proto;
"" $scheme;
}
proxy_set_header X-Forwarded-Proto $forwarded_proto;
3. Ajustar authelia_url y default_redirection_url
En configuration.yml de Authelia, usa la URL pública completa del proxy:
authelia_url: 'https://authelia.sampledomain.com'
default_redirection_url: 'https://jelly.sampledomain.com'
Asegúrate de que cualquier sub‑dominio que pueda aparecer en rd esté cubierto por una regla domain con política one_factor o bypass.
4. Simplificar la regla auth_request
En el bloque location / del host de Jellyfin, elimina la variable $target_url y usa la variable interna $request_uri combinada con https://$host:
auth_request_set $target_url https://$host$request_uri;
error_page 401 =302 https://authelia.sampledomain.com?rd=$target_url;
5. Revisar la configuración de Cloudflare Tunnel
En el archivo de túnel (config.yml), habilita ingress con service: https://nginx-proxy-manager:443 y marca originRequest: { noTLSVerify: true } solo si el certificado interno es auto‑firmado. Evita que el túnel convierta HTTPS a HTTP antes de llegar a NPM.
6. Verificar la lista de “Known Proxies” en Jellyfin
Añade la IP del túnel de Cloudflare (<tunnel_ip>) y la IP interna de NPM (<npm_ip>) a Known Proxy. Esto evita que Jellyfin rechace la cabecera X-Forwarded-For.
Cuándo aplicar esta solución
- Aparecen errores de redirección insegura después de una autenticación exitosa con Authelia.
- El flujo funciona cuando se accede directamente a Authelia, pero falla al llegar a la aplicación protegida.
- Se está usando Cloudflare Tunnel, NPM o cualquier otro túnel que termine en HTTP detrás de un front‑end HTTPS.
- La política de
access_control.rulesincluye dominios wildcard y se confía enauth_request.
No es necesario aplicar estos cambios si:
- La aplicación no depende de
auth_request(por ejemplo, uso de plugin interno de Authelia). - Todas las peticiones llegan directamente a Authelia sin pasar por un túnel que altere el esquema.
Código
# 1. Editar el bloque de Jellyfin en NPM
cat > /etc/nginx/conf.d/jellyfin.conf <<'EOF'
server {
listen 443 ssl http2;
server_name jelly.sampledomain.com;
# SSL config (omitido para brevedad)
real_ip_header CF-Connecting-IP;
location / {
auth_request /authelia;
auth_request_set $target_url https://$host$request_uri;
error_page 401 =302 https://authelia.sampledomain.com?rd=$target_url;
proxy_pass http://jellyfin:8096;
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;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /authelia {
internal;
proxy_pass http://authelia:9091/api/verify;
proxy_set_header Host $http_host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
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;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
}
EOF
# 2. Reiniciar NPM
docker exec -it nginx-proxy-manager nginx -s reload
Verificación
- Accede a
https://authelia.sampledomain.com. Inicia sesión. - Cuando la página redirija a
https://jelly.sampledomain.com, verifica que la barra de direcciones muestrahttpsy que no aparece el mensaje de redirección insegura. - En los logs de Authelia (
/config/notification.txtostdoutdel contenedor) busca entradasAuthentication succeededyRedirect URL: https://jelly.sampledomain.com/.... - En los logs de NPM, confirma que la petición a
/autheliadevuelve200y que no hay líneas401seguidas de302conrd=que contengahttp://.
Notas adicionales
- Cuando se usan sub‑dominios wildcard, siempre declara una regla explícita en
access_control.rulespara cada sub‑dominio que pueda aparecer enrd. Authelia no interpreta*.example.comen la lista de dominios permitidos. - Si el túnel de Cloudflare está configurado en modo “http2” pero el backend NPM solo escucha en HTTP, habilita
proxy_set_header X-Forwarded-Proto https;de forma estática. - En entornos con varios proxies (por ejemplo, Cloudflare + NPM + Traefik), la cadena de cabeceras
X-Forwarded-Forpuede crecer. Usareal_ip_recursive on;y limita la lista deset_real_ip_froma las IPs de tus proxies para evitar que una IP externa sea tratada como cliente. - La opción “Force SSL” de NPM no es necesaria cuando el túnel ya garantiza HTTPS; sin embargo, habilitar
strict-transport-securityen el bloqueserverayuda a evitar que navegadores intenten cargar recursos por HTTP.