Installer Traefik sur Ubuntu

Installer Traefik sur Ubuntu

Dans ce tutoriel nous verrons comment installer Traefik. Traefik est un reverse proxy qui va vous permettre de rendre accessible plusieurs services sur votre VPS. Traefik va vous permettre de router vos flux tcp/http/udp vers vos services préférés. Il facilite la configuration avec des providers dynamiques et il facilite la mise en place de https avec Let’s Encrypt.

C’est quoi au fait un reverse proxy ?

Un proxy inverse (reverse proxy) fait apparaître différents serveurs et services comme s’ils étaient une seule unité. Il vous permet de masquer la présence de plusieurs serveurs distincts derrière le même nom. Habituellement placé en frontal de serveurs web. Contrairement au serveur proxy qui permet à un utilisateur d’accéder au réseau Internet, le reverse proxy permet à un utilisateur d’Internet d’accéder à des serveurs internes. Une des applications courantes du reverse proxy est la répartition de charge (load-balancing).

Un proxy inverse (reverse proxy) fait apparaître différents serveurs et services comme s'ils étaient une seule unité.

Dans ce tutoriel, nous nous attarderons sur le reverse proxy Traefik. Ce logiciel est écrit en Go et est Français Monsieur.

Traefik nous permettra de :

  • Recharger à chaud des configurations:
  • Supporte plusieurs algorithmes de load-balancing (équilibrage de charge)
  • Intégration native de Let’s Encrypt pour fournir du HTTPS aux différents services.
  • Interface web pour contrôler la configuration et mise à disposition d’une API Rest.
  • Fournit des métriques (Rest, Prometheus, Datadog, Statsd, InfluxDB) et des logs d’accès (JSON, CLF).
  • Go oblige, il est fourni sous un binaire unique (ou via une image Docker relativement petite).
  • Supporte l’ajout de plugins écrits en Go via un Marketplace

Installation de Docker Engine

Avant d’utiliser Traefik, il faut d’abord installer plusieurs briques comme Docker.

Avant d’installer Docker Engine pour la première fois sur une nouvelle machine hôte, vous devez configurer le référentiel Docker (dépôt). Par la suite, vous pouvez installer et mettre à jour Docker à partir de ce référentiel.

sudo apt-get update
sudo apt-get install\
ca-certificates\
curl\
gnupg\
lsb-release

Avant d’utiliser Traefik, il faut d’abord installer plusieurs briques comme Docker.

Ajoutez la clé GPG officielle de Docker :

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Utilisez la commande suivante pour configurer le référentiel stable. Pour ajouter le dépôt nightly ou test, ajoutez le mot nightly ou test (ou les deux) après le mot stable dans les commandes ci-dessous :

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Utilisez la commande suivante pour configurer le référentiel stable.

Mettez à jour l’index des paquets apt, et installez la dernière version de Docker Engine et de containerd.

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Mettez à jour l'index des paquets apt, et installez la dernière version de Docker Engine et de containerd.

Pour vérifier que Docker soit bien installé sur votre serveur Linux, vous pouvez taper la commande ci-dessous qui affichera la version de Docker :

docker -v

Pour vérifier que Docker soit bien installé sur votre serveur Linux, vous pouvez taper la commande : docker -v

Le moteur Docker est installé et fonctionne. Le groupe docker est créé mais aucun utilisateur n’y est ajouté. Vous devez utiliser sudo pour exécuter les commandes Docker.

Vérifiez que Docker Engine est correctement initialisé en exécutant l’image hello-world.  Cette commande télécharge une image de test et l’exécute dans un conteneur. Lorsque le conteneur s’exécute, il affiche un message et quitte.

sudo docker run hello-world

Vérifiez que Docker Engine est correctement initialisé en exécutant l'image hello-world. 

Installer Docker-Compose

Compose est un outil permettant de définir et d’exécuter des applications Docker multi-conteneurs. Avec Compose, vous utilisez un fichier YAML pour configurer les services de votre application. Ensuite, avec une seule commande, vous créez et démarrez tous les services à partir de votre configuration.

Sous Linux, vous pouvez télécharger le binaire Docker Compose depuis la page de publication du dépôt Compose sur GitHub. Suivez les instructions ci-dessous, qui impliquent l’exécution de la commande curl dans votre terminal pour télécharger les binaires.

Exécutez cette commande pour télécharger la dernière version stable de Docker Compose (a l’écriture de ce tutoriel, la dernière version était V2.5.1) :

curl -SL https://github.com/docker/compose/releases/download/v2.5.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

Compose est un outil permettant de définir et d'exécuter des applications Docker multi-conteneurs.

Appliquer les droits d’exécution au binaire.

sudo chmod +x /usr/local/bin/docker-compose

Testez  votre installation.

docker-compose --version

utiliser la commande suivante : docker-compose --version, pour vérifier si docker-compose est bien installé

Installer Traefik

Tout d’abord, créez un répertoire pour les conteneurs.

mkdir -p /opt/containers/{traefik,portainer}

créez un répertoire pour les conteneurs.

Je vous rappelle que le répertoire /opt est un répertoire pour l’installation de packages non groupés (c’est-à-dire que les packages ne font pas partie de la distribution du système d’exploitation, mais fournis par une source indépendante), chacun dans son propre sous-répertoire. Ils constituent déjà des packages complets fournis par un distributeur de logiciels tiers indépendant.

Créer le dossier de données et les fichiers de configuration pour Traefik :

mkdir -p /opt/containers/traefik/data
touch /opt/containers/traefik/data/acme.json
chmod 600 /opt/containers/traefik/data/acme.json
touch /opt/containers/traefik/data/traefik.yml
  • Le fichier acme.json permet de stocker les certificats Let’s Encrypt
  • Le fichier traefik.yml contient les paramètres de configuration du logiciel Traefik au format YML. Dans ce format il faut respecter l’indentation des paramètres. La séparation doit être faite par des espaces et non avec la touche tabulation.

Créer le fichier de configuration de base de Traefik (attention à l’indentation). Voici un exemple que vous pouvez prendre et modifier à votre guise en fonction de vos contraintes avec gestion des certificats HTTPS via Let’s Encrypt.

Créer le fichier de configuration de base de Traefik (attention à l’indentation). Voici un exemple que vous pouvez prendre et modifier à votre guise en fonction de vos contraintes avec gestion des certificats HTTPS via Let's Encrypt.   

Les entryPoints, sont les points d’écoute de Traefik qui font partie de la static configuration  :

  • Ports et adresses : [host]:port/tcp | /udp
  • Redirection
  • Forwarding IP
  • Let’s Encrypt

On déclare dans le fichier de configuration de Traefik les entrypoint (ports d’écoutes) et ensuite on les référencent dans le fichier docker-compose.

Les providers sont des fournisseurs d’informations (registre de services) comme Docker, Kubernetes, Consul, …

CertificatResolvers

Le protocole ACME (de l’anglais Automatic Certificate Management Environment, littéralement « environnement de gestion automatique de certificat ») est un protocole de communication pour l’automatisation des échanges entre les autorités de certification et les propriétaires de serveur web. Il a été conçu par l’Internet Security Research Group pour leur service Let’s Encrypt.

Configuration de Traefik

Voici toutes les étapes pour configurer Traefik et commencer à déployer des containers Docker :

Créer un réseau Traefik qui sera partagé entre tous les conteneurs de nos applications.

docker network create proxy

Créer un réseau Traefik qui sera partagé entre tous les conteneurs de nos applications.

Générer les informations d’authentification pour se connecter à Traefik

sudo apt-get install apache2-utils
echo $(htpasswd -nbB yourUserName yourPassword) | sed -e s/\$/\$\$/g

Générer les informations d'authentification pour se connecter à Traefik

Créer le fichier docker-compose de Traefik  en remplaçant USER:PASSWORD par les valeurs utilisées ci-dessus.

Le fichier docker compose, doit être créé dans ce répertoire : /opt/containers/traefik/docker-compose.yml

Le fichier docker compose, doit être créé dans ce répertoire : /opt/containers/traefik/docker-compose.yml

Si, pour une raison ou une autre, notre serveur doit redémarrer, l’argument restart: always nous permettra d’avoir notre service reverse-proxy qui se relancera automatiquement tout seul.

Dans la partie ports nous rendons accessibles nos ports du service reverse-proxy à l’extérieur de celui-ci. Dans la partie volumes nous partageons des fichiers et/ou des répertoires avec notre service.

Démarrer Traefik avec la commande ci-dessous :

cd /opt/containers/traefik
docker-compose up -d

Démarrer Traefik avec la commande docker-compose up -d

Pour arrêter le container Traefik avec docker compose, il suffit d’utiliser la commande :

docker-compose down

Au lancement du container, si vous souhaitez voir les logs pour faire du debugging ou pour vérifier que tout fonctionne correctement, vous pouvez utiliser la commande suivante après le docker-compose up -d :

docker-compose logs -f

si vous souhaitez voir les logs pour faire du debugging ou pour vérifier que tout fonctionne correctement, vous pouvez utiliser la commande suivante : docker-compose logs -f

On voit clairement ici que le challenge Let’s Encrypt ne fonctionne pas, car je me suis trompé  dans l’adresse mail dans un fichier de configuration.

Une fois  les modifications apportées, vous arriverez sur le Dashboard de Traefik en HTTPS.

Dashboard de Traefik en HTTPS

Installer Portainer

Pour rappel Portainer est une interface web pour la gestion des containers.

Créer le fichier portainer docker-compose, qui doit se trouver dans /opt/containers/portainer/docker-compose.yml.

Fichier docker-compose de Portainer

Démarrer portainer avec les commandes suivantes :

cd /opt/containers/portainer
docker-compose up -d
docker-compose logs -f

Lancement de Portainer via les commandes docker-compose

Vous pouvez maintenant vous connectez à l’interface web de Portainer. Si vous souhaitez plus de détail dans l’utilisation de Portainer vous pouvez consulter ce tutoriel : Gérer vos containers avec Portainer.

Interface de gestion des containers avec Portainer

Mettre à jour Portainer

L’avantage de docker, c’est que les mises à jour sont simplifiés et rapides. Pour mettre à jour votre container Portainer, il suffit d’indiquer dans le fichier docker-compose.yml la dernière version du container en question.

L’avantage de docker, c’est que les mises à jour sont simplifiés et rapides. Pour mettre à jour votre container Portainer, il suffit d’indiquer dans le fichier docker-compose.yml la dernière version du container en question.

A la date de ce tutoriel, la dernière version disponible est la 2.11.0. Je vous conseille aussi de regarder sur Docker-Hub si l’image que vous utilisez a été mise à jour. Je vous conseille aussi vivement d’utiliser des images officielles pour éviter de nombreuses déconvenues. Si vous souhaitez avoir toujours les dernières versions vous pouvez utiliser le mot clé latest.

Puis après avoir modifier votre fichier docker-compose.yml, utiliser les commandes ci-dessous pour mettre à jour le container.(cela aura pour effet de télécharger la nouvelle image et de l’utiliser au prochain reboot de l’application)

docker-compose down
docker-compose up -d

utiliser les commandes ci-dessous pour mettre à jour le container : docker-compose down suivi de docker-compose up

Ensuite connectez-vous sur Portainer et aller dans Images. Vous devez avoir une ligne avec  unused. Vous devez supprimer l’ancienne image de Portainer pour vous faire gagner de la place.

Sur Portainer, aller dans Images. Vous devez avoir une ligne avec  unused. Vous devez supprimer l’ancienne image de Portainer pour vous faire gagner de la place.

Traefik et les labels

La particularité de Traefik, grâce à son intégration avec Docker, est qu’il a besoin d’accéder à /var/run/docker.sock. Cela lui permet, lorsqu’on rajoute ou retire un service de modifier sa configuration à chaud notamment avec les nombreux labels à spécifier.

Voici ma configuration de base que j’applique à chaque container. Bien entendu, n’étant pas spécialiste de Traefik vous pouvez m’aider à optimiser, sécuriser cette configuration de base. D’avance merci !!!!

  • traefik.enable=true: Expose les conteneurs par défaut à travers Traefik. S’il est défini à false, les conteneurs qui n’ont pas l’étiquette traefik.enable=true sont ignorés de la configuration de routage de Traefik.
  • traefik.http.routers.<nom-label>.entrypoints=http: Si cette option n’est pas spécifiée, les routeurs HTTP accepteront les demandes provenant de tous les points d’entrée définis. Si vous souhaitez limiter la portée du routeur à un ensemble de points d’entrée, définissez l’option entryPoints. Cela peut-être les ports 80 (HTTP), 443 (HTTPS), un port spécifique 1704/udp, une liste d’adresse ip spécifique, ….
  • traefik.http.routers.<nom-label>.rule=Host(‘<nom-de-donaime>’): Les règles sont un ensemble de « matchers » configurés avec des valeurs, qui déterminent si une demande particulière correspond à des critères spécifiques. Si la règle est vérifiée, le routeur devient actif, appelle les middlewares, puis transmet la demande au service. On peut combiner plusieurs critères comme, rule = « Host( example.com ) || (Host( example.org ) && Path( /traefik )) ».

Voici une liste de rule applicable :

Liste de rule applicable dans Traefik

  • traefik.http.middlewares.<nom-label-https-redirect>.redirectscheme.scheme=https: Attachés aux routeurs, les middleware sont un moyen de modifier les requêtes avant qu’elles ne soient envoyées à votre service (ou avant que les réponses des services ne soient envoyées aux clients). Il y a plusieurs middlewares disponibles dans Traefik, certains peuvent modifier la requête, les en-têtes, certains sont en charge des redirections, certains ajoutent l’authentification, et ainsi de suite. Les middlewares qui utilisent le même protocole peuvent être combinés en chaînes pour s’adapter à chaque scénario.

Middlewares HTTP disponibles :

Liste de Middlewares HTTP disponible dans Traefik

 

  • traefik.docker.network=traefik-frontend: pour que le conteneur soit sur le réseau frontend utilisé par Traefik ou un autre réseau définit au moment de l’installation.
  • traefik.http.routers.traefik.entrypoints=websecure: chaque routeur nécessite la configuration d’un entrypoint, on spécifie celui sur le port 443.
  • traefik.http.routers.traefik.tls=true: pour activer le TLS pour ce routeur.
  • traefik.http.routers.portainer.rule=Host( portainerdomain.local ): on choisit l’URL pour accéder au service.
  • traefik.http.services.portainer.loadbalancer.server.port=9000: on indique le port pour accéder au service.
  • traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https: déclaration d’un middlerware pour une redirection auto vers https

Traefik : Activer les access logs

Traefik utilise pour la création de ses logs, le format standardisé Common Log Format ( CLF ). C’est un format standard, les fichiers peuvent être facilement analysés par divers outils d’analyses de logs comme Webalizer ou bien encore Analog.

Par défaut dans la configuration statique de Traefik, les logs ne sont pas activés.

Voici comment activer les logs dans le fichier de configuration traefik.yml (/opt/containers/traefik/data/) :

Traefik : Activer les access logs

Sécuriser Traefik et ses containers

Si vous souhaitez sécuriser l’accès à vos containers, ou avoir une bonne note au test SSL Labs (https://www.ssllabs.com/ssltest/) et Securityheaders (https://securityheaders.com/), voici quelques conseils.

Pour obtenir un A ou A+ sur let’s Encrypt et SecurityHeader il faut modifier les headers avec les options suivantes en créant 1 fichier pour les options de TLS et un autre pour les HEADERS.

Pour obtenir un A ou A+ sur let's Encrypt et SecurityHeader il faut modifier les headers avec les options suivantes en créant 1 fichier pour les options de TLS et un autre pour les HEADERS.

Dans le répertoire de traefik dans /data/ j’ai créé un répertoire config avec 2 fichier :

  • middleware_conf.yaml (permet de gérer entre autre les headers et d’autres paramètres de sécurité, comme la limite de connexion, les WhiteList, …)
  • tls_conf.yaml (permet de gérer finement le paramétrage TLS)

Voici la configuration du fichier middleware_conf.yaml :

Permet de gérer entre autre les headers et d’autres paramètres de sécurité, comme la limite de connexion, les WhiteList, ...

  • Définissez contentTypeNosniff sur true pour ajouter l’en-tête X-Content-Type-Options avec la valeur nosniff. (C’est un marqueur utilisé par le serveur pour indiquer que les types MIME annoncés dans les en-têtes Content-Type ne doivent pas être modifiés ou et suivis. Cela permet de se détacher du sniffing de type MIME)
  • Définissez browserXssFilter sur true pour ajouter l’en-tête X-XSS-Protection avec la valeur 1 ; mode=block. (L’en-tête X-XSS-Protection permet d’activer la protection contre les attaques XSS incluse dans les navigateurs Internet compatibles (IE, Chrome, Safari…).  Cette en-tête peut prendre 4 valeurs différentes : 0 : le filtrage XSS est désactivé, 1 : le filtrage XSS est activé et le navigateur essaie de nettoyer le code, si besoin, 1; mode=block : le filtrage est activé et le navigateur bloque le rendu de la page si une tentative d’attaque de type XSS est détectée, 1; report=<reporting-URI> : le filtrage XSS est activé et le navigateur nettoie le code, si besoin, et envoie un rapport à l’adresse définie. Il faut bien comprendre que l’en-tête X-XSS-Protection n’est pas LA solution ultime et que l’implémenter ne vous mettra pas totalement à l’abri des attaques de type Cross-Site Scripting. Mais cela constitue un petit plus dont il serait dommage de se priver )
  • Définissez forceSTSHeader à true, pour ajouter l’en-tête STS même lorsque la connexion est HTTP. (permet de garantir que, lors de la session, tous les liens utiliseront HTTPS)
  • Le paramètre stsSeconds est l’âge maximal de l’en-tête Strict-Transport-Security. S’il est défini à 0, il n’inclura PAS l’en-tête.
  • Si stsIncludeSubdomains a la valeur true, la directive includeSubDomains sera ajoutée à l’en-tête Strict-Transport-Security. (Avec la directive includeSubDomains, cela permet de protéger l’intégralité des sous-domaines.)
  • Définissez stsPreload sur true pour que l’indicateur de préchargement soit ajouté à l’en-tête Strict-Transport-Security. (Le protocole HSTS permet de garantir que, lors de la session, tous les liens utiliseront HTTPS. L’idée ici est de faire inscrire son domaine sur un liste internationale utilisée par les navigateurs internet. Ainsi, les navigateurs savent qu’ils devront utiliser HTTPS dès le début de la session. Pour tester son éligibilité et demander son enregistrement sur la liste HSTS preloading, visiter le site HSTS Preload (https://hstspreload.org/)
  • Le paramètre accessControlMaxAge indique la durée (en seconde) pendant laquelle une demande de contrôle en amont peut être mise en cache.
  • Le paramètre sslRedirect n’autorise que les requêtes HTTPS lorsqu’il est défini à true.
  • Le paramètre sslForceHost permet de forcer les demandes à utiliser SSLHost, qu’elles utilisent déjà SSL ou non.
  • Le paramètre contentSecurityPolicy, ce header permet de restreindre l’origine des scripts exécutés par vos pages aux sites que vous autorisez.
  • Le paramètre referrerPolicy permet aux sites de contrôler quand les navigateurs transmettent l’en-tête Referer à d’autres sites.
  • Le paramètre frameDeny , l’en-tête de réponse HTTP X-Frame-Options peut être utilisé afin d’indiquer si un navigateur devrait être autorisé à afficher une page au sein d’un élément <frame> , <iframe> , <embed> ou <object> . Les sites peuvent utiliser cet en-tête afin d’éviter les attaques de clickjacking (ou « détournement de clic ») pour s’assurer que leur contenu ne soit pas embarqué dans d’autres site
  • Le paramètre customResponseHeaders permet de gérer la politique de permissions d’accès aux fonctionnalités du navigateur (caméra, notifications, ..).

Maintenant nous allons configurer les options TLS pour restreindre les chiffrements (cipher) acceptés.

Voici la configuration du fichier tls_conf.yaml :

configurer les options TLS pour restreindre les chiffrements (cipher) acceptés.

Avec cette configuration je choisi de ne pas supporter en dessous du TLS 1.2 et seulement certains ciphers et curves. De plus j’ai indiqué d’utiliser exclusivement mes certificats en mode SNI (Server Name Indication https://fr.wikipedia.org/wiki/Server_Name_Indication). Il est a noter que cette configuration est assez stricte et ne permet pas aux navigateurs et/ou OS anciens et obsolètes de se connecter.

Ensuite il faut indiquer à Traefik d’utiliser les fichiers de configuration ci-dessus. Voici les lignes à rajouter dans le fichier traefik.yml.

Il faut indiquer à Traefik d’utiliser les fichiers de configuration ci-dessus. Voici les lignes à rajouter dans le fichier traefik.yml.

Astuce 1 : Le paramètre Watch permet de prendre en compte les modifications dans les fichiers du répertoire /config/ sans relancer le service Traefik.

Enfin il faut appliquer ces politiques à chacun de vos containers que vous souhaitez sécuriser. Voici un exemple.

Il faut appliquer ces politiques à chacun de vos containers que vous souhaitez sécuriser.

N’oublier pas d’appeler pour chaque entrypoint 80 et 443 la sécurisation, grâce à ces lignes :

  • traefik.http.routers.psitransfer.middlewares=SecHeader@file
  • traefik.http.routers.psitransfer-secure.middlewares=SecHeader@file

Les options de sécurisation du TLS ne s’applique (forcément) que sur l’entrypoint 443 donc Secure :

  • traefik.http.routers.psitransfer-secure.tls.options=hardening@file

Maintenant pour être sûre de votre configuration, vous pouvez  tester votre URL sur les sites ci-dessous :

Test SSLLABS :

Test SSLLABS

Test SECURITYHEADERS :

Test SECURITYHEADERS

Obtenir une licence Portainer Business Edition gratuite

Portainer vous permet d’avoir une offre d’essai, sans limite de durée, où la Business Edition est gratuite jusqu’à 3 nœuds (c’est-à-dire 3 machines/installations). Ceci est largement suffisant à mon avis si vous utilisez un serveur pour la maison en plus de votre VPS par exemple.

Obtenir une licence Portainer Business Edition gratuite

Vous devez vous rendre sur ce lien : Portainer Business Edition gratuite et renseignez les informations pour recevoir votre licence. Dans l’usage que vous faites de Portainer vous pouvez sélectionner « Home ».

Vous allez recevoir 2 emails : un premier expliquant comment faire la mise à jour et un second avec votre licence.

Pour activer votre licence, vous devez changer de version de Portainer, pour passer de Portainer-ce à Portainer-ee. Il faudra donc modifier votre fichier docker-compose et rajouter cette ligne au niveau de l’image de votre container.

image: portainer/portainer-ee:latest

Après le redémarrage de votre container, vous aurez ceci :

Obtenir une licence Portainer Business Edition gratuite

Vous pouvez maintenant profiter de toutes les fonctionnalités de Portainer Business Edition.

Signature manuelle Guillaume

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *