Comment sécuriser HAProxy avec Let’s Encrypt sur Ubuntu 14.04

introduction

Let’s Encrypt est une nouvelle autorité de certification qui fournit un moyen simple d’obtenir et d’installer des certificats TLS / SSL gratuits, permettant ainsi le cryptage HTTPS sur des serveurs Web. Il simplifie le processus en fournissant un logiciel client, 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. Toutefois, Certbot peut être utilisé pour obtenir facilement un certificat SSL gratuit, qui peut être installé manuellement, quel que soit le logiciel de serveur Web choisi.

Dans ce tutoriel, nous allons vous montrer comment utiliser Certbot pour obtenir un certificat SSL gratuit et l'utiliser avec HAProxy sur Ubuntu 14.04. Nous vous montrerons également comment renouveler automatiquement votre certificat SSL.

HAProxy with Let’s Encrypt TLS/SSL Certificate and Auto-renewal

Conditions préalables

Avant de suivre ce tutoriel, vous aurez besoin de quelques choses.

Vous devriez avoir un serveur Ubuntu 14.04 avec un utilisateur non root qui a les privilègessudo. Vous pouvez apprendre comment configurer un tel compte utilisateur en suivant les étapes 1 à 3 de nosinitial server setup for Ubuntu 14.04.

Vous devez posséder ou contrôler le nom de domaine enregistré avec lequel vous souhaitez utiliser le certificat. Si vous ne possédez pas déjà un nom de domaine enregistré, vous pouvez en enregistrer un auprès d’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 unA Record qui pointe votre domaine vers l’adresse IP publique de votre serveur. Cela est nécessaire en raison de la façon dont Let’s Encrypt a confirmé que vous êtes propriétaire du domaine pour lequel il émet un certificat. Par exemple, si vous souhaitez obtenir un certificat pourexample.com, ce domaine doit être résolu sur votre serveur pour que le processus de validation fonctionne. Notre configuration utiliseraexample.com etwww.example.com comme noms de domaine, doncboth DNS records are required.

Une fois que vous avez éliminé toutes les conditions préalables, passons à l’installation decertbot, le logiciel client Let’s Encrypt.

[[step-1 -—- Installing-let-39-s-encrypt-client]] == Étape 1 - Installation de Let’s Encrypt Client

La première étape pour utiliser Let’s Encrypt pour obtenir un certificat SSL consiste à installer le logicielcertbot sur votre serveur. Les développeurs de Certbot fournissent un référentiel avec les versions à jour du logiciel. Ajoutons maintenant ce référentiel à notre gestionnaire de paquets:

sudo add-apt-repository ppa:certbot/certbot

Vous serez invité à confirmer l'ajout. Appuyez surENTER pour continuer. Puis mettez à jour le cache du paquet pour ramasser la nouvelle liste de paquets:

sudo apt-get update

Et enfin, installez le packagecertbot:

sudo apt-get install certbot

Maintenant quecertbot est installé, nous sommes prêts à obtenir notre certificat SSL.

[[step-2 -—- getting-a-certificate]] == Étape 2 - Obtention d'un certificat

Let’s Encrypt propose différentes méthodes pour obtenir des certificats SSL via divers plugins. Contrairement au plugin Apache, qui est couvert dansa different tutorial, la plupart des plugins ne vous aideront qu'à obtenir un certificat que vous devez configurer manuellement votre serveur Web à utiliser. Les plug-ins qui obtiennent uniquement des certificats et ne les installent pas sont appelés «authentificateurs» car ils permettent d'authentifier si un serveur doit recevoir un certificat.

Nous allons vous montrer comment utiliser le pluginStandalone 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 port80 par défaut) 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 port80 ne soit pas utilisé. Autrement dit, assurez-vous d'arrêter votre serveur Web normal, s'il utilise le port80 (c.-à-d. http), avant d'essayer d'utiliser ce plugin.

Par exemple, si vous utilisez HAProxy, vous pouvez l’arrêter en exécutant la commande suivante:

sudo service haproxy stop

Si vous n'êtes pas sûr que le port80 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 Standalone.

Exécuter Certbot

Maintenant, utilisez le plugin autonome en lançant cette commande:

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

Vous serez invité à entrer votre adresse e-mail et à accepter les conditions d'utilisation de Let’s Encrypt. Ensuite, le défihttp s'exécutera. Si tout réussit,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 ci-dessus.

[.note] #Note: Si votre domaine achemine 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 suivants codés PEM:

  • cert.pem: Certificat de votre domaine

  • chain.pem: Le certificat de chaîne Let’s Encrypt

  • fullchain.pem:cert.pem etchain.pem combinés

  • privkey.pem: La clé privée de votre certificat

Il est important que vous connaissiez l'emplacement des fichiers de certificat que vous venez de créer 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 de/etc/letsencrypt/archive. Cependant, Certbot crée des liens symboliques vers les fichiers de certificats les plus récents dans le répertoire/etc/letsencrypt/live/your_domain_name.

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

sudo ls /etc/letsencrypt/live/your_domain_name

Le résultat devrait ê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 une terminaison SSL, afin qu'il crypte le trafic entre lui-même et l'utilisateur final, vous devez combinerfullchain.pem etprivkey.pem dans un seul fichier.

Tout d'abord, créez le répertoire où le fichier combiné sera placé,/etc/haproxy/certs:

sudo mkdir -p /etc/haproxy/certs

Ensuite, créez le fichier combiné avec cette commandecat (remplacez lesexample.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.

[[step-3 -—- Installing-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.

Nous allons installer HAProxy 1.6, qui ne se trouve pas dans les référentiels Ubuntu par défaut. Cependant, nous pouvons toujours utiliser un gestionnaire de paquets pour installer HAProxy 1.6, si nous utilisons un PPA, avec cette commande:

sudo add-apt-repository ppa:vbernat/haproxy-1.6

Mettez à jour l'index de paquetage local sur vos équilibreurs de charge et installez HAProxy en tapant:

sudo apt-get update
sudo apt-get install haproxy

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

[[step-4 -—- configuring-haproxy]] == Étape 4 - Configuration de HAProxy

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

Ouvrezhaproxy.cfg dans un éditeur de texte:

sudo nano /etc/haproxy/haproxy.cfg

Laissez ce fichier ouvert pendant que nous l'éditions dans les sections suivantes.

Section globale

Ajoutons quelques paramètres de base dans la sectionglobal.

La première chose que vous voudrez faire est de définirmaxconn sur un nombre raisonnable. Cela affecte le nombre de connexions simultanées autorisées par HAProxy, ce qui peut affecter la qualité de service et empêcher vos serveurs Web de se bloquer en essayant de traiter trop de demandes. Vous devrez jouer avec pour trouver ce qui fonctionne pour votre environnement. Ajoutez la ligne suivante (avec une valeur que vous pensez raisonnable) à la sectionglobal:

haproxy.cfg — 1 of 7

   maxconn 2048

Ensuite, ajoutez cette ligne pour configurer la taille maximale des clés DHE temporaires générées:

haproxy.cfg — 2 of 7

   tune.ssl.default-dh-param 2048

Section Défauts

Ajoutez les lignes suivantes sous la sectiondefaults:

haproxy.cfg — 3 of 7

   option forwardfor
   option http-server-close

L'option forwardfor définit HAProxy pour ajouter les en-têtesX-Forwarded-For à chaque requête, et l'optionhttp-server-close réduit la latence entre HAProxy et vos utilisateurs en fermant les connexions mais en maintenant les keep-alives.

Sections Frontend

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

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

haproxy.cfg — 4 of 7

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

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

haproxy.cfg — 5 of 7

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 demandes de validation Let’s Encrypt (pour/.well-known/acme-challenge) au backendletsencrypt-backend, ce qui nous permettra de renouveler le certificat sans arrêter le service HAProxy. Toutes les autres demandes seront transmises auwww-backend, qui est le backend qui servira notre application Web ou notre site.

Sections Backend

Une fois que vous avez fini de configurer les frontaux, ajoutez le backendwww-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 lignesserver pour correspondre au nombre de serveurs backend dont vous disposez):

haproxy.cfg — 6 of 7

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éesserver, via HTTP (port 80).

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

haproxy.cfg — 7 of 7

backend letsencrypt-backend
   server letsencrypt 127.0.0.1:54321

Ce backend, qui ne gère que les défis Let’s Encrypt ACME qui sont utilisés pour les demandes de certificats et les renouvellements, envoie le trafic à l'hôte local sur le port54321. Nous utiliserons ce port au lieu de80 et443 lorsque nous renouvellerons notre certificat SSL Let’s Encrypt.

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

sudo service haproxy restart

[.note] #Note: Si vous rencontrez des problèmes avec le fichier de configuration dehaproxy.cfg, consultezthis 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 vérifier que le certificat TLS / SSL fonctionne en visitant votre domaine dans un navigateur Web.

[[step-5 -—- setting-up-auto-renew]] == Étape 5 - Configuration du renouvellement automatique

Les certificats de Let Encrypt n’ont une validité que de 90 jours. Il est donc important d’automatiser le processus de renouvellement.

Un moyen pratique de vous assurer que vos certificats ne seront pas périmés est de créer un travail cron qui gérera automatiquement le processus de renouvellement pour vous. Le cronjob exécuteracertbot tous les jours et renouvellera les certificats s'ils sont dans les trente jours suivant leur expiration. certbot exécutera également un script spécialrenew-hook après tout renouvellement réussi. Nous utiliserons ce script de renouvellement pour mettre à jour notre fichier.pem combiné 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 queroot:

sudo nano /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
service haproxy reload

Enregistrez et fermez le fichier. Ce script se déplace dans le bon répertoire Let’s Encrypt, exécute la commandecat 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

Ensuite, lancez le script:

sudo /usr/local/bin/renew.sh

Il devrait fonctionner sans erreur. Vous verrez des résultats sur le rechargement de haproxy. Nous allons ensuite mettre à jour Certbot et le configurer pour exécuter ce script de renouvellement.

Mettre à jour les configurations de certbot

La commandecertbot 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 quecertbot utilise pour exécuter son serveur http autonome afin qu’il ne soit 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 nano /etc/letsencrypt/renewal/example.com.conf

Nous devons changer la lignehttp01_port, donc cela se lit comme suit:

example.com.conf

http01_port = 54321

Enregistrez et fermez le fichier. Maintenant, testez le processus de renouvellement en spécifiant--dry-run pour ne rien renouveler:

sudo certbot renew --dry-run

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

Créer une tâche cron

Ensuite, nous éditerons le crontab pour créer un nouveau travail qui exécutera la commandecertbot renew tous les jours. Pour éditer 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 un nouveau travail cron qui exécutera la commandecertbot renew tous les jours à 2h30 du matin. La sortie produite par la commande sera redirigée vers un fichier journal situé à/var/log/le-renewal.log. Si le certificat est réellement renouvelé, le script--renew-hook s'exécutera pour créer le fichier PEM combiné et rechargerhaproxy.

Conclusion

C'est ça! HAProxy utilise maintenant un certificat gratuit Let’s Encrypt TLS / SSL pour desservir de manière sécurisée le trafic HTTPS.

Related