TLS Offloading
Configurez Traefik derrière un équilibreur de charge qui termine le TLS (App Gateway / ALB / GCP LB), gardez l'ingress privé et dépannez les erreurs 502 Bad Gateway.
Ces paramètres s'appliquent à votre release Traefik, pas au chart Scrydon. Le chart Scrydon ne provisionne jamais de contrôleur d'ingress ; il génère uniquement les objets Ingress que votre contrôleur route.
Derrière un équilibreur de charge qui termine le TLS
Si un équilibreur de charge en amont termine le TLS et transmet du HTTP brut à Traefik — Azure Application Gateway, AWS ALB, GCP HTTP(S) LB, F5 — Traefik doit être configuré pour faire confiance à la plage d'IP source de cet équilibreur. Sans cela, trois symptômes apparaissent :
- Boucles de redirection HTTP → HTTPS. Traefik voit du HTTP brut et redirige vers HTTPS ; l'équilibreur termine à nouveau le TLS et transmet du HTTP. Le navigateur tourne en boucle.
- Mauvaise IP cliente. Les limites de débit par IP et les journaux d'audit enregistrent l'IP de l'équilibreur plutôt que celle du vrai client.
- La connexion semble fonctionner, puis le cookie de session disparaît au prochain clic. Better-Auth lit
x-forwarded-protopour calculer son schéma public. Quand Traefik le réécrit enhttp, le cookie sécurisé est rejeté ou le POST cross-origin est refusé — pas de boucle de redirection, pas de 5xx, juste un « je suis déconnecté » silencieux.
Deux conditions doivent être réunies :
- Traefik doit voir l'IP source réelle de l'équilibreur au niveau TCP. La valeur par défaut
externalTrafficPolicy: Clusterfait que kube-proxy effectue un SNAT vers l'IP du nœud avant que Traefik le reçoive. DéfinirLocalpour préserver l'IP source en amont. - Les entrypoints doivent lister le CIDR source de l'équilibreur comme fiable, afin que Traefik honore les en-têtes
X-Forwarded-*qu'il envoie.
# traefik-values.yaml — votre release Traefik, pas le chart Scrydon.
service:
spec:
externalTrafficPolicy: Local
ports:
web:
forwardedHeaders:
trustedIPs:
- 10.0.1.0/24 # le sous-réseau depuis lequel l'équilibreur transmet (App Gateway, pare-feu, …)
websecure:
forwardedHeaders:
trustedIPs:
- 10.0.1.0/24helm upgrade --install traefik traefik/traefik \
--namespace traefik --create-namespace \
-f traefik-values.yamltrustedIPs est une liste — utilisez un fichier de valeurs, pas le style --set. Un --set inline fonctionne pour une valeur unique, mais devient fragile avec --reuse-values lors des mises à jour suivantes.
Cela complète le middleware force-https du chart Scrydon (ingress.middleware.forceHttps, activé par défaut). Ce middleware s'exécute après la logique des entrypoints de Traefik — il ne stoppe pas la boucle de redirection ni ne restaure l'IP cliente par lui-même.
Raccourci de diagnostic
Si vous suspectez ce problème sans connaître le bon CIDR, faites temporairement confiance à tout :
helm upgrade traefik traefik/traefik -n traefik --reuse-values \
--set "ports.web.forwardedHeaders.insecure=true" \
--set "ports.websecure.forwardedHeaders.insecure=true"Si le symptôme disparaît, lisez l'IP source depuis les journaux d'accès (kubectl logs -n traefik -l app.kubernetes.io/name=traefik | rg ClientAddr), convertissez-la en CIDR de sous-réseau, définissez trustedIPs et désactivez à nouveau insecure. Laisser insecure: true en production permet à n'importe quelle charge de travail de falsifier les en-têtes X-Forwarded-*.
ingress.tls.enabled — schéma public, pas protocole backend
C'est un piège classique :
ingress.tls.enabledest l'interrupteur « Scrydon est-il accessible via HTTPS par le navigateur ? » — ce n'est pas un bouton « Traefik termine-t-il le TLS ».
Le chart l'utilise pour dériver le schéma de chaque URL que les applications publient (APP_URL, URL de callback Better-Auth, liste d'autorisation CORS) et pour piloter le comportement des cookies sécurisés. false → les applications émettent des URL http:// ; true → https://.
Derrière un App Gateway qui sert le site en HTTPS, définissez ingress.tls.enabled: true même si l'équilibreur transmet du HTTP brut au cluster.
ingress:
enabled: true
tls:
enabled: true # le navigateur utilise https → mettre true quel que soit le saut backend
clusterIssuer: letsencrypt-prod
routing:
mode: subpath
host: app.example.com # doit être égal au nom d'hôte du listener App GatewaySi le navigateur utilise https:// mais que tls.enabled: false, le chart publie http://. Les navigateurs rejettent les cookies sécurisés et Better-Auth rebondit les callbacks de connexion comme des incompatibilités d'origine. L'interface se charge, mais on ne peut jamais terminer la connexion.
Ce que le protocole backend détermine — si Traefik lui-même a besoin d'un vrai certificat :
| App Gateway → Traefik | Traefik a-t-il besoin d'un certificat ? |
|---|---|
| HTTP / port 80 (TLS offload — le cas le plus courant) | Non. App Gateway détient le seul certificat. |
| HTTPS / port 443 (re-chiffrement / bout en bout) | Oui. Traefik doit terminer le TLS backend — a besoin d'un certificat utilisable dans tls-frontdoor (mode sous-chemin) ou dans des secrets par application (mode sous-domaine). |
Cert-manager + défi HTTP-01 derrière un App Gateway : le chemin /.well-known/acme-challenge/… n'est généralement pas accessible publiquement, donc l'émission échoue. Pour le cas de déchargement HTTP/80, c'est sans conséquence (Scrydon a seulement besoin du schéma, pas d'un vrai certificat). Pour le re-chiffrement HTTPS/443, optez pour DNS-01, pré-créez le secret TLS avec votre propre certificat, ou comptez sur App Gateway qui ne pinne pas une racine backend.
Garder l'ingress privé
Le chart Scrydon ne provisionne jamais d'IP publique. Tous les Services sont ClusterIP. L'IP externe provient du contrôleur Traefik (type LoadBalancer par défaut).
Pour donner à Traefik une adresse privée VNet/VPC, annotez son Service :
# traefik-values.yaml
service:
annotations:
# AKS
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
# AWS EKS
# service.beta.kubernetes.io/aws-load-balancer-internal: "true"
# GKE
# networking.gke.io/load-balancer-type: "Internal"
spec:
externalTrafficPolicy: Local
ports:
web:
forwardedHeaders:
trustedIPs: [10.0.1.0/24]
websecure:
forwardedHeaders:
trustedIPs: [10.0.1.0/24]helm upgrade --install traefik traefik/traefik \
--namespace traefik --create-namespace \
-f traefik-values.yaml
kubectl -n traefik get svc traefik
# EXTERNAL-IP devrait être une adresse privée VNet/VPC (ex. 10.0.x.x).Reconfigurez ensuite le pool backend de l'équilibreur en amont pour pointer vers cette IP Traefik privée.
externalTrafficPolicy: Local oblige l'équilibreur cloud à sonder chaque nœud et à ne transmettre qu'aux nœuds qui exécutent un pod Traefik. Faites tourner ≥ 2 répliques Traefik réparties sur les nœuds (le chart le fait par défaut) — le drain d'un seul nœud peut sinon couper l'ingress.
Dépannage des erreurs 502 Bad Gateway
Une 502 de l'équilibreur en amont signifie que son pool backend est en mauvaise santé — la requête n'a jamais reçu de bonne réponse de Traefik. Les changements trustedIPs modifient la façon dont Traefik interprète les requêtes ; ils ne rendent pas le backend accessible.
Isolez le saut défaillant depuis le pod vers l'extérieur :
# 1. Le backend Scrydon est-il en bonne santé ?
kubectl -n scrydon-platform get pods # tous Running, 2/2 avec le sidecar Dapr ?
# 2. Traefik route-t-il la requête ? Envoyez le vrai en-tête Host directement à Traefik.
curl -i -H "Host: app.example.com" http://<traefik-ip>/platform
# 200/3xx → Traefik fonctionne ; cherchez en amont au niveau de l'équilibreur.
# 404 → l'en-tête Host ne correspond pas à `routing.host`.
# 502/503 → Traefik n'a pas de backend sain → retourner à l'étape 1.Causes habituelles :
- Le pool backend pointe vers une IP Traefik périmée — ex. vous avez basculé Traefik de public vers interne et l'équilibreur cible encore l'ancienne IP publique.
- Le paramètre HTTP backend utilise HTTPS ou le mauvais port. Traefik reçoit du HTTP sur
:80(web) ; le paramètre backend de l'équilibreur doit être HTTP / port 80. - La sonde de santé reçoit une redirection ou une incompatibilité de Host. Pointez vers un chemin servi par Scrydon, envoyez
routing.hostcomme Host, acceptez200–399. Si la sonde reçoit encore301 → https, Traefik réécritX-Forwarded-Proto— définissezexternalTrafficPolicy: Localet vérifiez que le CIDRtrustedIPscorrespond au sous-réseau de l'équilibreur (pas à celui du client).