Aller au contenu
medium

Middlewares Traefik : transformez et sécurisez vos requêtes

32 min de lecture

Logo traefik

Ce guide vous apprend à configurer les middlewares Traefik en construisant pas à pas un environnement de test. Chaque middleware est présenté avec un cas d’usage, une configuration minimale, et une commande curl pour valider que ça fonctionne.

À la fin, vous saurez :

  • Protéger une API avec rate limiting et headers de sécurité
  • Sécuriser un backoffice avec authentification et filtrage IP
  • Exposer un site public avec compression et protection anti-abus

Public cible : développeurs et ops utilisant Traefik comme reverse proxy.

Prérequis : Docker installé. Ce guide utilise Docker Compose pour le lab.

Vous êtes pressé ? Allez directement au middleware qui vous intéresse :

BesoinMiddlewareSection
Supprimer /api de l’URLstripPrefixRéécriture
Ajouter un préfixeaddPrefixRéécriture
Protection par mot de passebasicAuthAuthentification
SSO (Authelia, Keycloak)forwardAuthAuthentification
Limiter les requêtes/seconderateLimitProtection
Filtrer par IPipAllowListProtection
Limiter requêtes simultanéesinFlightReqProtection
Couper si backend KOcircuitBreakerProtection
Headers de sécuritéheadersRéponse
CORSheaders (CORS)Réponse
Compression gzip/brotlicompressRéponse
HTTP → HTTPSredirectSchemeRedirections
Grouper des middlewareschainChaînage

Recettes prêtes à copier :

Tout le guide repose sur ce lab. Vous allez créer un environnement Traefik + whoami qui sert de terrain d’expérimentation pour tous les middlewares.

traefik-lab/
├── docker-compose.yml
├── traefik.yml # Config statique
└── config/
└── middlewares.yml # Middlewares (config dynamique)

1. docker-compose.yml

services:
traefik:
image: traefik:v3.2
ports:
- "80:80"
- "8080:8080" # Dashboard
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./config:/etc/traefik/config:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- "traefik.enable=true"
# Service de test principal
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
# API de test (même image, route différente)
api:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`whoami.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.api.entrypoints=web"

2. traefik.yml (config statique)

api:
dashboard: true
insecure: true # Dashboard sans auth (lab uniquement)
entryPoints:
web:
address: ":80"
providers:
docker:
exposedByDefault: false
file:
directory: /etc/traefik/config
watch: true
log:
level: INFO

3. config/middlewares.yml (vide pour l’instant)

http:
middlewares: {}
Fenêtre de terminal
mkdir -p traefik-lab/config
cd traefik-lab
# Créer les fichiers ci-dessus, puis :
docker compose up -d
Fenêtre de terminal
# Site principal
curl http://whoami.localhost
# → Affiche infos whoami (IP, headers...)
# Route API
curl http://whoami.localhost/api
# → Même chose, mais via /api
# Dashboard Traefik
open http://localhost:8080

Le lab est prêt. Tous les exemples qui suivent utilisent ce setup.

TermeDéfinition
MiddlewareFonction qui intercepte une requête entre le client et le backend pour la transformer ou la bloquer
ChainGroupe de middlewares exécutés dans l’ordre
RouterRègle qui détermine vers quel service envoyer la requête
ServiceCible de la requête (backend, load balancer)
EntrypointPort d’écoute de Traefik (ex: 80, 443)
AuthNAuthentification — vérifier l’identité (“qui êtes-vous ?”)
AuthZAutorisation — vérifier les permissions (“avez-vous le droit ?”)
Token bucketAlgorithme de rate limiting : un “seau” se remplit de tokens, chaque requête en consomme un
SSEServer-Sent Events — flux de données en temps réel du serveur vers le client
CORSCross-Origin Resource Sharing — mécanisme permettant à un site d’accéder à des ressources d’un autre domaine

Flux d'une requête à travers Traefik

Un middleware s’exécute après que le routeur a décidé où va la requête, et avant qu’elle n’atteigne le backend. Il peut :

  • Bloquer la requête (rate limit, auth, IP filter)
  • Transformer la requête (strip prefix, add header)
  • Modifier la réponse (headers, compression)

Règle d’or : “Bloquer tôt, transformer tard”

Section intitulée « Règle d’or : “Bloquer tôt, transformer tard” »

L’ordre des middlewares est critique. Appliquez cette règle :

Ordre des middlewares : bloquer tôt, transformer tard

Pourquoi ?

  1. Bloquer tôt économise des ressources : inutile d’authentifier une IP bannie
  2. Transformer tard garantit que les modifications passent au backend/client
ÉtapeMiddlewaresObjectif
1ipAllowList, rateLimit, inFlightReqBloquer les abus
2basicAuth, forwardAuthVérifier l’identité
3stripPrefix, addPrefix, replacePathRéécrire les chemins
4headers (response)Ajouter headers de sécurité
5compressCompresser la réponse

Avant de détailler chaque middleware, voici 3 chains complètes couvrant 90% des cas d’usage. Copiez celle qui correspond à votre besoin.

Objectif : protection anti-abus + headers de sécurité + compression.

config/middlewares.yml
http:
middlewares:
chain-public-web:
chain:
middlewares:
- rate-limit-web
- secure-headers-web
- compress-web
rate-limit-web:
rateLimit:
average: 100
burst: 200
secure-headers-web:
headers:
frameDeny: true
contentTypeNosniff: true
stsSeconds: 31536000
stsIncludeSubdomains: true
compress-web:
compress:
excludedContentTypes:
- text/event-stream

Appliquer au lab (docker-compose.yml) :

whoami:
labels:
- "traefik.http.routers.whoami.middlewares=chain-public-web@file"

✅ Vérifier :

Fenêtre de terminal
# Headers de sécurité présents
curl -I http://whoami.localhost
# → X-Frame-Options: DENY
# → X-Content-Type-Options: nosniff
# → Strict-Transport-Security: max-age=31536000
# Compression active
curl -H "Accept-Encoding: gzip" -I http://whoami.localhost
# → Content-Encoding: gzip

Recette B — Backoffice interne (admin, outils internes)

Section intitulée « Recette B — Backoffice interne (admin, outils internes) »

Objectif : accès restreint par IP + authentification SSO.

http:
middlewares:
chain-internal-app:
chain:
middlewares:
- ip-filter-internal
- auth-internal
- secure-headers-internal
ip-filter-internal:
ipAllowList:
sourceRange:
- "10.0.0.0/8"
- "192.168.0.0/16"
- "172.16.0.0/12"
auth-internal:
forwardAuth:
address: http://authelia:9091/api/verify
trustForwardHeader: false
authResponseHeaders:
- X-Forwarded-User
secure-headers-internal:
headers:
frameDeny: true
contentTypeNosniff: true

✅ Vérifier :

Fenêtre de terminal
# Depuis une IP non autorisée → 403
curl http://admin.localhost
# → 403 Forbidden
# Depuis une IP autorisée, sans auth → 401 (ou redirect SSO)
curl http://admin.localhost
# → 401 Unauthorized

Objectif : rate limiting strict + CORS + headers de sécurité.

http:
middlewares:
chain-api:
chain:
middlewares:
- rate-limit-api
- cors-api
- secure-headers-api
rate-limit-api:
rateLimit:
average: 60
burst: 100
period: 1m
sourceCriterion:
ipStrategy:
depth: 1
cors-api:
headers:
accessControlAllowMethods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
accessControlAllowHeaders:
- Authorization
- Content-Type
accessControlAllowOriginList:
- "https://app.example.com"
accessControlMaxAge: 86400
secure-headers-api:
headers:
contentTypeNosniff: true
customResponseHeaders:
Cache-Control: "no-store"

Appliquer au lab :

api:
labels:
- "traefik.http.routers.api.middlewares=chain-api@file"

✅ Vérifier :

Fenêtre de terminal
# CORS headers présents
curl -I -X OPTIONS http://whoami.localhost/api \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST"
# → Access-Control-Allow-Origin: https://app.example.com
# Rate limit (envoyer 200 requêtes)
for i in {1..200}; do curl -s -o /dev/null -w "%{http_code}\n" http://whoami.localhost/api; done
# → 429 Too Many Requests après dépassement

Maintenant, détaillons chaque middleware avec une structure répétable :

  1. 🟢 Quand l’utiliser (+ 2 cas concrets)
  2. 🔴 Quand ne pas l’utiliser
  3. Configuration minimale
  4. ✅ Vérifier (test curl)
  5. Pièges fréquents
  6. 🟠 Variante avancée (optionnel)

Ces middlewares modifient l’URL avant qu’elle n’atteigne le backend.

🟢 Quand l’utiliser :

  • Vous exposez /api/users mais le backend attend /users
  • Vous avez un préfixe de versioning (/v1/...) que le backend ne comprend pas

🔴 Quand ne pas l’utiliser :

  • Le backend gère déjà le préfixe (framework avec routing)

Configuration minimale :

config/middlewares.yml
http:
middlewares:
strip-api:
stripPrefix:
prefixes:
- /api

Appliquer au lab :

api:
labels:
- "traefik.http.routers.api.middlewares=strip-api@file"

✅ Vérifier :

Fenêtre de terminal
# Requête vers /api/test
curl http://whoami.localhost/api/test
# → Dans la sortie whoami : "GET /test HTTP/1.1"
# (le /api a été retiré)

Pièges fréquents :

  • Le backend renvoie des URLs avec le chemin original (sans /api) → les liens internes cassent
  • Oublier que stripPrefix laisse un / initial : /api/users/users (pas users)

🟠 Variante avancée — StripPrefixRegex :

strip-versions:
stripPrefixRegex:
regex:
- "^/v[0-9]+/"

Retire /v1/, /v2/, etc.

🟢 Quand l’utiliser :

  • Le backend attend un préfixe que vous ne voulez pas exposer
  • Migration : ancien chemin → nouveau chemin interne

🔴 Quand ne pas l’utiliser :

  • Le prefixe est déjà dans l’URL du client

Configuration minimale :

http:
middlewares:
add-v2:
addPrefix:
prefix: /v2

✅ Vérifier :

Fenêtre de terminal
curl http://whoami.localhost/users
# → Backend reçoit : "GET /v2/users HTTP/1.1"

Pièges fréquents :

  • Double préfixe si combiné avec stripPrefix dans le mauvais ordre

🟢 Quand l’utiliser :

  • Rediriger toutes les requêtes d’une route vers un chemin fixe
  • Endpoint de health check unique

🔴 Quand ne pas l’utiliser :

  • Vous voulez conserver une partie du chemin original

Configuration minimale :

http:
middlewares:
health-redirect:
replacePath:
path: /health

✅ Vérifier :

Fenêtre de terminal
curl http://whoami.localhost/anything
# → Backend reçoit : "GET /health HTTP/1.1"

🟢 Quand l’utiliser :

  • Protection rapide d’un service interne (dev, staging)
  • Accès temporaire à un outil sans SSO

🔴 Quand ne pas l’utiliser :

  • En production sans HTTPS (credentials en clair !)
  • Applications avec beaucoup d’utilisateurs (pas de gestion de sessions)

Configuration minimale :

Fenêtre de terminal
# Générer le hash (bcrypt recommandé)
htpasswd -nbB admin "monsecret"
# → admin:$2y$05$...
http:
middlewares:
basic-auth:
basicAuth:
users:
- "admin:$2y$05$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Appliquer au lab :

whoami:
labels:
- "traefik.http.routers.whoami.middlewares=basic-auth@file"

✅ Vérifier :

Fenêtre de terminal
# Sans credentials → 401
curl http://whoami.localhost
# → 401 Unauthorized
# Avec credentials → 200
curl -u admin:monsecret http://whoami.localhost
# → Réponse whoami

Pièges fréquents :

  • Hash mal généré (MD5 au lieu de bcrypt) → refusé
  • Oublier d’échapper les $ dans Docker labels
  • Utiliser en production sans HTTPS

🟠 Variante avancée — Fichier htpasswd :

basic-auth-file:
basicAuth:
usersFile: /etc/traefik/htpasswd
removeHeader: true # Ne pas transmettre le header au backend

🟢 Quand l’utiliser :

  • SSO avec Authelia, Keycloak, Authentik
  • Authentification centralisée multi-services

🔴 Quand ne pas l’utiliser :

  • Service interne simple (préférez BasicAuth)
  • Le service auth n’est pas résilient (single point of failure)

Configuration minimale :

http:
middlewares:
auth-sso:
forwardAuth:
address: http://authelia:9091/api/verify
authResponseHeaders:
- X-Forwarded-User
- X-Forwarded-Groups

✅ Vérifier :

Fenêtre de terminal
# Sans session → 401 ou 302 (redirect vers login)
curl -I http://whoami.localhost
# → HTTP/1.1 302 Found
# → Location: https://auth.example.com/login?rd=...
# Avec cookie de session valide → 200
curl -b "authelia_session=xxx" http://whoami.localhost

Pièges fréquents :

  • trustForwardHeader: true sans proxy de confiance → usurpation d’identité
  • authResponseHeaders mal configuré → headers sensibles transmis au client (smuggling)
  • Service auth lent → augmenter les timeouts

🟠 Variante avancée — trustForwardHeader :

auth-behind-proxy:
forwardAuth:
address: http://authelia:9091/api/verify
trustForwardHeader: true # SEULEMENT si derrière un proxy de confiance
authResponseHeaders:
- X-Forwarded-User

🟢 Quand l’utiliser :

  • Clients qui ne supportent pas BasicAuth moderne
  • Légèrement plus sécurisé que BasicAuth (pas de mot de passe en clair)

🔴 Quand ne pas l’utiliser :

  • En production (HTTPS + BasicAuth bcrypt est meilleur)
  • Applications modernes (préférez ForwardAuth + SSO)

Configuration minimale :

http:
middlewares:
digest-auth:
digestAuth:
users:
- "admin:traefik:hash"

Voir la documentation officielle pour la génération du hash.

🟢 Quand l’utiliser :

  • Protéger une API contre les abus
  • Éviter qu’un client monopolise les ressources

🔴 Quand ne pas l’utiliser :

  • Services internes entre microservices (latence ajoutée)
  • Quand vous avez un WAF en amont qui fait déjà du rate limiting

Configuration minimale :

http:
middlewares:
rate-limit:
rateLimit:
average: 10 # 10 req/s en moyenne
burst: 20 # Jusqu'à 20 en rafale

Appliquer au lab :

api:
labels:
- "traefik.http.routers.api.middlewares=rate-limit@file"

✅ Vérifier :

Fenêtre de terminal
# Envoyer 30 requêtes rapidement
for i in {1..30}; do
curl -s -o /dev/null -w "%{http_code} " http://whoami.localhost/api
done
# → 200 200 200 ... 429 429 429

Pièges fréquents :

  • sourceCriterion.requestHeaderName avec un header spoofable (X-Real-IP) → bypass
  • Oublier que Traefik utilise un token bucket (le burst permet des pics)
  • Rate limit trop agressif → faux positifs pour les utilisateurs légitimes

🟠 Variante avancée — Par API key :

rate-limit-by-key:
rateLimit:
average: 100
burst: 200
period: 1m
sourceCriterion:
requestHeaderName: X-API-Key # SEULEMENT émis par un service de confiance

🟢 Quand l’utiliser :

  • Restreindre l’accès à un backoffice par IP
  • Whitelister des partenaires ou un VPN

🔴 Quand ne pas l’utiliser :

  • IPs dynamiques (FAI résidentiels)
  • Alternative à l’authentification (IP != identité)

Configuration minimale :

http:
middlewares:
ip-whitelist:
ipAllowList:
sourceRange:
- "192.168.1.0/24"
- "10.0.0.0/8"

✅ Vérifier :

Fenêtre de terminal
# Depuis une IP autorisée → 200
curl http://whoami.localhost
# Depuis une IP non autorisée → 403
curl http://whoami.localhost
# → 403 Forbidden

Pièges fréquents :

  • Oublier ipStrategy.depth derrière un load balancer → bloque le LB, pas le client
  • Plages CIDR mal calculées

🟠 Variante avancée — Derrière un proxy :

ip-whitelist-behind-lb:
ipAllowList:
sourceRange:
- "192.168.1.0/24"
ipStrategy:
depth: 1 # Prend l'IP dans X-Forwarded-For

InFlightReq — Limiter les requêtes simultanées

Section intitulée « InFlightReq — Limiter les requêtes simultanées »

🟢 Quand l’utiliser :

  • Protéger un backend fragile contre la surcharge
  • Limiter le nombre de connexions longues (websockets, SSE)

🔴 Quand ne pas l’utiliser :

  • APIs stateless rapides (rate limit est plus adapté)

Configuration minimale :

http:
middlewares:
inflight:
inFlightReq:
amount: 10 # Max 10 requêtes simultanées par source

✅ Vérifier :

Fenêtre de terminal
# Lancer 20 requêtes lentes en parallèle
for i in {1..20}; do
curl -s "http://whoami.localhost/api?delay=5s" &
done
# → Les 10 premières passent, les suivantes reçoivent 503

Pièges fréquents :

  • Confondre avec rate limit (qui compte sur le temps, pas les requêtes actives)
  • sourceCriterion mal configuré → limite globale au lieu de par IP

🟢 Quand l’utiliser :

  • Protéger les utilisateurs d’un backend instable
  • Éviter de saturer un service défaillant avec des retries

🔴 Quand ne pas l’utiliser :

  • Backend toujours sain (overhead inutile)
  • Quand vous préférez des erreurs explicites (fail fast)

Configuration minimale :

http:
middlewares:
circuit-breaker:
circuitBreaker:
expression: "NetworkErrorRatio() > 0.30"

Comportement : si plus de 30% des requêtes échouent (erreurs réseau), le circuit s’ouvre et renvoie 503 pendant fallbackDuration (10s par défaut).

✅ Vérifier :

Difficile à tester sans simuler des erreurs backend. En lab, vous pouvez arrêter le service whoami :

Fenêtre de terminal
docker compose stop whoami
# Les requêtes vers whoami déclenchent le circuit après quelques échecs

Pièges fréquents :

  • Expression mal calibrée → circuit s’ouvre trop vite ou jamais
  • Oublier checkPeriod et recoveryDuration pour le retour à la normale

🟠 Variante avancée — Paramètres de timing :

circuit-breaker-tuned:
circuitBreaker:
expression: "NetworkErrorRatio() > 0.25 || ResponseCodeRatio(500, 600, 0, 600) > 0.30"
checkPeriod: 10s # Fréquence de vérification
fallbackDuration: 15s # Durée en mode "ouvert"
recoveryDuration: 30s # Durée de récupération progressive

🟢 Quand l’utiliser :

  • Toujours sur les services web (HSTS, X-Frame-Options, CSP)
  • Ajouter des headers métier (X-Request-ID, X-API-Version)

🔴 Quand ne pas l’utiliser :

  • Le backend gère déjà ces headers (duplication)

Configuration minimale :

http:
middlewares:
secure-headers:
headers:
frameDeny: true # X-Frame-Options: DENY
contentTypeNosniff: true # X-Content-Type-Options: nosniff
browserXssFilter: true # X-XSS-Protection: 1; mode=block
stsSeconds: 31536000 # HSTS 1 an
stsIncludeSubdomains: true

Appliquer au lab :

whoami:
labels:
- "traefik.http.routers.whoami.middlewares=secure-headers@file"

✅ Vérifier :

Fenêtre de terminal
curl -I http://whoami.localhost
# → X-Frame-Options: DENY
# → X-Content-Type-Options: nosniff
# → Strict-Transport-Security: max-age=31536000; includeSubDomains

Pièges fréquents :

  • HSTS sur un site sans HTTPS → les utilisateurs seront bloqués
  • CSP trop restrictive → casse le site (tester d’abord en mode report-only)

🟠 Variante avancée — CSP complète :

secure-headers-csp:
headers:
contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
customResponseHeaders:
X-Robots-Tag: "noindex, nofollow"

Headers CORS — Autoriser les requêtes cross-origin

Section intitulée « Headers CORS — Autoriser les requêtes cross-origin »

🟢 Quand l’utiliser :

  • API consommée par un frontend sur un autre domaine
  • Applications SPA (React, Vue, Angular)

🔴 Quand ne pas l’utiliser :

  • API interne entre microservices (même origine)
  • Quand le framework backend gère déjà CORS

Configuration minimale :

http:
middlewares:
cors:
headers:
accessControlAllowMethods:
- GET
- POST
- OPTIONS
accessControlAllowOriginList:
- "https://app.example.com"
accessControlMaxAge: 86400

✅ Vérifier :

Fenêtre de terminal
# Preflight OPTIONS
curl -I -X OPTIONS http://whoami.localhost/api \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST"
# → Access-Control-Allow-Origin: https://app.example.com
# → Access-Control-Allow-Methods: GET, POST, OPTIONS

🟢 Quand l’utiliser :

  • Sites web avec beaucoup de contenu texte (HTML, CSS, JS)
  • APIs JSON volumineuses

🔴 Quand ne pas l’utiliser :

  • Contenu déjà compressé (images, vidéos)
  • Flux temps réel (SSE, WebSocket) — voir note ci-dessous

Configuration minimale :

http:
middlewares:
compress:
compress: {}

Appliquer au lab :

whoami:
labels:
- "traefik.http.routers.whoami.middlewares=compress@file"

✅ Vérifier :

Fenêtre de terminal
# Demander gzip
curl -H "Accept-Encoding: gzip" -I http://whoami.localhost
# → Content-Encoding: gzip
# Demander brotli (prioritaire si supporté)
curl -H "Accept-Encoding: br, gzip" -I http://whoami.localhost
# → Content-Encoding: br

Pièges fréquents :

  • Compression sur des réponses tiny → overhead
  • Compression + SSE → latence au lieu de temps réel

🟠 Variante avancée — Taille minimale :

compress-smart:
compress:
minResponseBodyBytes: 1024 # Compresser seulement si > 1 KB
excludedContentTypes:
- text/event-stream

Priorité des algorithmes : Traefik choisit brotli (br) si le client le supporte, sinon gzip. Brotli offre une meilleure compression mais est plus lent.

🟢 Quand l’utiliser :

  • Forcer HTTPS sur tous les services

🔴 Quand ne pas l’utiliser :

  • Environnement de dev local sans certificat

Configuration minimale :

http:
middlewares:
redirect-https:
redirectScheme:
scheme: https
permanent: true # 301 au lieu de 302

✅ Vérifier :

Fenêtre de terminal
curl -I http://whoami.localhost
# → HTTP/1.1 301 Moved Permanently
# → Location: https://whoami.localhost/

RedirectRegex — Redirections par expression régulière

Section intitulée « RedirectRegex — Redirections par expression régulière »

🟢 Quand l’utiliser :

  • Rediriger www. vers apex (ou inversement)
  • Migrations d’URLs complexes

🔴 Quand ne pas l’utiliser :

  • Redirections simples (préférez RedirectScheme ou record DNS CNAME)

Configuration minimale :

http:
middlewares:
redirect-www:
redirectRegex:
regex: "^https://www\\.(.*)"
replacement: "https://${1}"
permanent: true

✅ Vérifier :

Fenêtre de terminal
curl -I https://www.example.com
# → HTTP/1.1 301 Moved Permanently
# → Location: https://example.com

Objectif : grouper plusieurs middlewares pour les réutiliser.

http:
middlewares:
# Middlewares unitaires
rate-limit:
rateLimit:
average: 100
burst: 200
secure-headers:
headers:
frameDeny: true
contentTypeNosniff: true
compress:
compress: {}
# Chain qui les combine
chain-web:
chain:
middlewares:
- rate-limit
- secure-headers
- compress

Utilisation :

docker-compose.yml
whoami:
labels:
- "traefik.http.routers.whoami.middlewares=chain-web@file"

L’ordre dans la liste middlewares est l’ordre d’exécution :

chain:
middlewares:
- rate-limit # 1. Bloque les abus
- basic-auth # 2. Vérifie l'identité
- strip-prefix # 3. Transforme l'URL
- secure-headers # 4. Ajoute headers
- compress # 5. Compresse la réponse

Observations :

  • Les headers attendus ne sont pas présents
  • L’authentification ne se déclenche pas

Causes probables :

  1. Nom mal orthographié — Vérifiez que le nom dans middlewares: correspond exactement à la définition

  2. Mauvais provider — Un middleware File Provider se référence avec @file, un Docker avec @docker :

    - middleware-name@file # File provider
    - middleware-name@docker # Docker provider
  3. Namespace Kubernetes — Le middleware doit être dans le même namespace ou référencé avec namespace-name@kubernetescrd

Diagnostic :

Fenêtre de terminal
# Lister les middlewares connus par Traefik
curl http://localhost:8080/api/http/middlewares | jq '.[].name'

Observations :

  • L’utilisateur a des credentials valides mais reçoit 401

Causes probables :

  1. Hash mal généré — Vérifiez que vous utilisez bcrypt (htpasswd -nbB)

  2. $ non échappé — Dans Docker labels, doublez les $ : $$2y$$05$$...

  3. ForwardAuth : service auth inaccessible — Vérifiez que le service auth répond :

    Fenêtre de terminal
    curl http://authelia:9091/api/verify

Observations :

  • Rate limit se déclenche pour des utilisateurs légitimes

Causes probables :

  1. Limites trop agressives — Augmentez average et burst

  2. sourceCriterion mal configuré — Tous les utilisateurs partagent la même limite :

    sourceCriterion:
    ipStrategy:
    depth: 0 # IP directe du client
  3. Derrière un proxy sans X-Forwarded-For — Toutes les requêtes semblent venir de la même IP

Observations :

  • curl -I ne montre pas les headers attendus

Causes probables :

  1. Middleware non attaché au routeur — Vérifiez le label middlewares=

  2. Backend renvoie déjà ces headers — Traefik n’écrase pas les headers existants par défaut

  3. Ordre des middlewares — Un autre middleware écrase les headers

Observations :

  • Erreur 500 avec “context deadline exceeded” dans les logs

Causes probables :

  1. Service auth lent — Le service d’authentification met trop de temps

  2. Mauvaise URLaddress pointe vers un service inaccessible

Solution — Vérifiez la connectivité :

Fenêtre de terminal
# Depuis le conteneur Traefik
docker exec -it traefik wget -q -O- http://authelia:9091/api/verify

Avant de déployer vos middlewares en production, vérifiez :

  1. HTTPS activé — BasicAuth et headers de sécurité n’ont de sens qu’avec TLS

  2. Ordre correct — Rate limit et IP filter avant l’authentification

  3. Tests curl effectués — Chaque middleware validé individuellement

  4. Logs consultés — Pas d’erreur dans docker logs traefik

  5. Dashboard vérifié — Middlewares visibles dans l’API

  1. Un middleware est un filtre — il transforme, vérifie ou protège entre le client et le backend.

  2. Bloquer tôt, transformer tard — rate limit avant auth, headers et compress en dernier.

  3. Chaînez avec chain — groupez les middlewares par cas d’usage (public, internal, api).

  4. Testez avec curl — chaque middleware a une commande de validation simple.

  5. BasicAuth sans HTTPS = danger — préférez ForwardAuth + SSO en production.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.