Traefik 2.3 : Vers les plugins et au-delà!

Traefik 2.3 : Vers les plugins et au-delà!

Mise à jour le 22/12/2021

Ce contenu a été mis à jour le 22/12/2021 pour pointer vers la version 2.5.5 de Traefik Proxy et Kubernetes 1.20.

Traefik Pilot n'est plus en beta, donc la ligne de lancement a été modifiée pour refléter cet état.

Traefik 2.3 (nom de code : Picodon - le picodon est un fromage, que vous pouvez voir en bannière de cet article) est disponible en release candidate depuis quelques jours. Plus qu'une simple incrémentation de version, il apporte son lot de nouveautés.

Deux grosses nouveautés ont attiré mon attention :

  • Le nouveau service de Traefik : Traefik Pilot
  • L'ajout de la gestion des plugins

Une autre nouveauté, la compatibilité avec ECS sera couverte lors d'un prochain article.

Y a-t-il un pilote dans l'avion ?

Traefik est un reverse proxy complet et puissant, comme je l'ai déjà présenté dans des articles précédents. Néanmoins, il lui manquait une solution de healthcheck.

C'est maintenant possible, gratuitement!

Un nouveau service est dédié à cette fonctionnalité, proposé par Containous (l'éditeur, entre autres, de Traefik).

Ce service se nomme Traefik Pilot, il est pour l'instant très basique et se contente du healthcheck de votre Traefik, en permettant l'envoi de notification si celui-ci ne répond plus. Il est disponible à l'url https://pilot.traefik.io/

Après une inscription rapide, il est possible d'enregistrer une instance Traefik.

Fake token, vous pouvez toujours le copier ;)

Pour ma part, j'ai donc rajouté le paramètre en ligne de commande dans la ligne de démarrage de Traefik sur Kubernetes.

Après un redémarrage, vous devriez voir votre statut passer en OK.

Il faut par contre garder en tête quelques points :

  • Ce statut ne correspond actuellement qu'au statut de votre container Traefik, et ne signifie pas que les backends sont fonctionnels
  • Ce healthcheck est envoyé depuis votre instance, en mode "heartbeat", et ne signifie pas forcément que votre serveur est accessible
  • Comme le signal est envoyé en heartbeat, il est aussi possible de surveiller des instances en zone applicative

Il est ensuite possible, en cliquant sur votre nom en haut à droite, de définir des alarmes, via des webhooks ou par mail.

A noter qu'il est possible d'indiquer que l'on souhaite recevoir des alarmes de sécurité, liés à la découverte d'éventuelle CVE sur votre version de Traefik.

Faites chauffer les plugins

J'ai utilisé pendant de longues années le très populaire Apache httpd. L'une des énormes forces de ce produit est sans doute sa modularité, permettant à la communauté d'étendre ses fonctionnalités.

Traefik permet maintenant d'utiliser aussi des plugins. La liste est actuellement plutôt très légère, mais je n'ai aucun doute sur le fait que le catalogue va vite grossir!

Les plugins sont écrit en Go, et il est possible de contribuer en suivant le guide mis à disposition par Containous.

Pour les besoins de cet article, j'ai donc choisi le plugin "Block Path" édité par Containous. Ce plugin permet de bloquer dynamiquement l'accès à certaines pages en se basant sur des expressions régulières.

Les pages bloqués renverront directement une erreur 403 (Forbidden).

L'intérêt de ce genre de plugins, existant déjà chez la plupart des reverse proxy est de pouvoir intercepter l'accès à certaines pages, et ainsi empêcher que le backend reçoive le moindre hit.

Cela permet :

  • De ne pas générer de charge (par exemple dans le cas d'une page d'admin qui pourrait se faire brute force/DDOS)
  • D'éviter d'exposer une faille zero day non découverte, vu que le backend ne reçoit aucune requête.

Charger le plugin

Le chargement du plugin se fait via la configuration statique de Traefik. Pour ma part, je l'ai chargé via les paramètres en ligne de commande, vu que c'est ainsi que j'ai choisi de charger l'ensemble de ma configuration.

       args:
       - --providers.kubernetescrd
       - --accesslog=true
       - --accesslog.filepath=/var/log/traefik/access.log
       - --accesslog.fields.headers.defaultmode=keep
       - --entrypoints.web.address=:80
       - --entrypoints.websecure.address=:443
       - [email protected]
       - --certificatesresolvers.le.acme.storage=/cert/acme.json
       - --certificatesResolvers.le.acme.httpChallenge.entryPoint=web
       - --pilot.token=mytoken
       - --experimental.plugins.demo.moduleName=github.com/containous/plugin-blockpath
       - --experimental.plugins.demo.version=v0.1.2

Vous pouvez voir ligne 12 et 13 le chargement du plugin.

Dans ma ligne de commande, "demo" est le nom que j'ai donné au plugin (utilisé juste après). moduleName contient ainsi le chemin vers le repository GitHub contenant le plugin, version étant la version Git à checkout.

Une fois cette configuration effectué, il est nécessaire de redémarrer Traefik.

Configurer le plugin

Le plugin se comporte ensuite comme un middleware classique, si vous vous souvenez de mes articles précédents, les middlewares sont des composants qui s'enfichent entre Traefik et votre backend, et peuvent altérer le comportement normal. Par exemple, sur cette page, un middleware permet de définir les headers de sécurité nécessaires.

Ainsi, j'ai déclaré un nouveau middleware dans mon Kubernetes :

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: demo
spec:
  plugin:
    demo:
      regex: ["^/demo-[a-z]{1,5}"]

On retrouve donc, de manière classique :

  • Ligne 4 : Le nom de mon middleware, qui peut être différent du nom que j'ai donné à mon plugin
  • Ligne 6 : J'indique à Traefik que ce middleware est un plugin
  • Ligne 7 : J'indique le nom que j'ai donné à mon plugin lors de son chargement
  • Ligne 8 et suivantes, si besoin : j'indique maintenant la configuration de mon middleware.

Dans mon exemple, j'ai donc indiqué de bloquer tout accès dont le chemin commencerait par "/demo-" avec 1 à 5 lettre en minuscule.

Charger le middleware

Maintenant que j'ai défini mon middleware, je dois le charger dans mon IngressRoute.

Je modifie donc mon IngressRoute en indiquant de charger aussi ce middleware. Pour rappel, vous pouvez définir des middlewares multiples sur vos IngressRoutes qui seront exécutés d'affilée.


apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-web-ui-tls
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - kind: Rule
    priority: 1
    match: (Host(`www.tferdinand.net`) || Host(`tferdinand.net`)) && PathPrefix(`/`)
    services:
    - name: ghost-tfe-fr
      port: 2368
      helthcheck:
        path: /
        host: tferdinand.net
        intervalSeconds: 10
        timeoutSeconds: 5
    middlewares:
      - name: security
      - name: demo
  tls:
    certResolver: le
    options:
      name: mytlsoption
      namespace: default

Vous pouvez voir le chargement à la ligne 23, qui sera exécuté après l'ajout des headers de sécurité.

Testons le plugin

Il est maintenant temps de tester mon plugin.

Oui, j'utilise aussi Windows, et je l'assume ;)

Vous pouvez voir que l'on à bien le comportement attendu, mes accès normaux fonctionnent de manières identiques, les accès qui correspondent au schéma que j'ai défini sont bloqués par Traefik directement.

En conclusion : Un petit pas pour Containous, un grand pas pour la communauté

L'ajout des plugins et Traefik Pilot sont clairement des previews actuellement, et ne permettent pas d'en tirer pleinement leur potentiel, néanmoins, cette ouverte à la modularité va permettre à la communauté d'étendre les fonctionnalités de base sans pour autant alourdir le noyau de Traefik.

Cela permet aussi aux entreprise de pouvoir potentiellement développer leurs propres plugins privés et donc d'adapter Traefik au plus proche de leurs besoins.

Pilot est une excellentz initiative, et j'ai hâte de voir comment Containous va transformer cet essai pour en faire une feature au top!