Traefik est un reverse proxy Open Source écrit en Go. Il a été spécialement développé pour fonctionner avec Docker. Voila les principales fonctionnalités :
Génération et renouvellement des certificats Let’s Encrypt
Support des plugins écrit en Go
Interface web
Pré-requis
Avant de continuer, assurez-vous d’avoir installé Docker et Docker-compose. Pour cela vous pouvez suivre les docs suivantes :
Traefik étant écrit en Go, vous pouvez télécharger le binaire mais la façon la plus commune est d’utiliser une image Docker.
Nous allons donc commencer par créer l’arborescence que nous allons utiliser
/srv/docker/traefik/certs/ contiendra les certificats Let’s Encrypt pour les sites web
/srv/docker/traefik/conf/ contiendra la configuration statique de Traefik
/srv/docker/traefik/dynamic/ contiendra la configuration dynamique de Traefik
/srv/docker/traefik/logs/ contiendra les logs de Traefik
La modification des fichiers de configuration statique nécessiteront un redémarrage du conteneur pour être pris en compte.
La modification des fichiers de configuration dynamique sont lus à chaque requêtes HTTP.
L’ensemble des fichiers de configuration de cette doc seront au format YML.
Nous allons créer le fichier de configuration statique de Traefik. Pour cela on tape la commande suivante :
global:
# On spécifie que l'on ne veut pas envoyer/partager les données d'usage avec TraefikLabs (Société derrière Traefk
sendAnonymousUsage: false
entryPoints:
# On configure un point d'entré nommé arbitrairement "web"
web:
# On spécifie le port d'entré. Ici le port 80 (http)
address: ':80'
# On redirige l'ensemble du trafic arrivant sur le port 80 http) sur le point d'entré nommé "web_secure", qui est le port 443 (https)
http:
redirections:
entryPoint:
to: web_secure
# On configure un point d'entré nommé arbitrairement "web_secure"
web_secure:
# On spécifie le port d'entré. Ici le port 443 (https)
address: ':443'
# Via le middlewares "SecHeader@file", on applique des
http:
middlewares:
- SecHeader@file
api:
# On active le dashboard (Interface web)
dashboard: True
# On désactive l'accès à l'API de Traefik
insecure: False
log:
# On spécifie le répertoire de stockage des logs de Traefik
filePath: /srv/docker/traefik/logs/traefik.log
# On spécifie le format de stockage des logs
format: common
# On précise le niveau des logs
level: INFO
accessLog:
# On spécifie le répertoire de stockage des logs d'accès au conteneur
filePath: /var/log/traefik/traefik_access.log
providers:
# On indique que l'on va utiliser Docker
docker:
# On désactive l'accès au conteneur Docker autrement que via Traefik
exposedByDefault: False
file:
# On spécifie le répertoire de stockage du fichier de configuration de Traefik
directory: /etc/traefik/config/
certificatesResolvers:
# On spécifie que l'on veut utiliser Certbot (Let's Encrypt pour la génération/gestion des certificats)
certbot:
acme:
# On spécifie l'email à utiliser pour nous prévenir en cas d'expiration du/des certificats SSL
email: mon_adresse_mail@mon-domaine.fr
# On spécifie le format de clé privé à générer/utiliser avec notre certificat
keyType: 'RSA4096'
# On spécifie le répertoire de stockage du certificat
storage: /letsencrypt/acme.json
# On précise le point d'entré à utiliser pour la génération/renouvellement des certificats
httpChallenge:
entryPoint: web
Nous allons créer le fichier de configuration TLS de Traefik. Pour cela on tape la commande suivante :
1
# vi /srv/docker/traefik/dynamic/tls.yml
On y copie le contenu suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tls:
options:
default:
# On spécifie la version minimum de TLS qui sera prise en charge par Traefik
minVersion: VersionTLS12
# On refuse la connexion aux sites Web qui n'ont pas de certificat TLS valide
sniStrict: True
# On spécifie les suites de Cipher qui seront pris en charge par Traefik
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
Nous allons créer le fichier de configuration middlewares de Traefik. Pour cela on tape la commande suivante :
1
# vi /srv/docker/traefik/dynamic/middleswares.yml
On y copie le contenu suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
http:
middlewares:
SecHeader:
# On défini les différences headers
headers:
# On défini X-Frame-Options à deny
frameDeny: True
# On défine X-Content-Type-Options à nosniff
contentTypeNosniff: True
referrerPolicy: same-origin
# On définie X-XSS-Protection à "1; mode=block"
browserXssFilter: True
# On ajoute les STSHeader même lorsque la connexion se fait en HTTP
forceSTSHeader: True
# On ajoute la directive "includeSubDomains" au header "Strict-Transport-Security"
stsIncludeSubdomains: True
# On défini la durée de vie du header "Strict-Transport-Security"
stsSeconds: 31536000
Afin que Traefik puisse ajouter les logs, nous devons créer les fichiers de logs vide. Pour cela, on tape la commande suivante :
Docker-compose est un outil indispensable pour simplifier la gestion des conteneurs Docker. Il est
disponible sur le dépôt Github du même nom Docker-compose.
Nous allons récupérer la dernière version à la date d’écriture de l’article et l’installer dans le répertoire /usr/local/bin/ via la commande suivante :
Nous avons récupérer le binaire de Docker-compose, pour autant nous ne pouvons pas l’utiliser. Nous devons le rendre exécutable. Pour cela, on tape la commande suivante :
1
# chmod +x /usr/local/bin/docker-compose
Et voilà, vous êtes prêt à utiliser des conteneurs 😉
Installation de Traefik
Docker met à disposition un site regroupant un très grand nombre d’images Docker, le Docker Hub. Il n’est pas nécessaire de créer un compte pour récupérer des images. Il l’est uniquement si l’on souhaite en mettre à disposition.
Nous allons utiliser l’image officielle mise à disposition pour la société éditrice “Containous”.
Nous n’allons pas récupérer manuellement l’image Traefik. Nous la récupérons automatiquement lorsque nous lancerons la commande “docker-compose”. En effet c’est elle qui s’en chargera automatiquement.
Nous allons créer le fichier docker-compose.yml via la commande suivante :
---
# Version du format du fichier docker-compose.yml
version: '3.7'
services:
# On défini le nom du service
traefik:
# On défini le nom du conteneur
conteneur_name: traefik
# On défini l'image à utiliser
image: traefik:latest
# On défini la politique de redémarrage du conteneur
restart: unless-stopped
# On défini les dossiers et fichiers qui seront accessibles depuis le conteneur
volumes:
# Trafik peut se connecter au socket Docker
- /var/run/docker.sock:/var/run/docker.sock
# On défini que le répertoire /letsencrypt/ du conteneur correspond au répertoire /srv/docker/traefik/certs/ de notre hôte
- ./certs/:/letsencrypt/
# On défini que le fichier /etc/traefik/traefik.yml du conteneur correspond au répertoire /srv/docker/traefik/conf/traefik.yml de notre hôte. Le conteneur n'y aura accès qu'en lecture
- ./conf/traefik.yml:/etc/traefik/traefik.yml:ro
# On défini que le répertoire /etc/traefik/config/ du conteneur correspond au répertoire /srv/docker/traefik/dynamic/ de notre hôte. Le conteneur n'y aura accès qu'en lecture
- ./dynamic/:/etc/traefik/config/:ro
# On défini que le fichier /var/log/traefik/traefik.log du conteneur correspond au répertoire /srv/docker/traefik/logs/traefik.log de notre hôte
- ./logs/traefik.log:/var/log/traefik/traefik.log
# On défini que le fichier /var/log/traefik/traefik_access.log du conteneur correspond au répertoire /srv/docker/traefik/logs/traefik_access.log de notre hôte
- ./logs/traefik_access.log:/var/log/traefik/traefik_access.log
# On défini les réseaux. J'en ai volontairement créé deux. Afin de pouvoir isoler les futurs conteneurs dans un réseau à part
networks:
traefik_lan:
wan:
# On défini les ports réseaux qui seront accessibles depuis l'hôte
ports:
- '80:80'
- '443:443'
# On défini les paramètres spécifiques à Traefik
labels:
# On active Traefik pour ce conteneur
traefik.enable: True
# On indique à Traefik que les ports accessibles depuis l'hôte, le seront sur le réseau "wan"
traefik.docker.network: wan
# On indique à Traefik de lire la configuration SSL/TLS contenu dans le fichier SecHeader@file précédemment créé
traefik.http.routers.traefik.middlewares: SecHeader@file
# On indique l'URL à partir de laquelle l'interface web de Traefik sera accessible
traefik.http.routers.traefik.rule: Host(`traefik.mon-domaine.fr`)
#
traefik.http.routers.traefik.service: api@internal
# On indique à Traefik d'activer le TLS pour ce conteneur
traefik.http.routers.traefik.tls: True
# On indique à Traefik d'utiliser "certbot" (Let's Encrypt) pour la génération des certificats
traefik.http.routers.traefik.tls.certresolver: certbot
# On défini les réseaux liés au conteneur
networks:
traefik_lan:
# On indique que le réseau sera externe. C'est à dire qu'il ne sera pas supprimé lors de la suppression du conteneur
external: True
wan:
# # On indique que le réseau sera externe. C'est à dire qu'il ne sera pas supprimé lors de la suppression du conteneur
external: True
Il nous reste une dernière chose à faire, créer les réseaux qui seront utilisés par notre conteneur (wan et traefik_lan). Pour cela, on tape la commande suivante :
1
2
# docker network create wan
# docker network create traefik_lan
Ajout d’une authentification basic pour l’accès au dashboard Traefik
Petite précision, l’authentification proposé par Traefik est basic. Vous aurez un popup qui vous demandera de vous authentifier au premier accès, ensuite vous n’aurez plus d’authentification tant que vous n’aurez pas vider le cache de votre navigateur.
Ce point précisé, nous pouvons poursuivre la mise en place. La première chose à faire est d’installer de binaire htpasswd :
Pour Debian :
1
# apt install apache2-utils
Pour CentOS :
1
# dnf install httpd-tools
Ensuite on créer le répertoire dans lequel sera stocké le fichier contiendra les utilisateurs et les mots de passe associés, via la commande suivante :
1
# mkdir /srv/docker/traefik/credentials/
On peut maintenant créer notre utilisateur, ici “admin” avec le mot de passe “password” via la commande suivante :
Nous devons ajouter un nouveau middleware qui s’occupera de l’authentification. On édite le fichier /srv/docker/traefik/dynamic/middlewares.yml, via la commande suivante :
1
# vi /srv/docker/traefik/dynamic/middlewares.yml
On y ajoute le contenu ci dessous. Attention “authentication doit être alligné sur le middleware SecHeader
1
2
3
4
authentication:
basicAuth:
# On défini le chemin d'accès au fichier contenant les uses dans le conteneur
usersFile: "/credentials/.password"
On doit maintenant modifier, la configuration du conteneur pour lui ajouter un nouveau répertoire à mapper et modifier la configuration pour ajouter le middleware précédement créé. Pour cela, on édite le fichier docker-compose.yml via la commande suivante :
1
# vi /srv/docker/traefik/docker-compose.yml
Voici le docker-compose.yml contenant les lignes pour l’authentification :
---
# Version du format du fichier docker-compose.yml
version: '3.7'
services:
# On défini le nom du service
traefik:
# On défini le nom du conteneur
conteneur_name: traefik
# On défini l'image à utiliser
image: traefik:latest
# On défini la politique de redémarrage du conteneur
restart: unless-stopped
# On défini les dossiers et fichiers qui seront accessibles depuis le conteneur
volumes:
# Trafik peut se connecter au socket Docker
- /var/run/docker.sock:/var/run/docker.sock
# On défini que le répertoire /letsencrypt/ du conteneur correspond au répertoire /srv/docker/traefik/certs/ de notre hôte
- ./certs/:/letsencrypt/
# On défini que le fichier /etc/traefik/traefik.yml du conteneur correspond au répertoire /srv/docker/traefik/conf/traefik.yml de notre hôte. Le conteneur n'y aura accès qu'en lecture
- ./conf/traefik.yml:/etc/traefik/traefik.yml:ro
# On défini que le répertoire /credentials/ du conteneur correspond au répertoire /srv/docker/traefik/credentials/ de notre hôte. Le conteneur n'y aura accès qu'en lecture
- ./credentials/:/credentials/:ro
# On défini que le répertoire /etc/traefik/config/ du conteneur correspond au répertoire /srv/docker/traefik/dynamic/ de notre hôte. Le conteneur n'y aura accès qu'en lecture
- ./dynamic/:/etc/traefik/config/:ro
# On défini que le fichier /var/log/traefik/traefik.log du conteneur correspond au répertoire /srv/docker/traefik/logs/traefik.log de notre hôte
- ./logs/traefik.log:/var/log/traefik/traefik.log
# On défini que le fichier /var/log/traefik/traefik_access.log du conteneur correspond au répertoire /srv/docker/traefik/logs/traefik_access.log de notre hôte
- ./logs/traefik_access.log:/var/log/traefik/traefik_access.log
# On défini les réseaux. J'en ai volontairement créé deux. Afin de pouvoir isoler les futurs conteneurs dans un réseau à part
networks:
traefik_lan:
wan:
# On défini les ports réseaux qui seront accessibles depuis l'hôte
ports:
- '80:80'
- '443:443'
# On défini les paramètres spécifiques à Traefik
labels:
# On active Traefik pour ce conteneur
traefik.enable: True
# On indique à Traefik que les ports accessibles depuis l'hôte, le seront sur le réseau "wan"
traefik.docker.network: wan
# On indique à Traefik de lire la configuration SSL/TLS contenu dans le fichier SecHeader@file précédemment créé
traefik.http.routers.traefik.middlewares: authentication@file,SecHeader@file
# On indique l'URL à partir de laquelle l'interface web de Traefik sera accessible
traefik.http.routers.traefik.rule: Host(`traefik.mon-domaine.fr`)
#
traefik.http.routers.traefik.service: api@internal
# On indique à Traefik d'activer le TLS pour ce conteneur
traefik.http.routers.traefik.tls: True
# On indique à Traefik d'utiliser "certbot" (Let's Encrypt) pour la génération des certificats
traefik.http.routers.traefik.tls.certresolver: certbot
# On défini les réseaux liés au conteneur
networks:
traefik_lan:
# On indique que le réseau sera externe. C'est à dire qu'il ne sera pas supprimé lors de la suppression du conteneur
external: True
wan:
# # On indique que le réseau sera externe. C'est à dire qu'il ne sera pas supprimé lors de la suppression du conteneur
external: True
Maintenant que l’ensemble des fichiers sont créés, nous pouvons lancer notre conteneur. Pour cela, on tape la commande suivante :
1
# docker-compose -f /srv/docker/traefik/docker-compose.yml up -d
Via l’option “-d” on indique à docker de lancer le conteneur en mode daemon.
Vous pouvez vérifier le bon fonctionnement de votre conteneur en vous connectant sur l’interface web (Dashboard) : https://traefik.mon-domaine.fr/
Vous devriez avoir cela, après avoir rentré votre utilisateur et mot de passe, défini plus haut :