Utilisation des certificats « Let’s Encrypt »

../../../../2016/02/20/letsencrypt/
Antoine Van-Elstraete (antoine@van-elstraete.net)
samedi 18 juin 2016





6 min.

Image d'illustration

Introduction

Dans cet article, je vais montrer comment j’ai déployé des certificats SSL/TLS fournis par « Let’s Encrypt ». J’utilise un serveur web nginx qui sert de reverse proxy, dans une jail sur un système FreeBSD. Je ne reviendrais pas sur le principe de la jail ou du reverse proxy.

Let’s Encrypt

« Let’s Encrypt » (site officiel) : https://letsencrypt.org/

« Let’s Encrypt » (« passons chiffré ») est une autorité de certification libre, gratuite et automatisée, d’intérêt public. « Let’s Encrypt » est un service proposé par l’« Internet Security Research Group (ISRG) » (Groupe de recherche pour la sécurité sur Internet).

Les principes clés derrière « Let’s Encrypt » sont :

  • gratuité : n’importe quelle personne possédant un nom de domaine peut utiliser « Let’s Encrypt » pour obtenir un certificat gratuitement.
  • automatisation : le logiciel de service web peut interagir avec « Let’s Encrypt » pour obtenir facilement un certificat, être configuré de manière sécurisante, et s’occuper automatiquement du renouvellement du certificat.
  • sécurité : « Let’s Encrypt » servira de plateforme pour faire avancer les meilleurs pratiques de sécurité TLS, aussi bien du côté de l’autorité de certification qu’en aidant les administrateurs à sécuriser correctement leurs seveurs.
  • transparence : tous les certificats émis ou révoqués seront publiquement conservés, et disponible pour toutes personnes souhaitant vérifier le système.
  • liberté, ouverture : le protocole d’émission et de renouvellement sera publié comme un standard ouvert que d’autres pourront adopter.
  • coopératif : tout comme l’est le protocole Internet, « Let’s Encrypt » s’est joint à l’effort d’intérêt publique, et bénéficie à la communauté en dehors de tout contrôle par une organisation privée.

— traduction libre de https://letsencrypt.org/about/

« Let’s Encrypt » a donc pour but de remplacer les autorités de certification (Comodo, UserTrust, …) faisant payer les certificats SSL, dans le but de démocratiser la pratique de chiffrement via SSL/TLS des transmissions web, tout en étant validé directement avec les navigateurs (contrairement à StartSSL ou CACert).

Installation d’un certificat

Installation de « Let’s Encrypt »

[16/06/2016]

Le client officiel pour les certificats Let’s Encrypt est certbot. Toutes les informations concernant son installation sur différentes plateformes sont disponibles sur https://certbot.eff.org/ .

Obtention du certificat

[21/02/2016] Je suis tombé sur [en] https://www.nginx.com/blog/free-certificates-lets-encrypt-and-nginx/, qui montre comment utiliser un bloc location /.well-known/acme-challenge pour rediriger les accès du serveur ACME vers un emplacement en dehors du webroot habituel du site (ce que je fais ici, en utilisant le dossier static qui ne contient pas les fichiers du blog mais ceux pour « keybase » et maintenant « Let’s Encrypt ».

Pour obtenir un certificat, sous FreeBSD et nginx, il n’y a pas (encore) de procédure automatisée. Il faut donc utiliser le mode manuel (option certonly --webroot), puis configurer soi-même nginx. De plus, il y a un paramétre dont le problème a déjà été soulevé : la taille de la clé ([en] https://github.com/letsencrypt/letsencrypt/issues/489). Par défaut elle est de 2048 bits, mais il est plus sage d’utiliser une clé d’au moins 3072 bits (voir le Référentiel Général de Sécurité, annexe B1, page 17, publié par l’ANSSI [fr] http://references.modernisation.gouv.fr/securite). Personnellement, je choisis de générer une clé de 4096 bits (option --rsa-key-size 4096). L’option --text sert simplement à rester en mode texte simple pour l’interface utilisateur (il est possible d’utiliser « ncurses » par exemple).

Il faut passer à letsencrypt-auto le(s) nom(s) de domaine (option -d), une adresse e-mail (option --email), ainsi que l’emplacement où le serveur de certification (« ACME CA », voir ce document [en] https://letsencrypt.org/howitworks/technology/) pourra placer la preuve cryptographique (option -w, la preuve sera dans le sous-dossier .well-known/acme-challenge/). Pour ce site, cela donne :

cd letsencrypt
./letsencrypt-auto certonly --webroot --email webmaster@antoineve.me --rsa-key-size 4096 --text -w /usr/jails/blog.antoineve.me/usr/local/www/blog.antoineve.me/blog/statics/ -d blog.antoineve.me -d www.blog.antoineve.me

J’utilise les « jails » FreeBSD, mais j’execute letsencrypt-auto sur la machine réelle. Cela me permet d’utiliser la même installation pour plusieurs service, chacun étant dans une jail séparée. Cela implique de lancer letsencrypt-auto en tant qu’utilisateur root.

Configuration de nginx

Afin de pouvoir passer les certificats et clés à nginx, je copie le dossier /etc/letsencrypt/ dans ma jail HTTP-reverse. L’outil « rsync » fait ça très bien : rsync -avh --delete-after /etc/letsencrypt/ /usr/jails/HTTP-reverse/usr/local/etc/nginx/ssl/letsencrypt/. Ensuite, il suffit d’indiquer à nginx d’utiliser ces certificats. Pour information, voici ce que j’utilise pour ce site (dans la partie « server ») :

listen                  192.168.64.80:443 ssl http2;
listen                  164.132.67.240:443 ssl http2;
listen                  [2001:41d0:2:9409::80]:443 ssl http2;
server_name             blog.antoineve.me;
ssl                     on;
ssl_certificate         /usr/local/etc/nginx/ssl/letsencrypt/live/blog.antoineve.me/fullchain.pem;
ssl_certificate_key     /usr/local/etc/nginx/ssl/letsencrypt/live/blog.antoineve.me/privkey.pem;
ssl_dhparam             /usr/local/etc/nginx/ssl/dhparams.pem;
ssl_ecdh_curve          secp384r1;
ssl_ciphers             "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:AES256+EECDH:AES256+EDH";
ssl_protocols           TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache       shared:SSL:10m;
add_header              Strict-Transport-Security       "max-age=15552000; includeSubDomains; preload";
add_header              Content-Security-Policy         upgrade-insecure-requests;
add_header              Content-Security-Policy         block-all-mixed-content;

Script de renouvellement

Ce script est plutôt simple :

  1. renouvellement (si necessaire) des certificats
  2. synchronisation des données
  3. recharge le serveur nginx dans la jail HTTP-reverse
#!/bin/sh
/root/letsencrypt/letsencrypt-auto renew --standalone > /dev/null
rsync -a --delete-after /etc/letsencrypt/ /usr/jails/HTTP-reverse/usr/local/etc/nginx/ssl/letsencrypt/ > /dev/null
jexec $(jls | grep HTTP |cut -f 2 -w) service nginx reload > /dev/null 2>&1

Ce script est ensuite exécuté toutes les 48h via une tâche cron.

Conclusion

Voilà comment obtenir un certificat SSL, gratuitement, et (assez) simplement pour vos sites web. L’utilisation d’un serveur sous FreeBSD et d’un reverse proxy nginx ajoute quelques subtilités au processus. Malheureusement, certaines options de SSL/TLS sont perdues au passage : la gestion du certificat dans le DNS (avec DANE/TLSA) et la Public Key Pinning Extension ne sont plus utilisées ici car le fonctionnement de « Let’s Encrypt » ne le permet pas facilement. J’espère pouvoir corriger ces points, en m’interressant de plus près au projet acme-tiny ([en] https://github.com/diafygi/acme-tiny). Mais comme expliqué dans l’article « Let’s Encrypt : joies… et déceptions ! » ([fr] https://blog.imirhil.fr/2015/12/12/letsencrypt-joie-deception.html), cela n’a pas l’air simple pour le moment.