[Partie 2] Mettre en place Traefik V2

Dans la partie, je présentais la théorie de traefik et en règle générale du reverse-proxy

Dans cette partie 2 nous allons voir comment réellement mettre en place traefik

En pratique

Bon c'est bien beau cette théorie, mais je pense qu'on peut maintenant passer à l'action lieutenant ! Bon désolé pour certains mais je pars du principe que vous connaissez l'environnement docker, linux et que vous êtes qqn de curieux si vous n'avez pas capté un détail. (au cas ou un petit lien vers la grotte du barbu, blog que je vous conseille)

En premier lieu il est important de se faire un rapide listing de ce qu'on va mettre en place :

  • L'application Traefik (ouais normal)
  • Une configuration statique
  • Une redirection HTTP vers HTTPS avec des certificats SSL Let's encrypt
  • Un premier site avec une configuration dynamique

Installation de Traefik : docker-compose

version: "3"

###########
# NETWORK #
###########

networks:
  traefik_proxy:
    external: true

###########
# VOLUMES #
###########

volumes:
  redis-auth: {}


############
# SERVICES #
############

services:

# TRAEFIK #
#=========#

  traefik:
    image: traefik:latest
    container_name: traefik
    hostname: traefik
    restart: always
    security_opt:
      - no-new-privileges:true
    networks:
      - traefik_proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik-data/traefik.yml:/traefik.yml:ro
      - ./traefik-data/acme.json:/acme.json
      - ./traefik-data/configurations:/configurations
      - /var/log/traefik:/var/log
    healthcheck:
      test: ["CMD", "traefik", "healthcheck", "--ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 1m
    labels:
      traefik.enable: true
      traefik.docker.network: traefik_proxy
      traefik.http.routers.traefik-secure.entrypoints: websecure
      traefik.http.routers.traefik-secure.rule: Host(`traefik.domain.com`)
      traefik.http.routers.traefik-secure.service: api@internal
      traefik.http.routers.traefik-secure.middlewares: authentification@file

En l'état actuel, on va lancer un conteneur traefik, exposé sur les ports 80 et 443. Nous allons aussi exposer l'API en interface graphique de traefik (avec une authentification username/password).

N'oubliez pas de changer le label suivant par celui de votre configuration. Ceci est l'URL qui vous permettra d'accéder à l'interface graphique de traefik (pas obligatoire cependant).

  traefik.http.routers.traefik-secure.rule: Host(`traefik.domain.com`)

Nos fichiers de conf seront dans :

  • ./traefik-data/traefik.yml → Configuration statique
  • ./traefik-data/configurations → Configuration dynamique

./traefik-data/traefik.yml

#######
# API #
#######
api:
  dashboard: true

###############
# ENTRYPOINTS #
###############
entryPoints:

# WEB / HTTP
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure

# WEBSECURE / HTTPS
  websecure:
    address: :443
    http:
      middlewares:
        - secureHeaders@file
      tls:
        certResolver: letsencrypt


########
# LOGS #
########
accessLog:
  filePath: "/var/log/access.log"
  filters:
    statusCodes:
      - "400-499"


#############
# PROVIDERS #
#############
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: /configurations/dynamic.yml
    watch: true

##########################
# CERTIFICATES RESOLVERS #
##########################
certificatesResolvers:
  letsencrypt:
    acme:
      email: monmail@mail.com
      storage: acme.json
      keyType: EC384
      httpChallenge:
        entryPoint: web

Ici on va donc

  • activer l'API
  • créer nos entrypoint sur les ports 80  et 443 et forcer le port 80 à être rediriger vers le port 443.
  • Le port 443 fait appel à notre fichier dynamic.yml qui va configurer les headers SSL (middleware secureHeader) et Let's Encrypt pour vos certificats (middleware tls)
  • On active les  logs
  • on créer un provider docker

./traefik-data/configurations/dynamic.yml

# Dynamic configuration
http:
  middlewares:
    secureHeaders:
      headers:
        sslRedirect: true
        browserXssFilter: true
        contentTypeNosniff: true
        frameDeny: true
        #HSTS Configuration
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 31536000
        customFrameOptionsValue: "SAMEORIGIN"

    authentification:
      basicAuth:
        users:
          # Generate username:$hash$password : htpasswd -n <username>
          - "username:$apr1$nxE8Sh7X$6Km8H/KybRakcGCPi1FfF/"

tls:
  options:
    default:
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
      minVersion: VersionTLS12

Ici on déclare donc :

On démarre le container : docker compose up -d. Voila le container fonctionne, maintenant il ne reste plus qu'a mettre en place un site pour tester, rien de mieux que l'application whoami 😁

On ajoute dans notre docker-compose.yml de traefik la section suivante :

# WHOAMI #
#========#

  whoami:
    image: traefik/whoami
    container_name: whoami
    hostname: whoami
    restart: unless-stopped
    networks:
      - traefik_proxy
    labels:
      traefik.enable: true
      traefik.docker.network: traefik_proxy
      traefik.http.routers.whoami.entrypoints: websecure
      traefik.http.routers.whoami.rule: Host(`public.domain.com`)
      traefik.http.routers.whoami.service: whoami
      traefik.http.services.whoami.loadbalancer.server.port: 80

Pensez à changer public.domain.com par votre url perso, Et voila, vous devriez maintenant accéder à une page, avec un certificat valide SSL.

Easy non ? Et cerise sur le gâteau, avec cette configuration vous obtiendrez un A+ sur le site : https://www.ssllabs.com/ssltest/. Tout ça grâce uniquement aux labels dans le docker-compose.

Par la suite je vous expliquerai pourquoi et comment mettre en place un DNS Challenge via l'API de OVH.