Dans le précédent article, nous avions vu ensemble comment mettre en place le SSL sur votre site avec Traefik en version 2. Mais pour le moment, nos tests sur sslabs et secuirytheaders nous renvoient un score de B et F. Pas terrible ! 😢

Aucun problème, vous allez maintenant comprendre pourquoi Traefik est un outil vraiment puissant et génial ! Dans un premier temps occupons-nous de notre certificat SSL.

Pré-requis

Petite note avant d'attaquer le sujet ! J'essaye de rendre les articles le plus intuitif possible et de ne pas rentrer trop dans l'explication de certains détails techniques. Certes passionants, mais qui pourraient faire fuir certains d'entre-vous. Ces articles ont une vocation de tutoriel : mais la meilleure voie pour devenir un vrai forgeron, c'est de forger soit même.

Dans ce sens, je vais mettre ici un lien vers le github où vous pourrez récupérer les configurations de départ de cet article. Cela vous permettra à tête reposée de reprendre une à une les modifications effectuées ci-dessous :

https://github.com/lfache/Traefik-SSL-Tuto-1

SSLLABS rang A+

Je vais tester à l'aider de SSLLABS mon site créé pour l'occasion : https://dev.dubarbu.fr.

SSLLABS_RANKB-1

Prenons le temps de lire le retour apporté par SSLLABS :

  • This server does not support Forward Secrecy with the reference browsers. Grade capped to B.
  • This server supports TLS 1.0 and TLS 1.1. Grade capped to B.

C'est écrit à 2 reprises, mon rang sera forcément cap à B car j'autorise le TLS 1.0 et 1.1. De plus mon installation ne supporte pas les "Forward Secrecy" mais qui découlent de l'utilisation des anciennes versions de TLS.

Corrigeons déjà le problème de version TLS. À l'aide de la documentation Traefik, je découvre rapidement une série d'option pour la configuration du protocole. Et notamment :

Minimum TLS Version ( Précision d'importance, la documentation précise en premier commentaire de cette option : # Dynamic configuration )

Je vous invite à revoir l'article sur les différents types de configuration de Traefik.

Il est donc nécessaire de placer ces options dans un fichier de configuration dynamique. Jusque là, nous utilisions principalement des labels pour définir nos configurations dynamiques. Dans certains cas, je préfère de mon côté utiliser des fichiers YAML ou TOML.

À la racine de mon projet, je vais créer un dossier config qui va me servir à définir mes configurations dynamiques dans des fichiers YAML :

mkdir conf

Ensuite je vais éditer un fichier tls.yml dans ce dossier :

vim config/tls.yml

Et ajoutez simplement ce contenu :

# Dynamic configuration
tls:
  options:
    default:
      minVersion: VersionTLS12
      sniStrict: true

Par défaut, nous demandons que la version minimum de TLS soit la 1.2.

Il faut maintenant spécifier à Traefik d'utiliser ce dossier pour récupérer les configurations. Rien de plus simple, éditez votre fichier traefik.yml et ajoutons un provider de type file :

providers:
  docker:
    exposedByDefault: false

  file:
    directory: /etc/traefik/config/
    watch: true

L'option watch n'est pas nécessaire, mais elle fait partie des gros plus de cette version :

Traefik va automatiquement voir les changements de fichiers dans le répertoire, et les prendre en compte.

Enfin ajoutons à notre docker-compose.yml le volume pour la configuration :

version: '3.7'
services:
  traefik:
    image: traefik:2.1
    container_name: traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
      - ./config/:/etc/traefik/config/:ro
      - traefik_ssl:/letsencrypt
    networks:
      - traefik

Redémarrez votre instance de Traefik avec docker-compose down et ensuite docker-compose up -d.

Un nouveau test sur ssllabs devrait vous fournir un rang A. Et retirer les deux problématiques présentes lors du premier test.

Vous pouvez à ce moment là, mettre les options TLS que vous souhaitez. Vous n'obtiendrez jamais de A+ sur SSLLABS sans un header de securité bien précis : le HSTS.

Les headers de sécurité :

Comme ce header est indispensable, commençons par là ! Une nouvelle fois, je n'invente rien du tout : https://docs.traefik.io/middlewares/headers/#using-security-headers

Si vous avez bien compris le fonctionnement de Traefik 2. Vous devez immédiatement comprendre quelques petites choses :

  • Ces modifications doivent être faites dans un middleware.
  • Elles sont donc dans la configuration dynamique.

Comme précédement, je fais le choix d'opter pour un fichier YML pour configurer tout ça :

vim config/middlewares.yml

Et ajoutons les headers nécessaires dans notre cas :

http:
  middlewares:
    SecHeader:
      headers:
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsSeconds: 31536000
        sslRedirect: true
        sslForceHost: true
        sslHost: 'dev.dubarbu.fr'

Il faut maintenant que nos services prennent en compte ce middleware. Cette fois-ci, tout doit se faire dans votre déclaration de service via vos labels :

version: '3.7'
services:
  whoami:
    image: containous/whoami
    container_name: whoami
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`dev.dubarbu.fr`)"
      - "[email protected]"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"
      - "traefik.http.routers.whoami-https.rule=Host(`dev.dubarbu.fr`)"
      - "[email protected]"
      - "traefik.http.routers.whoami-https.entrypoints=https"
      - "traefik.http.routers.whoami-https.tls=true"
      - "traefik.http.routers.whoami-https.tls.certresolver=myhttpchallenge"
    networks:
      - traefik

Et là, rendez-vous sur http://dev.dubarbu.fr et vous êtes immédiatement redirigé vers le HTTPS, magie !!

apple
MAGIC !

Pourquoi ? Vous avez déclaré ça dans votre middleware :

forceSTSHeader: true
stsIncludeSubdomains: true
stsSeconds: 31536000

En cas de connexion HTTP, on force le HSTS ( on force l'utilisation du HTTPS ) et on indique que les sous-domaines de dev.dubarbu.fr doivent également le faire.

sslRedirect: true
sslForceHost: true
sslHost: 'dev.dubarbu.fr'

On autorise uniquement les connexions HTTPS avec sslRedirect et on force systématiquement le host avec dev.dubarbu.fr.

Enfin et maintenant c'est très simple. Ajoutons les headers dans notre middleware que nous avions vu dans la partie 1 :

        contentSecurityPolicy: "script-src 'self'; img-src 'self'"
        referrerPolicy: "same-origin"
        featurePolicy: "vibrate 'self'; geolocation 'self'; midi 'self'; notifications 'self'; push 'self'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; vibrate 'self'; fullscreen 'self'"

        frameDeny: true
        contentTypeNosniff: true
        browserXssFilter: true

Pas besoin de relancer les services, notre watch: true travail pour nous :

SSLLABS_RANKA


À travers ces deux articles, nous avons pu voir comment mettre en place le HTTPS sur notre site avec Traefik 2. Mais également comment sécuriser cette mise en place à l'aide de notre reverse proxy. Vous voilà prêt pour une mise en situation réelle avec ces configurations !

Les fichiers de configuration finaux sont disponibles ici : https://github.com/lfache/Traefik-SSL-Tuto-2

N'hésitez pas à faire vos commentaires ou à suivre les publications sur Twitter !