Traefik v2 : configuration TLS personnalisée

Tut's Linux mars 03, 2020

L'objectif de cette documentation est de fournir les fichiers de configuration nécessaire pour faire fonctionner Traefik avec une configuration TLS personnalisée.


Article mis à jour et corrigé par ldez. (merci !). De nombreuses coquilles étaient présentes, notamment vis-à-vis de configuration inutiles, inexploitées ou encore des erreurs de syntaxe.

Avant-propos, vous ne pouvez pas utiliser les deux configurations (statique et dynamique) en même temps : c'est l'un ou l'autre.
Préparons notre fichier docker-compose.yml :

version: '3.7'
services:
  traefik:
    image: traefik:chevrotin
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - ./conf/traefik.toml:/etc/traefik/traefik.toml:ro
      - ./conf/traefik_dynamic.toml:/etc/traefik/traefik_dynamic.toml:ro
      - ./acme.json:/acme.json
    networks:
      - oueb

Explications :

  • on fige la version de Traefik avec la v2 nommée "cantal"
  • ouverture des ports 80 & 443
  • les volumes sont importants : un premier fichier de configuration "traefik.toml" pour les options de base et un fichier de configuration "traefik_dynamic.toml" pour les options dites "dynamiques".
  • le fichier "acme.json" est à créer avant tout, via un "touch acme.json && chmod 600 acme.json".

Contenu du fichier "conf/traefik.toml" :

[global]
  sendAnonymousUsage = false
  checkNewVersion = false

[log]
  level = "WARNING"

[providers]
  [providers.docker]
    endpoint = "unix:///var/run/docker.sock"
    exposedByDefault = false
    swarmMode = false

  [providers.file]
    filename = "/etc/traefik/traefik_dynamic.toml"
    watch = true

[entryPoints]
  [entryPoints.web]
    address = ":80"

  [entryPoints.websecure]
    address = ":443"

[certificatesResolvers]
  [certificatesResolvers.letsencrypt]
    [certificatesResolvers.letsencrypt.acme]
      email = "mail@nomdedomaine.org"
      caServer = "https://acme-v02.api.letsencrypt.org/directory"
      storage = "acme.json"
      keyType = "EC384"
        [certificatesResolvers.letsencrypt.acme.httpChallenge]
          entryPoint = "web"

Ce qui est important dans ce fichier, c'est le bloc "providers". Vous remarquerez le bloc "providers.file", avec la définition d'un fichier "traefik_dynamic.toml". La ligne "watch = true" permet à Traefik de regarder et d'activer les changements. N'oubliez pas non plus de modifier l'adresse e-mail pour correspondre à votre situation.


Le fichier de configuration secondaire (dynamique) est de même type que le "traefik.toml", la différence réside dans les conf' qu'il contient et ses usages. Pour rappel, le fichier "traefik.toml" contient la configuration pour le démarrage de Traefik, tandis que le fichier de configuration dynamique contient les options pour les middlewares, les routers et autres loadbalancers.
Retrouvez ci-dessous mon fichier de configuration "traefik_dynamic.toml" :

[tls]
  [tls.options]
    [tls.options.default]
      minVersion = "VersionTLS12"
      sniStrict = true
      cipherSuites = [
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
        "TLS_AES_128_GCM_SHA256",
        "TLS_AES_256_GCM_SHA384",
        "TLS_CHACHA20_POLY1305_SHA256"
      ]
      curvePreferences = ["CurveP521","CurveP384"]

[http]
  [http.middlewares.compression.compress]
    excludedContentTypes = ["text/event-stream"]

  [http.middlewares.https-redirect.redirectScheme]
    scheme = "https"
    permanent = true

  [http.middlewares.security.headers]
    accessControlAllowMethods = ["GET", "OPTIONS", "PUT"]
    accessControlAllowOrigin = "origin-list-or-null"
    accessControlMaxAge = 100
    addVaryHeader = true
    browserXssFilter = true
    contentTypeNosniff = true
    forceSTSHeader = true
    frameDeny = true
    stsIncludeSubdomains = true
    stsPreload = true
    customFrameOptionsValue = "SAMEORIGIN"
    referrerPolicy = "same-origin"
    featurePolicy = "vibrate 'self'"
    stsSeconds = 315360000

Beaucoup d'explications à fournir :

  • le bloc TLS instaure toutes les options nécessaires pour avoir une configuration optimale - pour faire simple, la version minimale est le TLS 1.2 avec des algorithmes de chiffrement qui vont bien.
  • le bloc "HTTP" comporte 3 sous-blocs :
    - un premier middleware pour compresser certains flux sauf en cas de streaming
    - un second middleware correpondant à la redirection automatique "HTTP to HTTPS"
    - enfin un troisième middleware pour toutes les sécurités relative au HTTPS (les "headers").

Les fichiers de configuration sont prêts, ne reste plus qu'à configurer les services dans votre docker-compose.yml ! Voilà ce qu'il faut saisir pour chaque service dans les labels :

    labels:
      traefik.enable: "true"
      traefik.http.routers.service-http.rule: "Host(`service.nomdedomaine.org`)"
      traefik.http.routers.service-http.entrypoints: "web"
      traefik.http.routers.service-http.middlewares: "https-redirect@file"
      traefik.http.routers.service-https.rule: "Host(`service.nomdedomaine.org`)"
      traefik.http.routers.service-https.entrypoints: "websecure"
      traefik.http.routers.service-https.middlewares: "security@file, compression@file"
      traefik.http.routers.service-https.tls: "true"
      traefik.http.routers.service-https.tls.certresolver: "letsencrypt"

Tout ces labels sont à saisir pour chaque service derrière Traefik. Les middleware "security@file", "compression@file" et "https-redirect@file" viennent piocher directement les paramètres dans le fichier "traefik_dynamic.toml" précédemment créé.
Lorsque vos labels sont mis en place, n'oubliez pas de relancer vos conteneurs Docker et le tour est joué !

Un petit tour chez SSLlabs pour voir ce qu'il en est de notre configuration HTTPS (avec quelques optimisations côté DNS) :

Mots clés

Julien HOMMET

Bercé par l'informatique depuis mon plus jeune âge, je transforme ma passion en expertise.

Super ! Vous vous êtes inscrit avec succès.
Super ! Effectuez le paiement pour obtenir l'accès complet.
Bon retour parmi nous ! Vous vous êtes connecté avec succès.
Parfait ! Votre compte est entièrement activé, vous avez désormais accès à tout le contenu.