Traefik avec support HTTPS
2020-05-08T15:00:00Z | 8 minutes de lecture | Mise à jour le 2020-09-05T00:08:08+02:00
Suite de mon introduction à Traefik v2, on applique maintenant le support de TLS pour nos services Web.
Introduction
Dans la continuité de mon introduction à Traefik v2, nous allons voir ici comment j’ai fait pour passé en HTTPS. Pour cela, j’ai généré des certificats Let’s Encrypt en utilisant le défi DNS dont j’ai parlé dans un autre article.
Après la mise en place des éléments du protocole ACME (résolveur), nous verrons comment appliquer cela à notre dashboard (configuration dynamique par fichier) et ensuite la démarche pour des conteneurs Web externes (configuration dynamique avec les labels).
Configuration du résolveur
Organisation
Je travaille en root (sudo -i
) dans le dossier /root/docker/traefik/
.
Depuis l’autre article, j’ai ordonné les fichiers en les mettant dans un dossier config
.
Voici d’avance la liste des fichiers de cette partie :
/root/docker/traefik/docker-compose.yml
/root/docker/traefik/config/traefik.yml
/root/docker/traefik/config/dynamique/dashboard.yml
/root/docker/traefik/config/acme.json
/root/docker/traefik/config/.ovh-api.env
Fichier Docker Compose
Voici donc le contenu du fichier docker-compose.yml
:
|
|
Vous remarquerez les spécificités suivantes :
- J’ai commenté la ligne d’exposition du port du dashboard vu que l’on va y accéder en HTTPS (donc sur le port 443)
- J’ai ajouté un fichier de variable d’environnement : il contiendra les clés nécessaires pour la connexion à l’API d’OVH
- J’ai mappé un fichier
acme.json
dans lequel seront stockés les éléments constituant les certificats
Fichier de configuration de Traefik
Le fichier config/traefik.yml
:
|
|
- J’ai décidé de mettre des noms stupides pour faciliter la compréhension : 2,4,25
- La ligne 28 contient l’adresse e-mail transmise à Let’s Encrypt (LE)
- A la ligne 35, vous remarquerez que j’ai spécifié l’adresse de “staging” de LE
afin d’obtenir des certificats de tests.
Vous trouverez plus d’information dessus sur la documentation officiel - Pour la configuration du défi DNS, je spécifie explicitement des DNS externes afin de ne pas entrer en conflit avec mon DNS interne
Cette configuration est à adapter selon vos spécificités.
Si vous préférez utiliser le défi HTTP-01, supprimez les lignes [40-46]
et décommentez-les [38-39].
Fichier des variables d’environnement
Pour connaitre les informations de votre fournisseur DNS
afin de faire votre fichier de variables, je vous invite à regarder la
documentation à ce sujet.
Vous pouvez aussi vous rendre sur
la page du module LEGO,
module qu’utilise Traefik pour résoudre le défi.
Voici (en quelque sorte 🤣) le mien (config/.ovh-api.env
) :
# OVH API credentials used by Certbot
OVH_ENDPOINT=ovh-eu
OVH_APPLICATION_KEY=bugsbunny
OVH_APPLICATION_SECRET=bipbip
OVH_CONSUMER_KEY=speedygonzales
Fichier des certificats
Le fichier acme.json
doit être créé avec les droits RW seulement.
Il est impératif que ce fichier existe avant le lancement de la stack.
Dans le cas contraire, un dossier sera créé à sa place et génèrera
donc une erreur.
touch config/acme.json
chmod 600 config/acme.json
Si vos essais mènent à des erreurs, je vous conseille d’effacer ce fichier et de le récréer à chaque fois.
Dashboard en HTTPS
Maintenant que nous avons notre résolveur de configuré, nous allons pouvoir appliquer cela à notre dashbord.
Le fichier config/dynamique/dashboard.yml
prend donc la forme suivante :
|
|
On déclare donc un routeur api-secure
(donnez lui n’importe quel nom) sur
lequel on applique l’option tls:
en spécifiant le résolveur définis dans
le fichier de configuration de Traefik.
Avec ce routeur seul, le dashboard sera accessible seulement en tapant l’adresse en HTTPS. Pour avoir la redirection (HTTP vers HTTPS), on est obligé de créer un autre routeur comme le précise la section TLS de la documentation :
If you need to define the same route for both HTTP and HTTPS requests, you will need to define two different routers: one with the tls section, one without.
C’est donc ce que j’ai fait avec le routeur api
où je demande l’application
de la redirection définie en fin de fichier que j’ai sobrement appelé redirection
.
J’ai fait suivre le lancement de la stack (docker-compose up -d
)
d’un docker-compose logs -f
afin de voir les évènements.
En tapant traefik.scrample.xyz
dans la barre d’adresse,
je suis bien redirigé en HTTPS car j’ai l’avertissement d’un mauvais certificat
car j’utilise l’environnement de qualification de LE.
Une fois l’exception ajoutée, j’ai bien la demande d’authentification basique.
Service Web en HTTPS
Pour faire simple, j’ai crée un conteneur Nginx dans un nouveau Docker Compose.
Je suis donc dans un autre dossier que celui de Traefik : /root/docker/web
J’y ai appliqué les mêmes règles que sur le dashbord mais en labels cette fois-ci.
Mon fichier prend donc la forme suivante :
version: '3.7'
services:
monsiteweb:
image: nginx:alpine
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.http.routers.monsiteweb.rule=Host(`mywebsite.scrample.xyz`)"
- "traefik.http.middlewares.redirection-monsiteweb.redirectscheme.scheme=https"
- "traefik.http.middlewares.redirection-monsiteweb.redirectscheme.permanent=true"
- "traefik.http.routers.monsiteweb.middlewares=redirection-monsiteweb"
- "traefik.http.routers.monsiteweb-secure.rule=Host(`mywebsite.scrample.xyz`)"
- "traefik.http.routers.monsiteweb-secure.tls=true"
- "traefik.http.routers.monsiteweb-secure.tls.certresolver=tomandjerry"
networks:
- proxy-net
networks:
proxy-net:
external:
name: traefik-net
Finalement, je me rends compte que c’est plutôt embêtant de faire la redirection pour chaque service… Ça double le nombre de routeur et d’intermédiaire ("middlewares"). J’ai donc cherché une façon d’appliquer la redirection de manière globale.
Redirection globale
Après avoir tout cassé (double docker-compose down
),
j’ai effectué les actions suivantes :
- Suppression des “redirecteurs” (vous m’avez compris) :
- Dashboard
- Conteneur Nginx
- Ajout d’une redirection globale
Ci-dessous, les fichiers que j’ai modifiés :
traefik/config/traefik.yml
|
|
traefik/config/dynamique/dashboard.yml
http:
routers:
api:
rule: "Host(`traefik.scrample.xyz`)"
service: api@internal
tls:
certResolver: tomandjerry
middlewares:
- auth
middlewares:
auth:
basicAuth:
users:
- "admin:$2y$10$sqgVdrmQxXQgYIpg3BycVuZ2J8sFSHheVnmd728KkE7fznFSlxA0u"
- "test:$2y$10$mPcvlMccO2mXjA2ye.uBWuhO36x46K/3b.g1AjJ1YllmKCSAuS.vG"
web/docker-compose.yml
version: '3.7'
services:
monsiteweb:
image: nginx:alpine
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.http.routers.monsiteweb.rule=Host(`mywebsite.scrample.xyz`)"
- "traefik.http.routers.monsiteweb.tls=true"
- "traefik.http.routers.monsiteweb.tls.certresolver=tomandjerry"
networks:
- proxy-net
networks:
proxy-net:
external:
name: traefik-net
C’est clairement plus simple !
J’ai remarqué qu’un routeur assez spécial est apparu sur le dashboard : La règle de “catching” est une expression régulière qui “match” tous les hôtes.
Pour avoir des certificats de production, il suffit de commenter la ligne
précisant le endpoint de l’API de LE (ligne 41 de traefik.yml
).
Cela est suffisant car la valeur par défaut de cette variable est celle du
serveur “normal” (soit “https://acme-v02.api.letsencrypt.org/directory").
Conclusion
Avec ce deuxième article sur Traefik, nous avons pu poser les bases d’une utilisation simple de ce “Edge Router”.
La série sur Traefik n’est pas finie, elle continuera quand j’aurai le courage de mettre cela en place en production. On verra surement s’il est possible d’aller plus loin et comment récupérer les métriques pour meublé un peu plus Grafana.