« Traefik » : différence entre les versions

De Wiki doc

(Remplacement des schémas ASCII Art en SVG)
(Remplacement des balises "source" obsolètes par "syntaxhighlight")
 
Ligne 31 : Ligne 31 :
  vim /etc/systemd/system/traefik.service
  vim /etc/systemd/system/traefik.service


<source lang="ini">
<syntaxhighlight lang="ini">
[Unit]
[Unit]
Description=Traefik, circulez y'a rien à voir !
Description=Traefik, circulez y'a rien à voir !
Ligne 48 : Ligne 48 :
[Install]
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target
</source>
</syntaxhighlight>


Chargement du service au démarrage du système
Chargement du service au démarrage du système
Ligne 59 : Ligne 59 :
=Configuration de base=
=Configuration de base=
Le fichier de configuration de ''Traefik'' est au format ''TOML'', mais peux être également au format ''JSON''. Il y a donc deux noms de fichier recommandés suivant le langage utilisé :
Le fichier de configuration de ''Traefik'' est au format ''TOML'', mais peux être également au format ''JSON''. Il y a donc deux noms de fichier recommandés suivant le langage utilisé :
* <source lang="bash" inline>traefik.toml</source>
* <syntaxhighlight lang="bash" inline>traefik.toml</syntaxhighlight>
* <source lang="bash" inline>traefik.yml</source>
* <syntaxhighlight lang="bash" inline>traefik.yml</syntaxhighlight>


Ce fichier est attendu dans l'une de ces arborescences :
Ce fichier est attendu dans l'une de ces arborescences :
* <source lang="bash" inline>/etc/traefik/</source>
* <syntaxhighlight lang="bash" inline>/etc/traefik/</syntaxhighlight>
* <source lang="bash" inline>$HOME/.config</source>
* <syntaxhighlight lang="bash" inline>$HOME/.config</syntaxhighlight>
* <source lang="bash" inline>.</source> (Dans la même arborescence que le binaire)
* <syntaxhighlight lang="bash" inline>.</syntaxhighlight> (Dans la même arborescence que le binaire)


Nous pouvons également définir à ''Traefik'' un fichier de configuration spécifique :
Nous pouvons également définir à ''Traefik'' un fichier de configuration spécifique :
<source lang="bash">
<syntaxhighlight lang="bash">
traefik --configFile=foo/bar/myconfigfile.toml
traefik --configFile=foo/bar/myconfigfile.toml
</source>
</syntaxhighlight>


{{attention|Dans ce fichier, il est attendu une configuration statique. Une modification de celui-ci nécessitera une relance de ''Traefik'' pour qu'elles soient prisent en compte. Sont également concernés les fichiers étrangers aux différents hôtes virtuels comme par exemple ''middleware.toml'' et  ''tls.toml'' que nous verrons plus bas. Seules les fichiers contenants les directives ''routers'' et ''services'' ne nécessites pas de redémarrage du service.}}
{{attention|Dans ce fichier, il est attendu une configuration statique. Une modification de celui-ci nécessitera une relance de ''Traefik'' pour qu'elles soient prisent en compte. Sont également concernés les fichiers étrangers aux différents hôtes virtuels comme par exemple ''middleware.toml'' et  ''tls.toml'' que nous verrons plus bas. Seules les fichiers contenants les directives ''routers'' et ''services'' ne nécessites pas de redémarrage du service.}}
Ligne 78 : Ligne 78 :
  vim /opt/traefik/config/traefik.toml
  vim /opt/traefik/config/traefik.toml


<source lang="yaml">
<syntaxhighlight lang="yaml">
# Configuration globale de Traefik
# Configuration globale de Traefik
[global]
[global]
Ligne 109 : Ligne 109 :
   [entryPoints.http] # Permet de déclarer un point d'entrée nommé "http"
   [entryPoints.http] # Permet de déclarer un point d'entrée nommé "http"
     address = ":80" # Permet de déclarer le port d'entrée
     address = ":80" # Permet de déclarer le port d'entrée
</source>
</syntaxhighlight>


{{attention|Pour les <source lang="bash" inline>filePath</source> des sections <source lang="bash" inline>[log]</source> et <source lang="bash" inline>[accessLog]</source>, il faudra prévoir une rotation du fichier journal (voir [[Logrotate]]) car ''Traefik'' ne gère pas cette fonction. Ceci est indispensable pour ne pas voir votre partition se remplir jusqu'à déni de service.}}
{{attention|Pour les <syntaxhighlight lang="bash" inline>filePath</syntaxhighlight> des sections <syntaxhighlight lang="bash" inline>[log]</syntaxhighlight> et <syntaxhighlight lang="bash" inline>[accessLog]</syntaxhighlight>, il faudra prévoir une rotation du fichier journal (voir [[Logrotate]]) car ''Traefik'' ne gère pas cette fonction. Ceci est indispensable pour ne pas voir votre partition se remplir jusqu'à déni de service.}}


Comme nous avons édité le fichier de configuration principal du serveur, il faut recharger le service
Comme nous avons édité le fichier de configuration principal du serveur, il faut recharger le service
Ligne 117 : Ligne 117 :


=Fonctionnalités=
=Fonctionnalités=
L'outil permet un éventail de fonctionnalités souvent rencontrées dans des logiciels de ce type. Elles sont décrites dans un ou plusieurs fichiers. Un hôte étant définit par des sections, il est possible d'en combiner plusieurs en un seul fichier ou d'en faire un par fichier. Ceci est configuré dans le paramètre <source lang="bash" inline>directory</source> de la directive <source lang="bash" inline>[providers]</source> vu précédemment. Comme précisé par le paramètre <source lang="bash" inline>watch</source> de cette même directive, ces fichiers sont appliqués au serveur à chaque enregistrements.
L'outil permet un éventail de fonctionnalités souvent rencontrées dans des logiciels de ce type. Elles sont décrites dans un ou plusieurs fichiers. Un hôte étant définit par des sections, il est possible d'en combiner plusieurs en un seul fichier ou d'en faire un par fichier. Ceci est configuré dans le paramètre <syntaxhighlight lang="bash" inline>directory</syntaxhighlight> de la directive <syntaxhighlight lang="bash" inline>[providers]</syntaxhighlight> vu précédemment. Comme précisé par le paramètre <syntaxhighlight lang="bash" inline>watch</syntaxhighlight> de cette même directive, ces fichiers sont appliqués au serveur à chaque enregistrements.


Parmi les fonctionnalités que nous avons explorées, nous pouvons noter la possibilité de faire:
Parmi les fonctionnalités que nous avons explorées, nous pouvons noter la possibilité de faire:
Ligne 136 : Ligne 136 :
  vim /opt/traefik/config/vhosts/ma_page.toml
  vim /opt/traefik/config/vhosts/ma_page.toml


<source lang="yaml">
<syntaxhighlight lang="yaml">
# Service de type http
# Service de type http
[http]
[http]
Ligne 148 : Ligne 148 :
       [[http.services.ma_page.loadBalancer.servers]] # Déclaration d'un serveur  
       [[http.services.ma_page.loadBalancer.servers]] # Déclaration d'un serveur  
         url = "http://[2001:db8:0:180::a0]" # URL vers mon serveur MaPage
         url = "http://[2001:db8:0:180::a0]" # URL vers mon serveur MaPage
</source>
</syntaxhighlight>


Vous pouvez noter le mot clé <source lang="bash" inline>loadBalancer</source> à la ligne créant le service (<source lang="bash" inline>[http.services.ma_page.loadBalancer]</source>). En fait, ''Traefik'' fait constament de la répartition de charge, même avec un seul hôte (ce qui revient à toujours envoyer les requêtes sur la même machine). La configuration d'une réelle répartition de charge consiste donc à ajouter un hôte, d'où la simplicité de mise en œuvre. Nous verrons ceci plus bas.
Vous pouvez noter le mot clé <syntaxhighlight lang="bash" inline>loadBalancer</syntaxhighlight> à la ligne créant le service (<syntaxhighlight lang="bash" inline>[http.services.ma_page.loadBalancer]</syntaxhighlight>). En fait, ''Traefik'' fait constament de la répartition de charge, même avec un seul hôte (ce qui revient à toujours envoyer les requêtes sur la même machine). La configuration d'une réelle répartition de charge consiste donc à ajouter un hôte, d'où la simplicité de mise en œuvre. Nous verrons ceci plus bas.


Il est également possible de faire des règles (paramètre <source lang="bash" inline>rule</source>) avec plus de conditions en utilisant des [https://docs.traefik.io/routing/routers/#rule structures conditionnelles] telles que <source lang="bash" inline>||</source> ou <source lang="bash" inline>&&</source>.
Il est également possible de faire des règles (paramètre <syntaxhighlight lang="bash" inline>rule</syntaxhighlight>) avec plus de conditions en utilisant des [https://docs.traefik.io/routing/routers/#rule structures conditionnelles] telles que <syntaxhighlight lang="bash" inline>||</syntaxhighlight> ou <syntaxhighlight lang="bash" inline>&&</syntaxhighlight>.


==Authentification==
==Authentification==
Ligne 159 : Ligne 159 :
<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_http_auth.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>
<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_http_auth.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>


Pour ce faire, nous allons créer un fichier ''htpasswd'' (utilitaire présent dans le paquet <source lang="bash" inline>apache2-utils</source>):
Pour ce faire, nous allons créer un fichier ''htpasswd'' (utilitaire présent dans le paquet <syntaxhighlight lang="bash" inline>apache2-utils</syntaxhighlight>):


  htpasswd -c /opt/traefik/passwd/groupe1 ycharbi
  htpasswd -c /opt/traefik/passwd/groupe1 ycharbi


{{attention| Si vous voulez ajouter un utilisateur, utilisez la commande suivante : <source lang="bash" inline>htpasswd /opt/traefik/passwd/groupe1 nmorin</source>. L'usage du paramètre <source lang="bash" inline>-c</source> ne devant être utilisé que pour la création du fichier, sous peine de l'écraser. De plus, il faut impérativement relancer le service pour prendre en compte tout ajout/modification/suppression.}}
{{attention| Si vous voulez ajouter un utilisateur, utilisez la commande suivante : <syntaxhighlight lang="bash" inline>htpasswd /opt/traefik/passwd/groupe1 nmorin</syntaxhighlight>. L'usage du paramètre <syntaxhighlight lang="bash" inline>-c</syntaxhighlight> ne devant être utilisé que pour la création du fichier, sous peine de l'écraser. De plus, il faut impérativement relancer le service pour prendre en compte tout ajout/modification/suppression.}}


Un ''middleware'' est unique au sein de ''Traefik'', bien qu'il soit possible de mettre la section dédiée directement dans l'hôte concerné, il est plus judicieux de leur créer un fichier propre afin de pouvoir piocher dedans les groupes d'utilisateurs pour les authentifications:
Un ''middleware'' est unique au sein de ''Traefik'', bien qu'il soit possible de mettre la section dédiée directement dans l'hôte concerné, il est plus judicieux de leur créer un fichier propre afin de pouvoir piocher dedans les groupes d'utilisateurs pour les authentifications:
Ligne 169 : Ligne 169 :
  vim /opt/traefik/config/vhosts/middlewares.toml
  vim /opt/traefik/config/vhosts/middlewares.toml


<source lang="yaml">
<syntaxhighlight lang="yaml">
# Service de type http
# Service de type http
[http]
[http]
Ligne 175 : Ligne 175 :
     [http.middlewares.mon_auth.basicAuth] # Création d'un middleware nommé "mon_auth" de type "basicAuth"
     [http.middlewares.mon_auth.basicAuth] # Création d'un middleware nommé "mon_auth" de type "basicAuth"
       usersFile = "/opt/traefik/passwd/groupe1" # Définit l'arborescence du fichier htpasswd
       usersFile = "/opt/traefik/passwd/groupe1" # Définit l'arborescence du fichier htpasswd
</source>
</syntaxhighlight>


Puis nous allons reprendre le fichier <source lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</source>:
Puis nous allons reprendre le fichier <syntaxhighlight lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</syntaxhighlight>:


<source lang="yaml">
<syntaxhighlight lang="yaml">
[http]
[http]
   [http.routers]
   [http.routers]
Ligne 191 : Ligne 191 :
       [[http.services.ma_page.loadBalancer.servers]]
       [[http.services.ma_page.loadBalancer.servers]]
         url = "http://[2001:db8:0:180::a0]"
         url = "http://[2001:db8:0:180::a0]"
</source>
</syntaxhighlight>


==Répartition de charges==
==Répartition de charges==
Ligne 200 : Ligne 200 :
L'ajout d'un serveur dans le système de répartition de charge est très simple. Il faut seulement déclarer un autre serveur dans le service. La répartition de charge utilise l'algorithme d'ordonnancement [https://fr.wikipedia.org/wiki/Round-robin_(informatique) Round-robin].
L'ajout d'un serveur dans le système de répartition de charge est très simple. Il faut seulement déclarer un autre serveur dans le service. La répartition de charge utilise l'algorithme d'ordonnancement [https://fr.wikipedia.org/wiki/Round-robin_(informatique) Round-robin].


Reprenons notre fichier <source lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</source> :
Reprenons notre fichier <syntaxhighlight lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</syntaxhighlight> :


<source lang="yaml">
<syntaxhighlight lang="yaml">
[http]
[http]
   [http.routers]
   [http.routers]
Ligne 216 : Ligne 216 :
       [[http.services.ma_page.loadBalancer.servers]] # Déclaration d'un autre serveur  
       [[http.services.ma_page.loadBalancer.servers]] # Déclaration d'un autre serveur  
         url = "http://[2001:db8:0:180::a1]" # URL vers mon serveur 2 MaPage
         url = "http://[2001:db8:0:180::a1]" # URL vers mon serveur 2 MaPage
</source>
</syntaxhighlight>


===Avec persistance de sessions===
===Avec persistance de sessions===
''Traefik'' nous offre la possibilité de gérer la persistance de sessions sur un serveur de manière très simple. Il faut simplement ajouter la valeur <source lang="bash" inline>.sticky.cookie</source> lors de la déclaration de notre service.
''Traefik'' nous offre la possibilité de gérer la persistance de sessions sur un serveur de manière très simple. Il faut simplement ajouter la valeur <syntaxhighlight lang="bash" inline>.sticky.cookie</syntaxhighlight> lors de la déclaration de notre service.


{{info|La persistance de sessions permet d'allouer un client au premier serveur que le ''Round-robin'' lui aura fait joindre. La technique s'appuie sur la génération et l'envoi d'un cookie au navigateur du client (cela ne fonctionne donc pas avec ''curl'' ou ''wget''). Celui-ci présente ce cookie au serveur mandataire qui retransmet sa requête au même serveur qu'au premier échange.}}
{{info|La persistance de sessions permet d'allouer un client au premier serveur que le ''Round-robin'' lui aura fait joindre. La technique s'appuie sur la génération et l'envoi d'un cookie au navigateur du client (cela ne fonctionne donc pas avec ''curl'' ou ''wget''). Celui-ci présente ce cookie au serveur mandataire qui retransmet sa requête au même serveur qu'au premier échange.}}


Toujours dans notre fichier <source lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</source>:
Toujours dans notre fichier <syntaxhighlight lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</syntaxhighlight>:


<source lang="yaml">
<syntaxhighlight lang="yaml">
# Service de type http
# Service de type http
[http]
[http]
Ligne 240 : Ligne 240 :
       [[http.services.ma_page.loadBalancer.servers]]
       [[http.services.ma_page.loadBalancer.servers]]
         url = "http://[2001:db8:0:180::a1]"
         url = "http://[2001:db8:0:180::a1]"
</source>
</syntaxhighlight>


==HTTPS==
==HTTPS==
Ligne 254 : Ligne 254 :
  vim /opt/traefik/config/traefik.toml
  vim /opt/traefik/config/traefik.toml


<source lang="yaml">
<syntaxhighlight lang="yaml">
[global]
[global]
   sendAnonymousUsage = false
   sendAnonymousUsage = false
Ligne 282 : Ligne 282 :
   [entryPoints.https] # Permet de déclarer un autre point d'entrée nommé "https"
   [entryPoints.https] # Permet de déclarer un autre point d'entrée nommé "https"
     address = ":443" # Permet de déclarer le port d'entrée 443
     address = ":443" # Permet de déclarer le port d'entrée 443
</source>
</syntaxhighlight>


Nous allons ajouter un nouveau fichier pour définir les propriétés pas défaut de notre ''TLS'':
Nous allons ajouter un nouveau fichier pour définir les propriétés pas défaut de notre ''TLS'':
Ligne 288 : Ligne 288 :
  vim /opt/traefik/config/vhosts/tls.toml
  vim /opt/traefik/config/vhosts/tls.toml


<source lang="yaml">
<syntaxhighlight lang="yaml">
[tls.options]
[tls.options]
   [tls.options.default]
   [tls.options.default]
Ligne 298 : Ligne 298 :
     curvePreferences = ["x25519", "CurveP521", "CurveP384"] # Définition des algorithmes d'échanges de clés accéptés par le serveur
     curvePreferences = ["x25519", "CurveP521", "CurveP384"] # Définition des algorithmes d'échanges de clés accéptés par le serveur
     preferServerCipherSuites = true # Imposer l'utilisation des suites cryptographiques définies par le serveur
     preferServerCipherSuites = true # Imposer l'utilisation des suites cryptographiques définies par le serveur
</source>
</syntaxhighlight>


''Note: Il est à précisé que GoLang ne permet pas de configurer de suites cryptographiques pour le [https://golang.org/doc/go1.12#tls_1_3 TLS 1.3]. Les développeurs du langage se justifient par le fait qu'elles sont définits dans la RFC 8446, respectés à la lettres et concidérées comme sûr donc y'a pas de problèmes... Personellement je trouve ça moyen surtout quand l'AES 128 bits est le choix par défaut... Ce n'est peut-être que temporaire, l'ajout de ce protocole datant de la version 1.12 du langage Go (on en est à la 1.13 au moment de la rédaction de ce paragraphe).''
''Note: Il est à précisé que GoLang ne permet pas de configurer de suites cryptographiques pour le [https://golang.org/doc/go1.12#tls_1_3 TLS 1.3]. Les développeurs du langage se justifient par le fait qu'elles sont définits dans la RFC 8446, respectés à la lettres et concidérées comme sûr donc y'a pas de problèmes... Personellement je trouve ça moyen surtout quand l'AES 128 bits est le choix par défaut... Ce n'est peut-être que temporaire, l'ajout de ce protocole datant de la version 1.12 du langage Go (on en est à la 1.13 au moment de la rédaction de ce paragraphe).''
Ligne 304 : Ligne 304 :
{{attention|N'oubliez pas que comme nous avons modifié le fichier de configuration principal ainsi qu'un fichier autre qu'un routeur ou un service, il faut relancer ''Traefik'' pour que la prise en compte de la configuration soit effective.}}
{{attention|N'oubliez pas que comme nous avons modifié le fichier de configuration principal ainsi qu'un fichier autre qu'un routeur ou un service, il faut relancer ''Traefik'' pour que la prise en compte de la configuration soit effective.}}


Dans le fichier <source lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</source> :
Dans le fichier <syntaxhighlight lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</syntaxhighlight> :


<source lang="yaml">
<syntaxhighlight lang="yaml">
[http]
[http]
   [http.routers]
   [http.routers]
Ligne 326 : Ligne 326 :
   certFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.crt" # Chemin d'accès au certificat
   certFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.crt" # Chemin d'accès au certificat
   keyFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.key" # Chemin d'accès à la clé du certificat
   keyFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.key" # Chemin d'accès à la clé du certificat
</source>
</syntaxhighlight>


''Note: la génération des certificats est expliquée dans la documentation concernant [[Openssl#Cr.C3.A9ation_d.27un_couple_de_cl.C3.A9s|OpenSSL]]. Prenez garde aux permissions de vos certificats. L'utilisateur "traefik" doit en être le propriétaire.''
''Note: la génération des certificats est expliquée dans la documentation concernant [[Openssl#Cr.C3.A9ation_d.27un_couple_de_cl.C3.A9s|OpenSSL]]. Prenez garde aux permissions de vos certificats. L'utilisateur "traefik" doit en être le propriétaire.''
Ligne 337 : Ligne 337 :
Comme nous pouvons le voir sur le schéma ci-dessus, il faut que l'on déclare un nouveau ''middlewares''.
Comme nous pouvons le voir sur le schéma ci-dessus, il faut que l'on déclare un nouveau ''middlewares''.


Reprenons notre fichier <source lang="bash" inline>/opt/traefik/config/vhosts/middlewares.toml</source>:
Reprenons notre fichier <syntaxhighlight lang="bash" inline>/opt/traefik/config/vhosts/middlewares.toml</syntaxhighlight>:


<source lang="yaml">
<syntaxhighlight lang="yaml">
[http]
[http]
   [http.middlewares]
   [http.middlewares]
Ligne 347 : Ligne 347 :
       scheme = "https" # Redirection vers https
       scheme = "https" # Redirection vers https
       permanent = true # Permet l'envoie d'un code HTTP 301
       permanent = true # Permet l'envoie d'un code HTTP 301
</source>
</syntaxhighlight>


Puis, dans notre fichier d'hôte <source lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</source>:
Puis, dans notre fichier d'hôte <syntaxhighlight lang="bash" inline>/opt/traefik/config/vhosts/ma_page.toml</syntaxhighlight>:


<source lang="yaml">
<syntaxhighlight lang="yaml">
[http]
[http]
   [http.routers]
   [http.routers]
Ligne 377 : Ligne 377 :
   certFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.crt"
   certFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.crt"
   keyFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.key"
   keyFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.key"
</source>
</syntaxhighlight>


=Supervision=
=Supervision=
''Traefik'' permet d'exporter ses métriques au format ''OpenMetrics'' afin d'être exploités par des outils de supervision tel que [[Prometheus]].
''Traefik'' permet d'exporter ses métriques au format ''OpenMetrics'' afin d'être exploités par des outils de supervision tel que [[Prometheus]].


Pour cela il faut ajouter les paramètres suivants à la fin du fichier <source lang="bash" inline>/opt/traefik/config/traefik.toml</source>:
Pour cela il faut ajouter les paramètres suivants à la fin du fichier <syntaxhighlight lang="bash" inline>/opt/traefik/config/traefik.toml</syntaxhighlight>:
<source lang="bash">
 
<syntaxhighlight lang="bash">
[metrics]
[metrics]
   [metrics.prometheus]
   [metrics.prometheus]
</source>
</syntaxhighlight>


{{attention| Relancer ''Traefik'' pour la prise en compte de la configuration.}}
{{attention| Relancer ''Traefik'' pour la prise en compte de la configuration.}}

Dernière version du 24 février 2023 à 21:05


Traefik est un logiciel permettant de faire un serveur mandataire inversé (reverse proxy) et pouvant faire de la répartition de charge (load balancer). Il est développé en Go et a la particularité de faire de la découverte automatique (toute les deux secondes par défaut) de fichiers de configurations (pas de redémarrage du service). Ceci a pour intérêt de permettre une actualisation du mandataire en agissant uniquement sur des fichiers et non le service lui-même. On peut alors imaginer une actualisation de la configuration du serveur par simple copier/coller de fichiers depuis un partage sans privilèges root par exemple.

ATTENTION

L'application Traefik évolue très rapidement. Le présent document traite de la version 2 de Traefik, les fichiers de configurations n'ont rien à voir.

Schéma fonctionnel

Traefik traite les requêtes des clients en les faisant passer dans divers fonctions selon le schéma suivant:

<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_logique_Traefik.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>

  • EntryPoint : Permet la déclaration des ports d'entrés de Traefik. Habituellement 80 et 443
  • Routers : Permet la déclaration de l'URL pour contacter le service
  • Middlewares : Permet la modification du comportement de l'appel. Ex: Ajout d'une authentification
  • Service : Permet la déclaration du serveur qui héberge le service


Installation

Traefik n'est pas présent dans les dépôts Debian Buster. Il va donc falloir le télécharger depuis son dépôt Git.

wget https://github.com/containous/traefik/releases/download/v2.2.1/traefik_v2.2.1_linux_amd64.tar.gz -P /tmp/
mkdir -p /opt/traefik/{config/vhosts,tls,passwd,logs}
tar xzvf /tmp/traefik_v2.2.1_linux_amd64.tar.gz -C /opt/traefik/

Création de l'utilisateur du service

useradd --system --home-dir /opt/traefik --user-group --shell /usr/sbin/nologin traefik
chown -R traefik:traefik /opt/traefik
chmod -R g+w /opt/traefik

Création du service Systemd

vim /etc/systemd/system/traefik.service
[Unit]
Description=Traefik, circulez y'a rien à voir !

[Service]
RestartSec=2s
Type=simple
User=traefik
Group=traefik
WorkingDirectory=/opt/traefik
ExecStart=/opt/traefik/traefik --configFile=/opt/traefik/config/traefik.toml
Restart=always
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Chargement du service au démarrage du système

systemctl daemon-reload
systemctl enable traefik.service
systemctl start traefik.service
systemctl status traefik.service

Configuration de base

Le fichier de configuration de Traefik est au format TOML, mais peux être également au format JSON. Il y a donc deux noms de fichier recommandés suivant le langage utilisé :

  • traefik.toml
  • traefik.yml

Ce fichier est attendu dans l'une de ces arborescences :

  • /etc/traefik/
  • $HOME/.config
  • . (Dans la même arborescence que le binaire)

Nous pouvons également définir à Traefik un fichier de configuration spécifique :

traefik --configFile=foo/bar/myconfigfile.toml

ATTENTION

Dans ce fichier, il est attendu une configuration statique. Une modification de celui-ci nécessitera une relance de Traefik pour qu'elles soient prisent en compte. Sont également concernés les fichiers étrangers aux différents hôtes virtuels comme par exemple middleware.toml et tls.toml que nous verrons plus bas. Seules les fichiers contenants les directives routers et services ne nécessites pas de redémarrage du service.

Voici un exemple:

vim /opt/traefik/config/traefik.toml
# Configuration globale de Traefik
[global]
  sendAnonymousUsage = false # Évite l'envoi d'informations à l'éditeur

# Configuration des journaux de Traefik
[log]
  level = "DEBUG" # Niveau de journalisation [DEBUG|PANIC|FATAL|ERROR|WARN|INFO]
  format = "common" # Format des journaux [common|json]
  filePath = "/opt/traefik/logs/traefik.log" # Chemin d'accès au fichier de journalisation

# Configuration des journaux d'accès
[accessLog]
  filePath = "/opt/traefik/logs/access.log" # Chemin d'accès au fichier de journalisation

# Configuration des fourniseurs
[providers]
  [providers.file] # Fournisseur de type "fichier"
    directory = "/opt/traefik/config/vhosts/" # Chemin d'accès du répertoire où sont stockés les fichiers des services
    watch = true # Permet le chargement à chaud des modifications de fichiers de configuration des hôtes virtuels

# Configuration de l'API
[api]
  dashboard = true # Permet d'activer le tableau de bord de Traefik
  debug = false # Permet de désactiver le mode développeur de l'API
  insecure = true # Permet d'activer l'accès à l'API via le port 8080 par défaut

# Configuration des points d'entrées de Traefik
[entryPoints]
  [entryPoints.http] # Permet de déclarer un point d'entrée nommé "http"
    address = ":80" # Permet de déclarer le port d'entrée

ATTENTION

Pour les filePath des sections [log] et [accessLog], il faudra prévoir une rotation du fichier journal (voir Logrotate) car Traefik ne gère pas cette fonction. Ceci est indispensable pour ne pas voir votre partition se remplir jusqu'à déni de service.

Comme nous avons édité le fichier de configuration principal du serveur, il faut recharger le service

systemctl restart traefik.service

Fonctionnalités

L'outil permet un éventail de fonctionnalités souvent rencontrées dans des logiciels de ce type. Elles sont décrites dans un ou plusieurs fichiers. Un hôte étant définit par des sections, il est possible d'en combiner plusieurs en un seul fichier ou d'en faire un par fichier. Ceci est configuré dans le paramètre directory de la directive [providers] vu précédemment. Comme précisé par le paramètre watch de cette même directive, ces fichiers sont appliqués au serveur à chaque enregistrements.

Parmi les fonctionnalités que nous avons explorées, nous pouvons noter la possibilité de faire:

  • un mandataire inverse HTTP/HTTPS
  • l'ajout d'une authentification HTTP
  • un répartiteur de charge


Afin de simplifier la compréhension des fichiers d'exemples qui suivront, nous allons partir du principe que nous voulons mettre à disposition de visiteurs sur Internet, un site WEB simple en HTML. Ce site est hébergé sur deux serveurs, ce qui nous permettra de configurer une répartition de charge. Nous le configurerons tout d'abord en HTTP, lui appliquerons une authentification, mettrons en place la répartition de charge et le passerons en HTTPS.

HTTP

Dans cette section, nous allons aborder la mise en place d'une redirection simple en HTTP comme on le ferrai avec Haproxy.

<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_http.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>

Nous allons créer un fichier représentant le nom du service:

vim /opt/traefik/config/vhosts/ma_page.toml
# Service de type http
[http]
  [http.routers] # Déclaration des routers
     [http.routers.vers_ma_page] # Création d'un routeur nommé "vers_ma_page"
      rule = "Host(`mapage.jmador.yo`)" # URL avec laquelle sera joint notre site web
      service = "ma_page" # Nom du service (déclaré ci-dessous)

  [http.services] # Déclaration des services
    [http.services.ma_page.loadBalancer] # Création d'un service nommé "ma_page"
      [[http.services.ma_page.loadBalancer.servers]] # Déclaration d'un serveur 
        url = "http://[2001:db8:0:180::a0]" # URL vers mon serveur MaPage

Vous pouvez noter le mot clé loadBalancer à la ligne créant le service ([http.services.ma_page.loadBalancer]). En fait, Traefik fait constament de la répartition de charge, même avec un seul hôte (ce qui revient à toujours envoyer les requêtes sur la même machine). La configuration d'une réelle répartition de charge consiste donc à ajouter un hôte, d'où la simplicité de mise en œuvre. Nous verrons ceci plus bas.

Il est également possible de faire des règles (paramètre rule) avec plus de conditions en utilisant des structures conditionnelles telles que || ou &&.

Authentification

Pour l’authentification, nous avons besoin d'un "middlewares" qui intercepte le lien pour demander un utilisateur et un mot de passe :

<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_http_auth.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>

Pour ce faire, nous allons créer un fichier htpasswd (utilitaire présent dans le paquet apache2-utils):

htpasswd -c /opt/traefik/passwd/groupe1 ycharbi

ATTENTION

Si vous voulez ajouter un utilisateur, utilisez la commande suivante : htpasswd /opt/traefik/passwd/groupe1 nmorin. L'usage du paramètre -c ne devant être utilisé que pour la création du fichier, sous peine de l'écraser. De plus, il faut impérativement relancer le service pour prendre en compte tout ajout/modification/suppression.

Un middleware est unique au sein de Traefik, bien qu'il soit possible de mettre la section dédiée directement dans l'hôte concerné, il est plus judicieux de leur créer un fichier propre afin de pouvoir piocher dedans les groupes d'utilisateurs pour les authentifications:

vim /opt/traefik/config/vhosts/middlewares.toml
# Service de type http
[http]
  [http.middlewares] # Déclaration des middlewares
    [http.middlewares.mon_auth.basicAuth] # Création d'un middleware nommé "mon_auth" de type "basicAuth"
      usersFile = "/opt/traefik/passwd/groupe1" # Définit l'arborescence du fichier htpasswd

Puis nous allons reprendre le fichier /opt/traefik/config/vhosts/ma_page.toml:

[http]
  [http.routers]
     [http.routers.vers_ma_page]
      rule = "Host(`mapage.jmador.yo`)"
      service = "ma_page"
      middlewares = ["mon_auth"] # Définit les middlewares utilisés pour ce routeur

  [http.services]
    [http.services.ma_page.loadBalancer]
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a0]"

Répartition de charges

Nous allons voir la configuration de la répartition de charge. Plusieurs serveurs pourront êtres utilisés pour répondre de façon alternés aux clients. Attention, nous n'aborderons pas ici la notion de gestion de faillite (failover). Un serveur injoignable sera quand même utilisé dans la répartition et renvéra des erreurs aux clients.

<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_http_auth_rep.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>

L'ajout d'un serveur dans le système de répartition de charge est très simple. Il faut seulement déclarer un autre serveur dans le service. La répartition de charge utilise l'algorithme d'ordonnancement Round-robin.

Reprenons notre fichier /opt/traefik/config/vhosts/ma_page.toml :

[http]
  [http.routers]
     [http.routers.vers_ma_page]
      rule = "Host(`mapage.jmador.yo`)"
      service = "ma_page"
      middlewares = ["mon_auth"]

  [http.services]
    [http.services.ma_page.loadBalancer]
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a0]"
      [[http.services.ma_page.loadBalancer.servers]] # Déclaration d'un autre serveur 
        url = "http://[2001:db8:0:180::a1]" # URL vers mon serveur 2 MaPage

Avec persistance de sessions

Traefik nous offre la possibilité de gérer la persistance de sessions sur un serveur de manière très simple. Il faut simplement ajouter la valeur .sticky.cookie lors de la déclaration de notre service.

INFORMATION

La persistance de sessions permet d'allouer un client au premier serveur que le Round-robin lui aura fait joindre. La technique s'appuie sur la génération et l'envoi d'un cookie au navigateur du client (cela ne fonctionne donc pas avec curl ou wget). Celui-ci présente ce cookie au serveur mandataire qui retransmet sa requête au même serveur qu'au premier échange.

Toujours dans notre fichier /opt/traefik/config/vhosts/ma_page.toml:

# Service de type http
[http]
  [http.routers]
     [http.routers.vers_ma_page]
      rule = "Host(`mapage.jmador.yo`)"
      service = "ma_page"
      middlewares = ["mon_auth"]

  [http.services]
    [http.services.ma_page.loadBalancer.sticky.cookie] # Création d'un service nommé "ma_page" avec gestion des cookies de session
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a0]"
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a1]"

HTTPS

Dans cette section nous ajouterons le support de TLS pour faire du HTTPS. Vous trouverez la documenation officielle sur le sujet ici ainsi que l'ensemble des suites cryptographiques configurables pour le chiffrement du flux et les algorithmes d'échange de clés basés sur les courbes ellyptiques (la syntaxes des algorithmes de la RFC 8446 est utilisable dans la configuration).

Simple

Le support de HTTPS se ferra en cohabitation avec HTTP. Les clients pourrons se connecter soit en clair, soit en chiffré.

<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_https_auth_rep.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>

Comme vous pouvez le voir dans le schéma ci-dessus, nous avons un nouveau point d'entrée sur le port 443. Il faut donc l'ajouter dans la configuration de base de Traefik.

vim /opt/traefik/config/traefik.toml
[global]
  sendAnonymousUsage = false

# Configuration des journaux de Traefik
[log]
  level = "DEBUG"
  format = "common"
  filePath = "/opt/traefik/logs/traefik.log"

[accessLog]
  filePath = "/opt/traefik/logs/access.log"

[providers]
  [providers.file]
    directory = "/opt/traefik/config/vhosts/"
    watch = true

[api]
  dashboard = true
  debug = false
  insecure = true

[entryPoints]
  [entryPoints.http]
    address = ":80"
  [entryPoints.https] # Permet de déclarer un autre point d'entrée nommé "https"
    address = ":443" # Permet de déclarer le port d'entrée 443

Nous allons ajouter un nouveau fichier pour définir les propriétés pas défaut de notre TLS:

vim /opt/traefik/config/vhosts/tls.toml
[tls.options]
  [tls.options.default]
    # Définition des suites cryptographiques accéptés par le serveur
    cipherSuites = [ 
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
    ]
    curvePreferences = ["x25519", "CurveP521", "CurveP384"] # Définition des algorithmes d'échanges de clés accéptés par le serveur
    preferServerCipherSuites = true # Imposer l'utilisation des suites cryptographiques définies par le serveur

Note: Il est à précisé que GoLang ne permet pas de configurer de suites cryptographiques pour le TLS 1.3. Les développeurs du langage se justifient par le fait qu'elles sont définits dans la RFC 8446, respectés à la lettres et concidérées comme sûr donc y'a pas de problèmes... Personellement je trouve ça moyen surtout quand l'AES 128 bits est le choix par défaut... Ce n'est peut-être que temporaire, l'ajout de ce protocole datant de la version 1.12 du langage Go (on en est à la 1.13 au moment de la rédaction de ce paragraphe).

ATTENTION

N'oubliez pas que comme nous avons modifié le fichier de configuration principal ainsi qu'un fichier autre qu'un routeur ou un service, il faut relancer Traefik pour que la prise en compte de la configuration soit effective.

Dans le fichier /opt/traefik/config/vhosts/ma_page.toml :

[http]
  [http.routers]
     [http.routers.vers_ma_page]
      entryPoints = ["https"] # On force l'accès via le point d'entrée "https"
      rule = "Host(`mapage.jmador.yo`)"
      service = "ma_page"
      middlewares = ["mon_auth"]
      [http.routers.vers_ma_page.tls] # On autorise les connexion "TLS"

  [http.services]
    [http.services.ma_page.loadBalancer.sticky.cookie]
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a0]"
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a1]"

[[tls.certificates]]
  certFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.crt" # Chemin d'accès au certificat
  keyFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.key" # Chemin d'accès à la clé du certificat

Note: la génération des certificats est expliquée dans la documentation concernant OpenSSL. Prenez garde aux permissions de vos certificats. L'utilisateur "traefik" doit en être le propriétaire.

Avec redirection de HTTP vers HTTPS

Le support d'HTTPS sera obligatoire, toute connexion en HTTP redirigera automatiquement le client en HTTPS.

<img src="https://doc.ycharbi.fr/fichiers/services/mandataire/traefik/images/Schéma_exemple_Traefik_redirect_https_auth_rep.svg" alt="Schéma logique Traefik" style="display: block; width: 60%; height:auto; margin-left:auto; margin-right:auto;"/>

Comme nous pouvons le voir sur le schéma ci-dessus, il faut que l'on déclare un nouveau middlewares.

Reprenons notre fichier /opt/traefik/config/vhosts/middlewares.toml:

[http]
  [http.middlewares]
    [http.middlewares.mon_auth.basicAuth]
      usersFile = "/opt/traefik/passwd/groupe1"
    [http.middlewares.redirection_https.redirectScheme] # Création d'un middleware nommé "redirection_https" de type "redirectScheme"
      scheme = "https" # Redirection vers https
      permanent = true # Permet l'envoie d'un code HTTP 301

Puis, dans notre fichier d'hôte /opt/traefik/config/vhosts/ma_page.toml:

[http]
  [http.routers]
     [http.routers.vers_ma_page_http] # Création d'un routeur nommé "vers_ma_page_http"
      entryPoints = ["http"] # On force l'accès via le point d'entrée "http"
      rule = "Host(`mapage.jmador.yo`)" # URL avec laquelle sera joint notre site web
      service = "ma_page" # Nom du service (même si on y va pas)
      middlewares = ["redirection_https"] # Définit les middlewares utilisés pour ce routeur

     [http.routers.vers_ma_page_https] # Création d'un routeur nommé "vers_ma_page_https"
      entryPoints = ["https"]
      rule = "Host(`mapage.jmador.yo`)"
      service = "ma_page"
      middlewares = ["mon_auth"]
      [http.routers.vers_ma_page_https.tls]

  [http.services]
    [http.services.ma_page.loadBalancer.sticky.cookie]
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a0]"
      [[http.services.ma_page.loadBalancer.servers]]
        url = "http://[2001:db8:0:180::a1]"

[[tls.certificates]]
  certFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.crt"
  keyFile = "/opt/traefik/tls/mapage.jmador.yo/mapage.jmador.yo.key"

Supervision

Traefik permet d'exporter ses métriques au format OpenMetrics afin d'être exploités par des outils de supervision tel que Prometheus.

Pour cela il faut ajouter les paramètres suivants à la fin du fichier /opt/traefik/config/traefik.toml:

[metrics]
  [metrics.prometheus]

ATTENTION

Relancer Traefik pour la prise en compte de la configuration.

Sources