Title: Utiliser Let's Encrypt avec Haproxy subtitle: [FR] Date: 2015-12-18 09:33 Modified: 2015-12-18 09:33 Category: Système Tags: haproxy, hébergement, reverse proxy, sécurité, système keywords: haproxy, hébergement, reverse proxy, sécurité, système Slug: utiliser-letsencrypt-haproxy Authors: Victor Status: published lang: fr
[TOC]
Note: This is the French version of the post. English version here.
Haproxy est un logiciel de proxy. Il peut servir à beaucoup de chose, ici nous l'utiliserons pour de l'https et de l'http. Je vous invite à lire mon article à ce sujet si vous voulez en savoir plus.
Dans cet article, nous considérerons que vous avez un serveur avec Haproxy fonctionnel pour les tests.
Let's Encrypt est un projet soutenu entre autre par la fondation Mozilla et Cisco.
L'idée est de mettre en place une autorité de certification gratuite pour créer des certificats SSL et permettre au plus grand nombre de personne de sécuriser leurs sites web.
Au regard du prix habituel d'un certificat, c'est un projet vraiment très intéressant !
D'autant plus qu'il est vraiment axé sur la facilité d'utilisation, avec notamment une API permettant de créer des certificats de manière simple.
Nous nous appuierons ici sur cette API, à travers un client créé par Let's Encrypt.
EDIT : 04/04/16 : ajout d'une note si vous utilisez des redirect de l'http vers l'https, pour permettre le renouvellement auto de letsencrypt
EDIT : 16/09/16 : Mise à jour avec les nouveaux binaires suite à la sortie de bêta de LE + amélioration et versionning des Scripts
Let's Encrypt propose plusieurs options via le client pour télécharger et valider un certificat SSL.
Si votre haproxy est sur le même serveur que le serveur web, vous pouvez utiliser l'option --webroot, qui permet de placer un fichier à la racine de votre site, que le site letsencrypt ira vérifier pour valider que vous possédez bien le site web. Si vous souhaitez utiliser cette technique, cet article de blog explique très bien comment le faire interagir en utilisant un serveur apache dédié.
Dans cet article, nous utiliserons l'option --standalone qui permet de lancer un mini serveur web, qui contiendra le fichier de vérification et qui sera utilisé par le site letsencrypt. Cette option présente à première vue l'inconvénient de devoir utiliser le port 80 ou 443 pour lancer le serveur web, ce qui demande evidemment de faire sauter le serveur web principal, et donc de couper les sites pendant la vérification.
Mais nous allons utiliser une option du client qui permet d'utiliser un autre port que ceux par défaut, allié aux capacité frontend/backend de haproxy, pour effectuer la vérification sans aucune coupure de vos sites :-)
Merci à coolaj86 dont l'article m'a donné cette idée d'utiliser haproxy et Let's Encrypt ensembles ;-)
-- Many thanks to coolaj86 as his post give me this idea to use haproxy and Let's Encrypt together ;-) --
Maintenent que LE est officiellement sorti un binaire plus carré est disponible, et beaucoup plus simple à installer que le précédent letsencrypt-auto.
Toutes les info sont présente sur le site officiel de certbot, mais voici les instructions rapides pour l'installer.
cd /root/
mkdir letsencrypt
cd letsencrypt
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
Vous pouvez ensuite directement utiliser le binaire pour activer vos certificats
./certbot-auto certonly --domains blog.victor-hery.com --renew-by-default --http-01-port 63443 --agree-tos
Pour éviter toute coupure, nous allons utiliser votre (vos) frontend existant.
La requête de Let's Encrypt se fera sur l'adresse IP à laquelle répond le site web pour lequel vous générez le certificat, donc si vous avez plusieurs frontend ou plusieurs IP, il faudra configurer chaque frontend selon vos besoins.
L'idée est la suivante : lors de sa requête, Let's Encrypt interrogera l'url du site, suivi simplement de /.well-known/acme-challenge/un-id_unique.
Nous allons donc configurer une acl qui cherchera cette chaine pour la rediriger vers un backend spécifique !
frontend http-in acl app_letsencrypt path_beg /.well-known/acme-challenge/ [...] use_backend bk-letsencrypt if app_letsencrypt
Ainsi, toutes les requêtes de vérification de Let's Encrypt seront redirigées vers le backend bk-letsencrypt.
Attention : Si vous redirigez de manière forcée vos sites en HTTP vers l'HTTPS, alors haproxy va rediriger aussi les requêtes let's encrypt vers votre frontend HTTS.
Il faut alors ajouter l'acl et le use_backend bk-letsencrypt dans votre frontend https !
Concernant le backend, nous allons le configurer pour rediriger les requêtes vers le serveur qui sera lancé en local par le client Let's Encrypt.
backend bk-letsencrypt log global mode http server srv_letsencrypt 127.0.0.1:63443
Ce serveur ne tournera pas en permanence, uniquement lorsque le client Let's Encrypt est en attente de vérification, en temps normal haproxy renverra donc une erreur 503 si quelqu'un tente d'accéder à une URL qui correspond à l'acl du frontend.
Bien sûr, rechargez haproxy après ces modifications.
systemctl reload haproxy.service
Pour simplifier la ligne de commande et faciliter l'automatisation, nous allons directement configurer un fichier pour Let's Encrypt.
Let's Encrypt utilise par défaut le fichier /etc/letsencrypt/cli.ini. Nous allons donc taper dedans directement.
rsa-key-size = 4096 email = your_admin_email authenticator = standalone standalone-supported-challenges = http-01
Utiliser http pour la vérification ne pose pas de problème, car seule la requête de validation passe en clair, et elle n'a rien de secrète.
La ligne de commande à utiliser pour générer votre certificat est la suivante :
/root/letsencrypt/certbot-auto certonly --domains yourdomain.tld --renew-by-default --http-01-port 63443 --agree-tos
Les certificats sont mis en place dans le répertoire /etc/letsencrypt/live/yourdomain.tld/ par le client lors de la génération.
Vous y trouverez plusieurs fichiers :
Pour haproxy, vous devez concaténer fullchain.pem et privkey.pem dans un seul fichier, et le placer là ou votre haproxy lit ses certificats.
cat fullchain.pem privkey.pem > domain.tld.pem
Un exemple :
frontend https-in bind IP:443 ssl crt /etc/haproxy/cert/
Ici, nous devons mettre notre fichier.pem dans le répertoire /etc/haproxy/cert/
Une fois le certificat placé là, rechargez haproxy pour qu'il le lise, et ça y est tout sera Ok.
N'oubliez pas que pour que votre site fonctionne en HTTPS, il faudra un frontend https dans haproxy, avec les acl qui vont bien.
En général, un copier/coller de votre frontend HTTP classique en changeant le port vers 443 fait l'affaire.
Même sorti de bêta, LE a pris la décision de ne fournir des certificat valides que 3 mois (90 jours), ce afin d'éviter les abus et faire "vivre" le certificat.
Notez que contrairement au binaire de bêta, certbot-auto peut scanner vos certificats disponibles (via le répertoire /etc/letsencrypt/renewal/) pour les renouveller automatiquement.
Pensez donc à configurer une tache cron sur votre serveur pour renouveler le certificat régulièrement
crontab -e #renew certificate 30 01 01,10,20,30 * * /root/letsencrypt/certbot-auto renew
Cette tâche permettra de lancer la commande tous les 10 jours, afin d'être sur d'avoir des certificats à jour.
N'oubliez pas qu'il faudra quand même aller récupérer le fullchain.pem et le .key pour aller les mettre dans haproxy. Voyez plus bas pour un peu d'automatisation sur cette tâche !
A cause de sa gratuité, Let's Encrypt dispose d'un système évitant de générer trop violemment des certificats pour le même domaine.
Vous aurez donc une erreur si vous tentez de générer trop vite ou trop souvent des certificats avec le même domaine.
Attention, c'est valable également pour les sous-domaine ! La limitation prend en compte tout ce qui se termine par domain.tld.
Actuellement Let's Encrypt ne gère pas les noms de domaines internationaux.
Il est donc impossible de générer un certificat pour un domaine ou un sous-domaine contenant des accents ou des caractères spéciaux.
Impossible par exemple de générer pour l'instant un certificat pour blog.héry.com malheureusement.
Une requête existe actuellement à ce sujet sur le github de Let's Encrypt, mais plusieurs mois après le passage en stable, ce n'est toujours pas prêt malheureusement. Affaire à suivre (et à aider dans la mesure de ses moyens ;-) )
Histoire de faciliter la génération et la mise en place sur haproxy, j'ai écris quelques petits scripts maison permettant de générer le certificat et le placer dans le bon répertoire, ainsi que gérer proprement le renouvellement.
Ceux-ci sont disponibles sur mon dépôt git, vous pouvez donc directement les cloner sur votre serveur :
git clone https://git.lecygnenoir.info/LecygneNoir/letsencrypt-haproxy.git
Le README décrit rapidement comment utiliser les scripts, c'est globalement assez simple.
create_certificate permet de créer un certificat pour le domaine passé en paramètre, génère le .pem pour haproxy, le place dans l'arborescence haproxy et reload haproxy.
renew-certificates se contente de renouveler tous les certificats, de générer les fichiers pour haproxy et de reload ce dernier. Vous pouvez utiliser renew-certificates dans une tâche cron comme indiqué plus haut.
Vérifiez les chemins dans les scripts, notamment où placer les certificats et le chemin vers le binaire certbot
Voila, avec tout ça vous devriez pouvoir générer autant de certificat que vous le souhaitez, et les utiliser directement dans haproxy, alors bienvenue dans le monde de l'HTTPS !