- Traefik est connu dans les environnements de conteneurs, mais comme il peut être déployé sous forme de fichier exécutable Go unique, il peut aussi fonctionner comme reverse proxy sans moteur de conteneurs
- Par rapport à la famille nginx/caddy/apache2, qui sert directement des fichiers, c’est un proxy plus proche de HAProxy, axé sur la transmission des requêtes, le renvoi des réponses et l’ajustement des en-têtes
- Même sans utiliser de labels Docker, il peut être configuré avec un provider de fichiers de configuration, en séparant configuration statique et configuration dynamique pour gérer routeurs, services et middlewares
- Il prend en charge le TLS Passthrough ainsi que l’entrée/sortie du protocole PROXY de HAProxy, mais le protocole PROXY doit aussi être pris en charge par le service cible ; apache2 et nginx le supportent
- L’intégration de l’authentification et le blocage par user agent ou IP peuvent être insuffisants avec les seules fonctions intégrées ; il faut donc aussi évaluer la charge de gestion liée à ForwardAuth, oauth2-proxy et aux plugins tiers
Traefik utilisable aussi hors des conteneurs
- Traefik a gagné en popularité ces dernières années dans l’écosystème YouTube des home labs, et il est principalement présenté avec des infrastructures de conteneurs comme Docker ou Kubernetes
- Par sa nature fonctionnelle, il est plus proche de HAProxy que de nginx/caddy/apache2
- Il transmet les requêtes aux services et renvoie les réponses
- Il peut modifier les en-têtes ainsi que certaines parties des requêtes et réponses
- Il ne prend pas en charge le service de fichiers
- Dans un environnement de conteneurs, Traefik est lui aussi exécuté comme conteneur, avec le socket Docker monté pour détecter automatiquement les autres conteneurs
- Le comportement du proxy peut être configuré via les labels Docker des conteneurs
- Lorsqu’un nouveau conteneur est détecté, il peut demander automatiquement un certificat TLS Let’s Encrypt et exposer le service
Binaire unique et déploiement avec systemd
- Traefik est écrit en Go et compilé en un seul fichier exécutable
- La distribution binaire est disponible dans la documentation d’installation de Traefik
- Il est possible d’exécuter à la fois Traefik lui-même et les services cibles sans moteur de conteneurs
- Un exemple d’unité de service systemd est disponible dans le dépôt Traefik
- En production réelle, il faut aussi créer un utilisateur dédié et régler les permissions des fichiers de configuration, en plus des fichiers de configuration eux-mêmes
Configuration basée sur des fichiers
- Sans conteneurs, on ne peut pas utiliser les labels Docker, mais Traefik peut être configuré avec le provider de fichiers
- La configuration se divise globalement en deux parties
- Configuration statique : contient les fournisseurs de certificats comme Let’s Encrypt et les entrypoints, c’est-à-dire les ports sur lesquels Traefik écoute
- Configuration dynamique : contient les routeurs, services et middlewares
- Traefik peut détecter les événements du système de fichiers et effectuer un hot reload de la configuration dynamique
- La documentation fournit les concepts clés et des exemples de configuration adaptés à chaque approche
- Les termes comme certificate provider, entrypoint, router, service et middleware peuvent être rapidement consultés dans la documentation Traefik
Comportement après configuration et débogage
- Lorsque la configuration n’est pas correcte, Traefik affiche des avertissements
- Les logs par défaut ne sont pas très verbeux, mais il est facile de comprendre quel chemin emprunte une requête
- Selon un retour d’expérience utilisateur, la configuration initiale a été rapide et aucun problème arbitraire n’a été rencontré
TLS Passthrough et protocole PROXY
- Traefik prend en charge le TLS Passthrough
- Il permet de transmettre le trafic à un service web fournissant son propre certificat TLS, sans terminer TLS au niveau du proxy
- Il est aussi possible de configurer un service pour demander directement un certificat Let’s Encrypt en passant par Traefik
- Le proxy ne peut pas voir le contenu transmis
- Le choix classique d’un hôte virtuel s’effectue via l’en-tête HTTP
Host, mais avec TLS Passthrough cet en-tête se trouve dans le corps chiffré et ne peut donc pas être utilisé - L’hôte cible est sélectionné via le SNI (Server Name Indication) de TLS, une méthode utilisée par Traefik ainsi que par de nombreux serveurs web et proxies
- Il prend aussi en charge l’entrée/sortie du protocole PROXY de HAProxy
- C’est une méthode permettant de transmettre au service cible des informations qui disparaissent lorsque l’utilisateur atteint d’abord le proxy
- Elle est considérée comme plus facile à gérer du point de vue sécurité que les anciens en-têtes
X-Forwarded-... - Le service cible doit lui aussi prendre en charge le protocole PROXY
- apache2 et nginx le supportent, et la liste des services compatibles continue de s’allonger
Les limites restantes côté intégration de l’authentification
- Avec nginx, il est possible d’utiliser Vouch Proxy pour protéger certains services avec Azure AD, aujourd’hui Microsoft Entra
- Traefik prend en charge ForwardAuth, similaire au mécanisme d’authentification de nginx
- Vouch Proxy ne fonctionne pas encore avec Traefik, et une issue est ouverte à ce sujet
- Il est possible d’exploiter soi-même une instance Keycloak, de l’intégrer à AAD et de l’utiliser avec ForwardAuth, mais la configuration initiale ainsi que la maintenance de sécurité et les mises à jour représentent une lourde charge
- traefik-forward-auth est souvent recommandé, mais sa dernière mise à jour remonte à juin 2020 et ses dépendances doivent être mises à jour, ce qui le rend difficile à utiliser selon l’évaluation donnée
- Les expériences passées avec oauth2-proxy n’ont pas été positives, et placer un proxy derrière un autre proxy augmente le risque d’erreurs, car il faut aligner HTTP/2·HTTP/3, les timeouts, la taille des corps de requête et la configuration WebSocket à chaque proxy intermédiaire
- D’après la mise à jour du 06/05/2024, oauth2-proxy peut aussi être intégré via une API HTTP
- Il prend en charge le auth_request de nginx
- Il prend en charge le ForwardAuth de Traefik
- Cette approche semble être une option proche de la configuration souhaitée
Blocage par user agent et par IP
- Il existe des situations où l’on ne souhaite pas que des services internes soient archivés par archive.org
- robots.txt et les en-têtes similaires ne sont pas efficaces pour bloquer Archive.org ; les méthodes de blocage des crawlers consistent à bloquer le user agent
archive.org_botou des plages d’IP - Pour bloquer des user agents ou des adresses IP dans Traefik, il faut un plugin tiers plutôt qu’une fonction intégrée
- Plugin de blocage par user agent
- Plugin deny IP
- Les plugins tiers demandent de l’attention lors des mises à jour et peuvent introduire des vulnérabilités de sécurité, ce qui les rend peu souhaitables
- Il est possible d’utiliser le middleware IPAllowList pour autoriser tout le reste à l’exception des IP que l’on veut bloquer
- Le calcul des plages IP est également possible
- Ce n’est pas pire qu’un blocage direct, mais ce n’est pas élégant, car il est difficile de savoir quelles plages ont été bloquées en ne regardant que les sous-réseaux restants
Exemple de configuration
- L’exemple est divisé entre
/etc/traefik/traefik.ymlet/etc/traefik/dynamic.yml - La configuration statique définit les éléments suivants
- Les entrypoints
:80et:443 - La redirection systématique des endpoints HTTP vers HTTPS
- L’émission de certificats Let’s Encrypt via TLS challenge
- La surveillance du fichier de configuration dynamique
/etc/traefik/dynamic.yml
- Les entrypoints
- La configuration dynamique inclut les éléments suivants
- Routage TCP avec TLS Passthrough pour
cloud.xx.xyz - Transmission vers le service
10.33.1.2:4433d’un autre hôte - Activation du protocole PROXY version 2
- Terminaison TLS puis proxy vers le service local
http://127.0.0.1:3000pourgit.xx.xyz - Middleware redirigeant
https://xx.xyz/redirmeplsvershttps://google.com - Middleware ajoutant l’en-tête
X-Robots-Tag: noindex, nofollow, nosnippet, noarchive
- Routage TCP avec TLS Passthrough pour
1 commentaires
Avis sur Hacker News
Traefik est plutôt correct, mais souffre du même problème désastreux qu’Ansible. Il y a beaucoup de documentation et d’articles, mais impossible de trouver ce dont on a vraiment besoin.
Je l’utilise depuis la v1, et pourtant je me perds souvent dans la documentation, ce qui est très frustrant. Pour les petits projets, j’ai tendance à utiliser Caddy, parce que sa documentation n’est pas aussi mauvaise que celle de Traefik.
À l’attention des rédacteurs de documentation technique : une documentation centrée sur les exemples n’est utile qu’aux débutants qui la parcourent rapidement. Les personnes déjà familières avec le produit ont besoin d’une documentation de référence et de listes exhaustives, pas d’explications de champs éparpillées sur 10 pages de tutoriels. Il ne faut pas se concentrer uniquement sur le processus d’onboarding, mais aussi penser aux personnes qui utilisent le produit tous les jours.
C’est ce qui m’agace le plus, la raison pour laquelle j’en suis venu à détester autant Ansible, et Traefik présente un problème similaire, quoique moins marqué.
Elle suppose qu’on ne fera que des opérations très simples sur des structures de données très plates, alors que la réalité est rarement ainsi. Pour bien utiliser ce type de langage, il faut comprendre tout un ensemble de règles implicites sur la façon d’écrire du YAML, mais la documentation les aborde rarement.
Il existe une documentation propre à la configuration de chaque module, mais la façon d’utiliser la configuration standard, de manipuler les données retournées ou de les combiner avec quelque chose d’un peu complexe est rarement claire. C’est comme si on vous jetait une douzaine d’exemples d’un paragraphe pour chaque élément, comme un tas d’ingrédients, puis qu’on vous demandait de faire un gâteau.
J’ai presque toujours vécu la même expérience avec plusieurs systèmes d’interprétation de YAML que j’ai utilisés, et ce n’est qu’après des centaines de milliers de lignes de YAML que j’ai pu vraiment avancer ; la documentation, elle, n’avait guère plus de valeur qu’une liste de paramètres.
Cela dit, avec
ansible-doc, j’ai trouvé un workflow assez correct, et mes alias fréquents sontalias adl='ansible-doc --list',alias adls='ansible-doc --list | less -S',alias ad='ansible-doc'.Je commence par chercher rapidement les commandes pertinentes avec
adls, puis je consulte la documentation avecad, et je saute presque toujours directement à la fin (G) pour voir les exemples. En général, la réponse dont j’ai besoin s’y trouve.Écrire des scripts Ansible dépend énormément de la documentation ; je pense donc que, même par défaut, l’outil devrait mieux prendre en charge ce processus de consultation et fournir une interface permettant de trouver rapidement ce qu’on cherche sans devoir créer tout un tas d’alias.
Bien sûr, c’est son projet, mais à chaque fois que je cherche une méthode d’un objet, je dois fouiller dans de longues pages de prose. Parfois, il est tout simplement plus facile de lire le code source.
Nous utilisons Traefik en production depuis 2 ans. Avant, nous utilisions NGINX, mais nous avons décidé de passer à Traefik à cause de l’intégration automatique avec Let's Encrypt, et je regrette cette décision
La documentation de Traefik ne parle pas vraiment à mon équipe ni à moi. C’est délicat, et le comportement est étrange, sans logs corrects
Par exemple, quand on essaie de recréer un certificat, cela échoue par intermittence et la production tombe sans qu’on sache quand elle reviendra. Nous sommes en train de revenir à NGINX
configuration.nixpour le configurer, et en interne cela utiliselego(1)et letsencryptsecurity.acme = { acceptTerms = true; defaults.email = "admin-email@provider.net"; certs."mydomain.example.com" = { domain = "*.mydomain.example.com"; dnsProvider = "cloudflare"; environmentFile = "/path/to/cloudflare/password"; }; };services.caddy.enable = true;services.caddy.virtualHosts."subdomain1.mydomain.example.com" = { extraConfig = '' reverse_proxy 127.0.0.1:1234 ''; useACMEHost = "mydomain.example.com"; };La configuration avec nginx doit être assez similaire. https://github.com/go-acme/lego
Même registrar de domaine, même API, même configuration Docker, tous les logs activés, mais aucune information sur la raison pour laquelle le certificat n’était pas créé. Il revenait simplement au certificat par défaut généré, comme s’il n’avait même pas essayé
Après deux sessions de dépannage et plusieurs heures de recherches, j’ai abandonné et j’ai dû utiliser un fichier de certificat autosigné. C’est vraiment frustrant de n’avoir aucune information sur la raison de l’échec, avec un échec silencieux suivi d’un comportement de repli
Globalement, c’était le plus gros problème avec Traefik. Quand ça marche, c’est excellent, mais quand ça ne marche pas, il a toujours été difficile de dépanner ou de trouver l’information nécessaire dans la documentation. Au travail, nous prévoyons de commencer à utiliser Traefik en production vers la fin de l’année, donc j’espère me familiariser davantage avec Traefik d’ici là
Le meilleur, c’est qu’il n’y a pas de langage de configuration. Il suffit d’utiliser Go
Ce que j’ai appris plus tard, c’est que si le DNS n’est pas correctement configuré, après N échecs de validation, Let's Encrypt refuse pendant un moment de retenter la validation TLS-01, et votre problème ressemble à ce genre de cas
Après être passé à la validation DNS-01, l’expérience est soudain devenue bien meilleure. On peut aussi créer des certificats pour des services qui ne sont pas exposés publiquement, et cela demande beaucoup moins d’orchestration que TLS-01
Si le fournisseur DNS fonctionne correctement, en cas de problème il y a de fortes chances de recevoir une erreur d’API avant que Let's Encrypt ne vérifie l’enregistrement, et l’échec survient bien avant le backoff lié aux échecs de vérification côté Let's Encrypt. Désormais, que j’utilise Traefik, Caddy, Nginx ou un autre proxy inverse, j’ai pratiquement décidé de n’utiliser que la validation DNS-01 pour Let's Encrypt ; et si je dois utiliser TLS-01, je vérifierai impérativement avec l’API Staging que tout est correctement réglé dès le départ
À noter que lorsqu’on crée un certificat Let's Encrypt Staging dans Traefik, il n’y a pas de bonne façon de l’invalider. Il faut modifier l’ACME JSON pour supprimer le certificat puis redémarrer Traefik pour que le changement soit pris en compte. Peut-être que
SIGHUPsuffit, mais je n’ai pas essayéDans l’ensemble, il y a beaucoup d’échecs silencieux et de comportements étranges, mais la plus grande douleur est qu’il rend opaques les erreurs des services dont il dépend
J’utilise Caddy plutôt que Traefik. De mon point de vue, gérer un Caddyfile est beaucoup plus simple que la configuration YAML de Traefik, et je maintiens des Caddyfile distincts pour les déploiements local, production et on-premise
Il y a aussi beaucoup d’excellents plugins, et nous utilisons le plugin WAF coraza pour Caddy, qui fonctionne bien
Il a toutes les fonctionnalités dont j’ai besoin tout en étant beaucoup plus simple
https://github.com/lucaslorentz/caddy-docker-proxy
Par exemple, comment gérer le stockage local quand on utilise un stockage externe. On dit qu’on peut le traiter comme stateless, mais ce n’est peut-être pas le cas
Au final, il faut prier pour que la personne qui a créé le module nécessaire sache vraiment ce qu’elle fait. De ce côté-là non plus, il n’y a pas de standard de documentation. Les mainteneurs devraient mettre un frein aux modules aléatoires qui fournissent des fonctionnalités essentielles avec zéro documentation, comme un backend de stockage S3
Pour des besoins modestes, avec quelques hôtes Docker et quelques dizaines de conteneurs, je me demande quelle raison il y aurait d’utiliser Traefik plutôt que nginx. J’utilise https://github.com/NginxProxyManager/nginx-proxy-manager ; à cette petite échelle, Traefik apporterait-il vraiment un avantage ?
En réalité, il y a aussi le fait que je n’aime pas la syntaxe de nginx et que Traefik me semblait séduisant. J’y suis venu pour le renouvellement Let’s Encrypt et les conteneurs, et j’y suis resté à cause de sa manière de configurer les choses.
Je n’envisagerais une migration qu’au moment où j’aurais besoin d’une fonctionnalité que Traefik fournit et que Nginx n’a pas.
Je trouve aussi un peu étrange que Let’s Encrypt automatique soit un argument de vente, alors que Certbot est partout et prend en charge davantage de scénarios. Les arguments de vente de Traefik et Caddy ne me parlent pas vraiment, car il ne s’agit pas seulement de rendre les choses plus faciles qu’avec des alternatives déjà largement prises en charge.
Il y a quelques semaines, je cherchais un reverse proxy et j’ai finalement choisi Caddy pour sa simplicité. Cela dit, la découverte automatique de conteneurs de Traefik et la référence par labels sont plutôt intéressantes, et Caddy a aussi un plugin qui fait la même chose.
J’ai lu l’article, mais je ne suis toujours pas convaincu que Traefik ait un avantage sur Caddy pour mon cas. Il peut en avoir pour d’autres, donc j’aimerais entendre des avis.
Il faut aussi noter que Traefik est configuré par défaut dans K3s. Grâce à cela, K3s est devenu la manière la plus rapide de monter un cluster K8s de test, et permet de traiter les clusters comme du bétail.
Il suffit d’ajouter le déploiement et les services associés en NodePort pour accéder à l’application sans se soucier de l’ingress controller.
J’utilise un script shell pour lancer un cluster K3s et tester, quand j’en ai besoin, l’application indiquée en argument positionnel. Pour cela, j’exploite le registre de conteneurs temporaire de ttl.sh. Le même script supprime aussi le cluster à la fin.
J’envisage de migrer vers Traefik le reverse proxy que j’utilise pour mon self-hosting. Contrairement à l’auteur, je fais tourner des workloads conteneurisés avec Docker Compose, et j’utilise actuellement Caddy avec l’excellent plugin caddy-docker-proxy.
Ce que j’obtiens aujourd’hui, c’est un reverse proxy configuré via des labels Docker, la détection automatique des nouveaux workloads, des certificats TLS, et une configuration DNS automatique via le plugin caddy-dynamicdns. Même si mon FAI me donne une autre IP, je n’ai pas vraiment à craindre de perdre l’accès.
En revanche, chaque fois qu’un nouveau workload est ajouté ou redémarré, Caddy redémarre entièrement, ce qui coupe temporairement l’accès. Caddy ne sait pas transmettre les connexions existantes à la nouvelle instance.
Autre point : l’utilisation de certificats wildcard n’est pas assez simple. Je ne veux pas que tous mes workloads soient exposés au monde via les journaux de transparence des certificats, donc j’utilise un certificat wildcard ; mais dans ce cas, je ne peux pas utiliser la syntaxe simple du Caddyfile avec un certificat par nom d’hôte. Je sais que des travaux sont en cours côté Caddy, mais pour l’instant c’est comme ça.
Quoi qu’il en soit, j’ai utilisé Traefik dans des environnements k8s et c’était plutôt bien, donc je pense l’essayer aussi pour un usage personnel. J’espère que ce commentaire ne dissuadera personne d’essayer Caddy : Caddy est vraiment excellent aussi.
localtest.meavec les noms d’hôte.Ça vaut le coup d’essayer. Les deux sont excellents dans des domaines différents.
En fait, les plugins ne sont pas nécessaires. J’ai un playbook Ansible qui configure tout cela dans une VM et génère même le modèle de fichier compose, et un autre playbook qui supprime tout du serveur à l’exception des données et des montages. Pour les sauvegardes, j’utilise restic avec des scripts personnalisés capables de sauvegarder des fichiers, plusieurs bases de données, etc., vers plusieurs emplacements.
Avant, je déployais k3s, mais j’ai compris que c’était trop lourd et trop complexe pour du self-hosting. Je veux juste pouvoir déployer rapidement sans gérer moi-même les certificats.
Je viens de vérifier en local, et ça fonctionne bien.
J’ai beaucoup utilisé Traefik, mais j’en ai eu assez de gérer les labels docker-compose, les couches et des dizaines de lignes simplement pour mettre en place un reverse proxy. Puis j’ai découvert Caddy, et je ne suis jamais revenu en arrière.
Je n’étais probablement pas le public cible de Traefik. Ce dont j’ai besoin, c’est d’un reverse proxy avec HTTPS activé, ou tout au plus d’une couche d’authentification basique. Dans Caddy, les deux tiennent en une ligne, c’est très concis, et il n’y a pas non plus de couches que je ne comprends toujours pas.
J’utilise Traefik pour tout mon self-hosting depuis plusieurs années.
En revanche, j’ai abandonné la découverte dynamique et les labels Docker : c’était trop pénible et agaçant à déboguer.
À la place, je génère des fichiers de configuration statiques avec un moteur de templates. Comme presque tous les services sont une combinaison host/target/port, il est très facile de créer les sections correspondantes, et il n’y a pas non plus de middleware complexe en dehors de la gestion TLS. L’auteur de l’article lié semble avoir choisi la même voie.
La configuration est générée par des scripts Ansible, puis copiée sur la machine où tourne Traefik ; Traefik surveille le répertoire contenant ce fichier et le recharge automatiquement en cas de changement. Ça a très bien fonctionné jusqu’ici.
J’utilise Traefik en production avec des conteneurs, et ce que j’aime le plus, c’est que la configuration est portée par les labels de conteneur. Du coup, je n’ai presque jamais à modifier la configuration de Traefik elle-même.
Le plus gros inconvénient, c’est de savoir comment prononcer son nom. On dirait que ça se lit comme le mot courant « traffic », mais j’ai sans cesse envie de dire un truc du genre « trey-feek ».
Le combo Traefik + Docker Compose me semble être un très bon compromis pour du petit self-hosting, avant que ça ne devienne assez gros pour passer à k8s, surtout quand on a moins de serveurs que ce qu’exige le plan de contrôle haute disponibilité de k8s.
Le nombre de grimaces et de rires de mes collègues a été énorme, et ça a freiné l’adoption et l’usage du produit.
Nous le prononcions « tray-feek », ce qui passait encore, mais lors d’un appel avec le support officiel, ils nous ont dit que ça se prononçait exactement comme le « traffic » ordinaire. Du coup, chaque fois qu’on parle de ce proxy, ça donne des phrases du genre : « on reçoit le traffic via le load balancer public, et le load balancing natif de traffic envoie le traffic vers les pods de traffic ». Ça sonne stupide, et en fait c’est stupide.
Sinon, il serait plus facile de faire des choses sympa, comme une page de maintenance ou le démarrage d’un conteneur à la première requête après une période d’inactivité.
Du coup, je réfléchis à créer un plugin qui saurait où sont stockés les fichiers compose et pourrait les lire directement.
aeest ce qui se rapproche le plus deyouhi. Donc mon intuition serait Tryfik, ou sinon Trayfik. Avec unfikà l’européenne, ça pourrait aussi donner feek.