Let's Encrypt : premières impressions

Avertissement : j'ai écrit ce billet à une époque où le service était uniquement disponible en béta fermée sur inscription. Beaucoup de choses ont sûrement évolué depuis.

Lorsqu'on met en place un site Web et qu'on souhaite servir son site en HTTPS, il faut tout d'abord obtenir un certificat SSL auprès d'une autorité de certification.

Ces certificats SSL sont généralement payants, pour des raisons diverses et variées. Il existe quelques autorités de certification gratuites mais de qualité très variable. Les AC gratuites ne sont en outre pas toujours reconnues par la plupart des navigateurs et ainsi, sans configuration spécifique côté client, un tel certificat peut entraîner l'affichage d'une alerte de sécurité. Alertes qui sont conçues pour faire peur, et pour une bonne raison.

Jusqu'à maintenant, il y avait CACert et StartSSL. Le premier fonctionne bien mais n'est pas reconnu. Le second se targue d'être reconnu, mais mes mauvaises expériences chez eux ne m'incitent pas à les recommander. Mais une troisième AC gratuite, reconnue et particulièrement prometteuse va bientôt voir le jour : Let's Encrypt.

Let's Encrypt est en effet une nouvelle autorité de certification SSL qui fournit gratuitement des certificats DV (Domain Validation). Cerise sur le gâteau, cette autorité de certification est reconnue par la plupart des navigateurs.

Il y a deux semaines, j'ai donc reçu dans ma boîte mail une invitation à la béta fermée de Let's Encrypt.

E-mail reçu de la part
de Let's Encrypt
Un e-mail que j'ai attendu avec impatience.

L'occasion parfaite pour, en guise de test, générer un certificat et une clé privée SSL par le biais de leur service pour x0r.fr. L'expérience est une réussite et je suis sûr que cette autorité de certification finira par modifier en profondeur le marché des certificats SSL.

J'expliquerai succinctement l'intérêt qu'a pour des blogueurs comme moi le fait de servir du HTTPS, avant de montrer comment j'ai mis en œuvre les outils de Let's Encrypt sous FreeBSD pour générer mon certificat SSL.

Pourquoi tout le monde devrait (en théorie) servir du HTTPS

Il fut un temps où l'on estimait que servir son site en HTTPS n'était utile que lorsqu'il y avait un vrai impératif de confidentialité, comme par exemple sur un site marchand où on est amené à saisir des informations sensibles (numéros de carte bleue, etc.). Mais ça, c'était en 1997.

Il ne faut pas oublier les autres avantages du HTTPS, qui sont entre autres la protection de la vie privée de l'utilisateur et la protection de l'intégrité des pages Web.

Par exemple, aux États-Unis, un fournisseur d'accès à Internet proposait des connexions Wi-Fi gratuites. Cependant ce FAI injectait des publicités dans les pages visitées par les utilisateurs. Ces publicités injectées étaient placées de telle manière qu'elles semblaient provenir du site Web lui-même.

Rien n'empêcherait non plus un fournisseur d'accès à lancer un petit tcpdump et à enregistrer tous les paquets ayant comme port de destination 80, afin de logguer les sites consultés par chaque utilisateur.

En fin de compte, servir du HTTPS ne signifie en rien qu'on a forcément quelque chose à cacher ; il est aussi utile pour se protéger des intermédiaires techniques parfois peu scrupuleux. Et il paraît absurde de nos jours de vouloir restreindre cette protection à ceux qui seraient prêts à mettre des dizaines voire centaines d'euros par an pour cela. Dans un Web universel, le HTTPS devrait donc être accessible à tous, tant consommateurs que producteur de contenus.

Mise en œuvre de Let's Encrypt

Un des buts de Let's Encrypt est d'automatiser le plus possible les tâches de génération de clés publiques et privées d'une part et la génération de la requête de certification d'autre part. Avouons-le, qui s'est rappelé de la ligne de commandes d'openssl(1) du premier coup ?

Pour cela, l'autorité de certification fournit un programme, letsencrypt, qui se charge de gérer de façon automatisée les certificats.

Les certificats de Let's Encrypt étant des certificats DV (Domain Validation), dont la seule garantie est de « prouver » qu'ils ont été distribués au propriétaire légitime du domaine, le programme letsencrypt se charge aussi d'apporter la preuve que le demandeur du certificat contrôle bien le nom de domaine qu'il demande.

Le serveur d'authentification effectue pour cela une authentification par défi-réponse : le défi est un chemin (relatif à la racine du domaine) généré au hasard et supposé ne pas exister auparavant. La réponse est une chaîne de caractères qui doit être servie au format MIME text/plain par le serveur HTTP en réponse à un GET sur l'URL du défi.

Par défaut, letsencrypt veut ouvrir les ports 80 et 443 et écouter sur ces ports pour effectuer la validation par défi-réponse. Ceci est généralement impossible ; après tout, la plupart des gens qui souhaitent mettre en œuvre HTTPS ont déjà leur site en HTTP uniquement, et vraisemblablement un Apache, lighttpd ou nginx qui écoute sur ces deux ports. Il existe heureusement deux solutions : une manuelle, l'autre automatique. Les deux nécessitent cependant de modifier les fichiers de configuration du serveur Web ; je ne montrerai ici que nginx car je n'ai pas testé d'autres configurations.

Première installation et mise en œuvre de letsencrypt-auto

Note importante : le logiciel évolue assez rapidement ; aussi les bugs exhibés dans ce paragraphe pour­raient être résolus depuis, de nouveaux bugs pourraient s'être glissés depuis et le fonctionnement et les messages affichés à l'écran peuvant différer de ce qui est transcrit ici.

Mise à jour du 12 janvier 2016 : sous FreeBSD, le logiciel est désormais disponible dans la collection des ports FreeBSD. Le port s'appelle security/py-letsencrypt et le package pkgng s'appelle py27-letsencrypt. Installez-le par ce biais, c'est plus propre.

L'installation de letsencrypt et de ses dépendances commence par le clonage du dépôt Github.

# git clone 'https://github.com/letsencrypt/letsencrypt.git'
# cd letsencrypt/

Sa première mise en place devait normalement être faite par la commande ci-dessous, mais qui ne fonctionnait pas au moment de mes essais :

# ./letsencrypt-auto --debug
Bootstrapping dependencies for FreeBSD...
./letsencrypt-auto: : Permission denied

Pour obtenir le même résultat, il a fallu que j'enchaîne les deux commandes :

# sh bootstrap/freebsd.sh
# sh -x ./letsencrypt-auto --debug

Authentification manuelle

Lors de mes premiers essais, j'ai uniquement trouvé la méthode manuelle. Celle-ci s'invoque de la manière suivante :

# ./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory -a manual certonly

L'outil affiche pas mal de texte avant d'imprimer ceci à l'écran :

Make sure your web server displays the following content at
http://example.com/.well-known/acme-challenge/N5_Uft_vn0XL0sGfsYsvNCfEzWkm77iHTlmY-hPBT6A before continuing:

N5_Uft_vn0XL0sGfsYsvNCfEzWkm77iHTlmY-hPBT6A.G_2TWMVNdOlzHIUDK_XG9n_c8Bkk3yrAiwb-U-HSNxM

Content-Type header MUST be set to text/plain.

(snip)

Press ENTER to continue

On modifie ensuite la configuration nginx pour ajouter la clause suivante :

location /.well-known/acme-challenge/N5_Uft_vn0XL0sGfsYsvNCfEzWkm77iHTlmY-hPBT6A {
    default_type 'text/plain';
    return 200 'N5_Uft_vn0XL0sGfsYsvNCfEzWkm77iHTlmY-hPBT6A.G_2TWMVNdOlzHIUDK_XG9n_c8Bkk3yrAiwb-U-HSNxM';
}

On reload nginx et on appuie sur ENTRÉE. Si tout se passe bien, on obtient le message suivant :

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire
   on 2016-02-04. To obtain a new version of the certificate in the
   future, simply run Let's Encrypt again.

Renouvellement automatique

Mise à jour du 12 janvier 2016 : l'option --accept-dev-preview a été remplacée par --accept-tos depuis la béta ouverte.

Les certificats fournis par Let's Encrypt ne sont valables que 90 jours. Cette durée de validité est très courte et semble prendre à contrepied la politique de la plupart des autorités de certification, qui proposent des certificats valables entre 6 mois et 2 ans.

Lorsqu'on administre qu'un seul site Web, ce n'est pas très fastidieux de devoir modifier seulement quatre lignes de configuration nginx tous les deux à trois mois. Mais à partir de deux, ça devient vite peu pratique.

Heureusement, la tâche de renouvellement se prête bien à l'automatisation, moyennant deux modi­fi­cations. La première est d'utiliser letsencrypt avec l'option -a webroot au lieu de -a manual. Cela demande à letsencrypt de faire l'authentification par challenge-response en plaçant un fichier adéquat dans le sous-répertoire .well-known/acme-challenge dans l'emplacement de son choix. La deuxième est de modifier la configuration de nginx pour servir le contenu des fichiers de ce sous-répertoire.

Ces informations (ainsi que le gist de renchap) me permettent de faire le script shell de renouvellement, dont voici le listing.

#!/bin/sh

LETSENCRYPT="/root/.local/share/letsencrypt/bin/letsencrypt"
DIR="/tmp/letsencrypt-auto"
DOMAINS="-d example.com -d www.example.com"

mkdir -p "${DIR}" && \
${LETSENCRYPT} certonly \
    --agree-tos --renew -a webroot --webroot-path "${DIR}" \
    --server https://acme-v01.api.letsencrypt.org/directory ${DOMAINS} && \
service nginx reload

J'associe ce script avec un fichier de configuration nginx que j'ai appelé letsencrypt.conf, dont voici le contenu :

location '/.well-known/acme-challenge' {
    default_type "text/plain";
    root /tmp/letsencrypt-auto;
}

Enfin, j'inclus ce fichier de configuration à l'aide d'un include 'letsencrypt.conf'; dans la configuration de chacun de mes vhosts.

J'ai pu vérifier que ce script renouvelle bien le certificat pour x0r.fr avec comme nom alternatif www.x0r.fr.

Lorsqu'on a plusieurs sites Web sur la même machine, il faudra lancer ce script plusieurs fois (une fois par site) afin de générer des certificats (et donc des clés privées) différents par site.

Place au test

Après avoir mis en place les certificats et adapté ma configuration nginx, mon site réussit haut la main le test SSL de SSL Labs. Il ne reste plus qu'à mettre en place HSTS pour avoir la note A+.

Résultat du test
 de SSL Labs
Enfin ! Ça fait du bien d'avoir une note autre que « T » sur ce test.

Conclusion

L'approche de Let's Encrypt tranche radicalement avec les habitudes des autres autorités de certification SSL que j'ai pu connaître. Le fait qu'il s'agisse d'un système entièrement automatisé, la faible durée de vie des certificats, la gratuité et le fait que l'autorité de certification soit reconnue dans la plupart des navigateurs en font quelque chose d'unique.

Let's Encrypt n'aurait à mon avis pas pu exister sans le contexte des écoutes en masse par la NSA qui ont été révélées par Edward Snowden, ni sans les problématiques du respect de la vie privée ou de la neutralité des réseaux. Il s'agissait là de donner la possibilité à n'importe qui de déployer du HTTPS facilement. Ce pari me semble bien parti pour être réussi.

Posté par x0r à 7 commentaires • Tags : linux nginx letsencrypt https ssl

Commentaires

Poster un commentaire

#1 — McBuzz

Bonjour, Je m'étais intéressé à la certification SSL pour mon site Web, à l'époque je m'étais tourné du côté de Comodo security qui proposé du SSL pour pas cher (ce qui n'est plus vraiment le cas) mais leur certificat n'était reconnu par presque aucun navigateur. Concrètement quelle démarche faut-il entamer pour accéder à la Beta de Let's Encrypt, ou ne vaut-il pas mieux attendre une première version ouverte ?

Cordialement.

#2 — x0r

À une époque il était possible de s'inscrire pour avoir un accès à la béta fermée, mais je ne trouve plus le lien. Cependant, ils annoncent une béta ouverte pour le 3 décembre, donc au pire il suffira d'attendre un peu.

#3 — John

Merci pour l'article, j'ai néanmoins 2 questions : Quelles informations personnelles sont (vont être) demandées pour pouvoir se voir délivrer un certificat letsencrypt ? va-t-il y avoir une sélection particulière ou tout quidam sera automatiquement accepté ?

Concernant votre interrogation "J'ignore cependant comment letsencrypt fonctionne lorsqu'on a deux domaines [...] faut-il lancer letsencrypt une fois par domaine ou une fois pour tous les domaines ?", ce n'est pas le rôle du paramètre "DOMAINS" de votre script ? On ne peut pas spécifier tous les domaines en un seul coup ?

#4 — x0r

Apparemment, tout ce qu'ils demandent, c'est une adresse e-mail.

La variable DOMAINS dans mon script sert à donner une liste des domaines à mettre dans le même certificat. Par exemple "x0r.fr" et "www.x0r.fr". Je préfère utiliser un certificat par site Web, au lieu de mettre tout dans un seul certificat : ça reviendrait à utiliser une seule clé privée pour plusieurs sites, ce qui est à mon avis une mauvaise idée.

De ce que j'ai fini par comprendre, il faudra lancer plusieurs fois le script (une fois par site) lorsqu'on héberge plusieurs sites sur la même machine.

#6 — Gilles

Bonjour, Une nouvelle version du script (0.4.2 si j'ai bien vu) est disponible. Si on ne précise rien au travers d'option, le script propose désormais les choix par des dialogues : choix des hôtes virtuels, forçage du https.

#7 — Claude

Bonjour a tous, Cela a l'air plus facile avec Let's Encrypt Il faut savoir que dans la nouvelle DSM 6 des serveurs Synology il y a maintenant la possibilité d'obtenir un certificat avec Let's Encrypt Claude

Poster un commentaire