Comment sécuriser HAProxy avec Let's Encrypt sur CentOS 7

De Get Docs
Aller à :navigation, rechercher

Introduction

Let's Encrypt est une nouvelle autorité de certification (CA) qui fournit un moyen simple d'obtenir et d'installer des certificats TLS/SSL gratuits, permettant ainsi le chiffrement HTTPS sur les serveurs Web. Il simplifie le processus en fournissant un client logiciel, Certbot, qui tente d'automatiser la plupart des étapes requises. Actuellement, l'ensemble du processus d'obtention et d'installation d'un certificat est entièrement automatisé uniquement sur les serveurs Web Apache. Cependant, Certbot peut être utilisé pour obtenir facilement un certificat SSL gratuit, qui peut être installé manuellement, quel que soit votre choix de logiciel de serveur Web.

Dans ce tutoriel, nous allons vous montrer comment utiliser Let's Encrypt pour obtenir un certificat SSL gratuit et l'utiliser avec HAProxy sur CentOS 7. Nous vous montrerons également comment renouveler automatiquement votre certificat SSL.

Conditions préalables

Avant de suivre ce tutoriel, vous aurez besoin de quelques éléments.

Vous devez avoir un serveur CentOS 7 avec un utilisateur non root disposant des privilèges sudo. Vous pouvez apprendre à configurer un tel compte d'utilisateur en suivant les étapes 1 à 3 de notre tutoriel configuration initiale du serveur pour CentOS 7.

Vous devez posséder ou contrôler le nom de domaine enregistré avec lequel vous souhaitez utiliser le certificat. Si vous n'avez pas encore de nom de domaine enregistré, vous pouvez en enregistrer un auprès de l'un des nombreux bureaux d'enregistrement de noms de domaine (par exemple Namecheap, GoDaddy, etc.).

Si vous ne l'avez pas déjà fait, assurez-vous de créer un A Record qui pointe votre domaine vers l'adresse IP publique de votre serveur. Ceci est nécessaire en raison de la façon dont Let's Encrypt valide que vous possédez le domaine pour lequel il émet un certificat. Par exemple, si vous souhaitez obtenir un certificat pour example.com, ce domaine doit être résolu sur votre serveur pour que le processus de validation fonctionne. Notre configuration utilisera example.com et www.example.com comme noms de domaine, donc les deux enregistrements DNS sont requis.

Une fois que vous avez réglé toutes les conditions préalables, passons à l'installation de Certbot, le logiciel client Let's Encrypt.

Étape 1 - Installation de Certbot, le client Let's Encrypt

La première étape pour utiliser Let's Encrypt pour obtenir un certificat SSL est d'installer le logiciel certbot sur votre serveur. Actuellement, la meilleure façon de l'installer est via le référentiel EPEL.

Activez l'accès au référentiel EPEL sur votre serveur en saisissant :

sudo yum install epel-release

Une fois le référentiel activé, vous pouvez obtenir le package certbot en tapant :

sudo yum install certbot

Le client certbot Let's Encrypt devrait maintenant être installé et prêt à être utilisé.

Étape 2 — Obtention d'un certificat

Let's Encrypt fournit une variété de façons d'obtenir des certificats SSL, via divers plugins. Contrairement au plugin Apache, qui est couvert dans un tutoriel différent, la plupart des plugins ne vous aideront qu'à obtenir un certificat que vous devez configurer manuellement votre serveur Web à utiliser. Les plugins qui obtiennent uniquement des certificats, et ne les installent pas, sont appelés « authentificateurs » car ils sont utilisés pour authentifier si un serveur doit recevoir un certificat.

Nous allons vous montrer comment utiliser le plugin Standalone pour obtenir un certificat SSL.

Vérifiez que le port 80 est ouvert

Le plugin autonome fournit un moyen très simple d'obtenir des certificats SSL. Il fonctionne en exécutant temporairement un petit serveur Web, sur le port 80, sur votre serveur, auquel l'autorité de certification Let's Encrypt peut se connecter et valider l'identité de votre serveur avant d'émettre un certificat. En tant que telle, cette méthode nécessite que le port 80 ne soit pas utilisé. Autrement dit, assurez-vous d'arrêter votre serveur Web normal, s'il utilise le port 80 (c'est-à-dire http), avant d'essayer d'utiliser ce plugin.

Par exemple, si vous utilisez HAProxy, vous pouvez l'arrêter en exécutant cette commande :

sudo systemctl stop haproxy

Si vous ne savez pas si le port 80 est utilisé, vous pouvez exécuter cette commande :

netstat -na | grep ':80.*LISTEN'

S'il n'y a pas de sortie lorsque vous exécutez cette commande, vous pouvez utiliser le plug-in autonome.

Exécuter Certbot

Utilisez maintenant le plug-in Standalone en exécutant cette commande :

sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d example.com -d www.example.com

Vous serez invité à saisir votre adresse e-mail et à accepter les conditions d'utilisation de Let's Encrypt. Ensuite, le défi http se déroulera. Si tout est réussi, certbot imprimera un message de sortie comme celui-ci :

Output:IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2017-09-06. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Vous voudrez noter le chemin et la date d'expiration de votre certificat, qui ont été mis en évidence dans l'exemple de sortie ci-dessus.

Remarque : Si votre domaine route via un service DNS tel que CloudFlare, vous devrez le désactiver temporairement jusqu'à ce que vous ayez obtenu le certificat.


Fichiers de certificat

Après avoir obtenu le certificat, vous aurez les fichiers encodés PEM suivants :

  • cert.pem : Le certificat de votre domaine
  • chain.pem : Le certificat de chaîne Let's Encrypt
  • chaîne complète.pem : cert.pem and chain.pem combined
  • privkey.pem : La clé privée de votre certificat

Il est important que vous connaissiez l'emplacement des fichiers de certificat qui viennent d'être créés, afin de pouvoir les utiliser dans la configuration de votre serveur Web. Les fichiers eux-mêmes sont placés dans un sous-répertoire dans /etc/letsencrypt/archive. Cependant, Certbot crée des liens symboliques vers les fichiers de certificat les plus récents dans le répertoire /etc/letsencrypt/live/your_domain_name.

Vous pouvez vérifier que les fichiers existent en exécutant cette commande (en remplaçant votre nom de domaine) :

sudo ls /etc/letsencrypt/live/your_domain_name

La sortie doit être les quatre fichiers de certificat mentionnés précédemment.

Combinez fullchain.pem et privkey.pem

Lors de la configuration de HAProxy pour effectuer la terminaison SSL, afin qu'il chiffre le trafic entre lui-même et l'utilisateur final, vous devez combiner fullchain.pem et privkey.pem dans un seul fichier.

Commencez par créer le répertoire où sera placé le fichier combiné, /etc/haproxy/certs :

sudo mkdir -p /etc/haproxy/certs

Ensuite, créez le fichier combiné avec cette commande cat (remplacez le example.com en surbrillance par votre nom de domaine) :

DOMAIN='example.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'

Sécurisez l'accès au fichier combiné, qui contient la clé privée, avec cette commande :

sudo chmod -R go-rwx /etc/haproxy/certs

Nous sommes maintenant prêts à utiliser le certificat SSL et la clé privée avec HAProxy.

Étape 3 - Installation de HAProxy

Cette étape couvre l'installation de HAProxy. S'il est déjà installé sur votre serveur, ignorez cette étape.

Installez HAProxy avec yum :

sudo yum install haproxy

HAProxy est maintenant installé mais doit être configuré.

Étape 4 - Configuration de HAProxy

Cette section vous montrera comment configurer HAProxy de base avec la configuration SSL. Il explique également comment configurer HAProxy pour nous permettre de renouveler automatiquement notre certificat Let's Encrypt.

Ouvrez haproxy.cfg dans un éditeur de texte :

sudo vi /etc/haproxy/haproxy.cfg

Gardez ce fichier ouvert pendant que nous le modifions dans les sections suivantes.

Section mondiale

Ajoutez cette ligne à la section global pour configurer la taille maximale des clés DHE temporaires générées :

haproxy.cfg — 1 sur 5

   tune.ssl.default-dh-param 2048

Sections frontales

Nous sommes maintenant prêts à définir nos sections frontend.

Remarque : La configuration HAProxy par défaut comprend un frontend et plusieurs backends. N'hésitez pas à les supprimer car nous ne les utiliserons pas.


La première chose que nous voulons ajouter est une interface pour gérer les connexions HTTP entrantes et les envoyer à un backend par défaut (que nous définirons plus tard). À la fin du fichier, ajoutons une interface appelée www-http. Assurez-vous de remplacer haproxy_public_IP par l'adresse IP publique de votre serveur HAProxy :

haproxy.cfg — 2 sur 5

frontend www-http
   bind haproxy_www_public_IP:80
   reqadd X-Forwarded-Proto:\ http
   default_backend www-backend

Ensuite, nous ajouterons une interface pour gérer les connexions HTTPS entrantes. À la fin du fichier, ajoutez une interface appelée www-https. Assurez-vous de remplacer haproxy_www_public_IP par l'adresse IP publique de votre serveur HAProxy. De plus, vous devrez remplacer example.com par votre nom de domaine (qui doit correspondre au fichier de certificat que vous avez créé précédemment) :

haproxy.cfg — 3 sur 5

frontend www-https
   bind haproxy_www_public_IP:443 ssl crt /etc/haproxy/certs/example.com.pem
   reqadd X-Forwarded-Proto:\ https
   acl letsencrypt-acl path_beg /.well-known/acme-challenge/
   use_backend letsencrypt-backend if letsencrypt-acl
   default_backend www-backend

Ce frontend utilise une ACL (letsencrypt-acl) pour envoyer les requêtes de validation Let's Encrypt (pour /.well-known/acme-challenge) au backend letsencrypt-backend, ce qui nous permettra de renouveler le certificat sans arrêter le HAProxy un service. Toutes les autres demandes seront transmises au www-backend, qui est le backend qui servira notre application Web ou notre site.

Sections principales

Une fois que vous avez terminé de configurer les frontends, ajoutez le backend www-backend en ajoutant les lignes suivantes. Assurez-vous de remplacer les mots en surbrillance par les adresses IP privées respectives de vos serveurs Web (ajustez le nombre de lignes server en fonction du nombre de serveurs principaux dont vous disposez) :

haproxy.cfg — 4 sur 5

backend www-backend
   redirect scheme https if !{ ssl_fc }
   server www-1 www_1_private_IP:80 check
   server www-2 www_2_private_IP:80 check

Tout trafic reçu par ce backend sera équilibré entre ses entrées server, via HTTP (port 80).

Enfin, ajoutez le backend letsencrypt-backend, en ajoutant ces lignes

haproxy.cfg — 5 sur 5

backend letsencrypt-backend
   server letsencrypt 127.0.0.1:54321

Ce backend, qui ne gère que les défis Let's Encrypt ACME utilisés pour les demandes et les renouvellements de certificats, envoie le trafic à l'hôte local sur le port 54321. Nous utiliserons ce port au lieu de 80 et 443 lors du renouvellement de notre certificat SSL Let's Encrypt.

Nous sommes maintenant prêts à démarrer HAProxy :

sudo systemctl start haproxy

Remarque : Si vous rencontrez des problèmes avec le fichier de configuration haproxy.cfg, consultez ce GitHub Gist pour un exemple.


Le certificat Let's Encrypt TLS/SSL est maintenant en place et nous sommes prêts à configurer le script de renouvellement automatique. À ce stade, vous devez tester le fonctionnement du certificat TLS/SSL en visitant votre domaine dans un navigateur Web.

Étape 5 - Configuration du renouvellement automatique

Les certificats Let's Encrypt ne sont valables que 90 jours, il est donc important d'automatiser le processus de renouvellement.

Un moyen pratique de vous assurer que vos certificats ne seront pas obsolètes consiste à créer une tâche cron qui gérera automatiquement le processus de renouvellement pour vous. Le cronjob exécutera certbot quotidiennement et renouvellera les certificats s'ils sont dans les trente jours suivant leur expiration. certbot exécutera également un script spécial renew-hook après tout renouvellement réussi. Nous utiliserons ce script de renouvellement pour mettre à jour notre fichier combiné .pem et recharger haproxy.

Créons ce script maintenant, puis testons-le.

Créer un script de renouvellement

Ouvrez un nouveau fichier dans /usr/local/bin en tant que root :

sudo vi /usr/local/bin/renew.sh

Ce sera un nouveau fichier texte vierge. Collez le court script suivant, en veillant à mettre à jour le nom de domaine en surbrillance avec le vôtre :

#!/bin/sh

SITE=example.com

# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE

# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem

# reload haproxy
systemctl reload haproxy

Enregistrez et fermez le fichier. Ce script se déplace dans le bon répertoire Let's Encrypt, exécute la commande cat pour concaténer les deux fichiers .pem en un seul, puis recharge haproxy.

Ensuite, rendez le script exécutable :

sudo chmod u+x /usr/local/bin/renew.sh

Exécutez ensuite le script :

sudo /usr/local/bin/renew.sh

Il devrait fonctionner sans erreur. Ensuite, nous mettrons à jour Certbot et le configurerons pour exécuter ce script de renouvellement.

Mettre à jour les configurations de certbot

La commande certbot renew que nous utiliserons pour renouveler nos certificats lit un fichier de configuration qui a été créé la première fois que nous avons exécuté certbot. Nous devons ouvrir ce fichier et mettre à jour le port que certbot utilise pour exécuter son serveur http autonome afin qu'il n'entre pas en conflit avec haproxy (qui écoute déjà sur les ports 80 et 443). Ouvrez le fichier de configuration dans un éditeur de texte :

sudo vi /etc/letsencrypt/renewal/example.com.conf

Nous devons changer la ligne http01_port, donc elle se lit comme suit :

exemple.com.conf

http01_port = 54321

Enregistrez et fermez le fichier. Testez maintenant le processus de renouvellement, en spécifiant --dry-run afin que nous ne renouvelions rien :

sudo certbot renew --dry-run

Certbot écoutera le port 54321 pour le défi de renouvellement, et haproxy transmettra la demande du port 80 au 54321.

Créer une tâche cron

Ensuite, nous allons modifier la crontab pour créer une nouvelle tâche qui exécutera la commande certbot renew tous les jours. Pour modifier la crontab pour l'utilisateur root, exécutez :

sudo crontab -e

Ajoutez ce qui suit au bas du fichier :

entrée crontab

30 2 * * * /usr/bin/certbot renew --renew-hook "/usr/local/bin/renew.sh" >> /var/log/le-renewal.log

Sauvegarder et quitter. Cela créera une nouvelle tâche cron qui exécutera la commande certbot renew tous les jours à 2h30. La sortie produite par la commande sera redirigée vers un fichier journal situé dans /var/log/le-renewal.log. Si le certificat est effectivement renouvelé, le script --renew-hook s'exécute pour créer le fichier PEM combiné et recharger haproxy.

Conclusion

C'est ça! HAProxy utilise désormais un certificat Let's Encrypt TLS/SSL gratuit pour servir le trafic HTTPS en toute sécurité.