Publié par
Il y a 1 année · 10 minutes · Back

Vers un Web HTTPS avec Let’s Encrypt

lets encrypt-xebiaLet’s Encrypt est un projet jeune et très dynamique. Ces derniers mois ont été l’occasion pour les équipes d’annoncer plusieurs avancées dont notamment :

  • le support par les navigateurs grâce à la signature croisée avec IdenTrust ;
  • l’ouverture de la bêta publique en décembre dernier.

Nous vous proposons un tour d’horizon de ce projet qui permet de gérer vos certificats SSL de manière simple, automatique et sans frais.

Naissance du projet

L’annonce de ce projet remonte au 18 novembre 2014 par l’ISRG (Internet Security Research Group), un regroupement formé par plusieurs grands noms de l’IT (Mozilla, Akamai, Cisco, l’université du Michigan et Electronic Frontier Foundation).

Let’s Encrypt est né du constat que de plus en plus de données personnelles circulent sur le Web. Par ailleurs, la mise en place et la maintenance d’un certificat HTTPS sont rarement triviales et nécessitent dans l’immense majorité des cas un moyen de paiement.

Grâce à un agent sur les serveurs et au protocole ACME sous-jacent, Let’s Encrypt veut s’affranchir de toutes ces difficultés pour acquérir et installer un certificat signé, reconnu par les navigateurs, avec le minimum d’intervention humaine. Son leitmotiv  :

No validation emails, no complicated configuration editing, no expired certificates breaking your website. And of course, because Let’s Encrypt provides certificates for free, no need to arrange payment.

En octobre 2015 – prérequis nécessaire à la phase bêta – un accord a été signé avec l’autorité de certification IdenTrust, permettant aux certificats ainsi générés d’être reconnus par pratiquement tous les navigateurs existants. Que l’on parle de Chrome, Firefox, Internet Explorer, Opera, Safari ou Edge, le petit cadenas vert apparaît dans la barre d’adresses.

En théorie

Pour honorer la promesse du tout automatique, l’ISRG a imaginé le protocole ACME (Automatic Certificate Management Environment). Il permet d’automatiser les interactions entre l’autorité de certification et l’agent présent sur les serveurs. Pour cela il est basé sur des messages JSON transitant sur du HTTPS. L’autorité de certification répondant au protocole ACME est implémentée en Go via le programme boulder et l’agent letsencrypt est une implémentation en Python.

Le processus de gestion d’un certificat se déroule en deux étapes :

1 – L’agent doit préciser à l’autorité de certification que sa demande est légitime en prouvant qu’il contrôle le domaine en question.

2 – L’agent forge la requête d’administration souhaitée sur le certificat (obtention, renouvellement, révocation).

Validation du domaine

Le serveur web est identifié par une clé publique qui est générée au premier lancement de l’agent. Pour initier le processus, l’agent demande à l’autorité les informations dont elle a besoin pour lui prouver que sa demande est légitime, c’est à dire qu’il contrôle bien le nom de domaine. L’autorité de certification de Let’s Encrypt propose alors un challenge que l’agent doit accomplir pour prouver sa bonne foi. Ce challenge consiste à servir une ressource dont le contenu et l’emplacement sont communiqués par l’autorité dans la réponse. Avec ce challenge, Let’s Encrypt fourni un token que l’agent doit signer avec sa clé privée pour justifier qu’il contrôle également la paire de clés.


Image issue du site letsencrypt.org

Sur le schéma, l’agent indique à l’autorité qu’il souhaite manager le domaine example.com. L’autorité lui répond qu’il doit placer le contenu ed98 à l’emplacement https://example.com/8303 et signer le token 9cf0b331 avec sa clé privée.

Quand les conditions du challenge ont été remplies par l’agent, l’autorité vérifie la signature du token. Si la clé publique qu’elle connait permet de déchiffrer, alors cela signifie que l’agent possède bien la clé privée. L’étape suivante consiste à télécharger le fichier à l’emplacement préalablement communiqué. Si toutes les comparaisons sont positives alors la paire de clés de l’agent est autorisée à envoyer des ordres pour le domaine en question.

Délivrance et révocation

Une fois que l’agent a montré patte blanche, la création, le renouvellement ou la révocation de certificats consiste à envoyer un message signé à l’autorité de certification.

Lors de la création, l’agent forge une Demande de Signature de Certificat (CSR) au format PKCS#10 qui contient les informations relatives au demandeur ainsi que la clé publique du certificat. Les certificats émis par Let’s Encrypt étant des Domain Validation (DV), seuls les attributs Common Name (CN) et email sont renseignés. La CSR est ensuite signée par la clé privée correspondant à la clé publique de la CSR. Pour prouver que l’autorité accepte la demande, la CSR doit être également signée avec la clé privée de l’agent.

Image issue du site letsencrypt.org

La révocation fonctionne de manière similaire, l’agent fabrique et signe la requête avec sa clé privée. Suite aux vérifications idoines, l’autorité publie la révocation dans les canaux traditionnels (CRL, OCSP) pour avertir les clients (ex: les navigateurs) de ne plus accepter le certificat.

En pratique

Let’s Encrypt étant en phase bêta, toutes les fonctionnalités ne sont pas encore opérationnelles. Mais l’outil permet d’ores et déjà de se faire une idée en générant des certificats parfaitement valides. Nous vous proposons une configuration simple, à savoir un NGINX servant un site en HTTPS utilisant un certificat Let’s Encrypt.

Installation de l’agent

La commande letsencrypt est une implémentation en Python. Elle automatise les tâches de manipulation des certificats et de configuration des serveurs. Ce script est présent dans les gestionnaires de paquets des distributions Debian (testing et sid), Arch Linux, FreeBSD et OpenBSD. Pour les environnements ne disposant pas encore du package natif, l’installation s’effectue en clonant le repository Git et en lançant le wrapper letsencrypt-auto qui installe les dépendances nécessaires et créé un environnement virtuel Python. De par sa nature de wrapper, il accepte exactement les mêmes options et arguments que la commande letsencrypt qu’il encapsule.

Pour Debian Jessie par exemple, les paquets python python-dev virtualenv gcc dialog libaugeas0 libssl-dev libffi-dev ca-certificates seront provisionnés lors du premier lancement de letsencrypt-auto.

Distribution supportée (Debian Testing)

 L’installation est très simple car le paquet est présent dans les dépôts officiels. En général, une seule commande suffit.

 apt-get install letsencrypt

Distribution non supportée (Debian Jessie)

Dans le cas ou le paquet n’existe pas pour votre distribution, quelques opérations supplémentaires sont nécessaires mais la démarche reste néanmoins très simple et efficace. Après s’être assuré d’installer Git, il faudra cloner le dépôt git de Lets’Encrypt pour obtenir l’agent.

apt-get install git
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

Création du certificat

Maintenant que l’agent est installé sur le serveur, il ne reste plus qu’à créer le certificat pour le nom de domaine. Plusieurs plugins sont à votre disposition :

  • apache/2.x : obtention du certificat et configuration d’Apache2.

  • standalone : lance sont propre serveur HTTP pour prouver la gouvernance du domaine.

  • webroot ajoute les fichiers du challenge à la racine du serveur web existant pour prouver la gouvernance du domaine.

  • manuel : fourni les commandes à exécuter pour valider le domaine afin d’obtenir le certificat.

  • nginx/0.8.48+ : obtention du certificat et configuration de Nginx (expérimental).

Nous allons obtenir le certificat avec le plugin standalone. Il lance un serveur web écoutant sur le port 80 ou 443 afin que l’autorité de certification puisse récupérer le fichier de challenge. Ce mode est à combiner avec certonly qui permet d’obtenir le certificat sans l’installer.

./letsencrypt-auto certonly --standalone --standalone-supported-challenges http-01 --agree-tos --email letsencrypt@xebia.fr -d domain1 

Explications :

  • --standalone : utilisation du plugin standalone pour lancer un serveur http dédié.
  • --standalone-supported-challenges http-01 : utilisation du port 80 pour communiquer avec la CA.
  • --agree-tos : acceptation des Subscriber Agreement. Sans cette option une invite ncurses s’ouvre invitant l’utilisateur à accepter les conditions d’utilisation.
  • --email : adresse email pour les communications. Un email est envoyé lorsque la date d’expiration approche par exemple.
  • -d domain1 : domaine du certificat (l’argument peut être présent plusieurs fois pour générer un certificat SAN).

Attention car ce mode est incompatible si vous avez déjà un serveur web qui tourne sur votre production car il y a de grandes chances que les ports 80 ou 443 soient utilisés par ce dernier. Dans notre cas nous l’avons utilisé avant d’ouvrir le site au public. La commande letsencrypt indique qu’il est possible de modifier le port avec l’argument --http-01-port $PORT, mais cela n’a pas fonctionné dans notre cas.

Récupération du certificat

La commande précédente produit la sortie suivante :

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

Les fichiers générés se situe dans le dossier /etc/letsencrypt/live/$DOMAIN/. Deux fichiers en particulier sont nécessaires à la mise en place du NGINX :

  • privkey.pem : la clé privée à renseigner dans la directive ssl_certificate_key
  • fullchain.pem : toute la chaîne de certificat incluant celui du serveur correspondant à la directive ssl_certificate.

On peut voir également que la durée de validité des certificats produits est de 90 jours soit 3 mois. Comparé aux autres autorités de certification, cette durée est assez faible mais pousse à automatiser le processus de renouvellement, ce que prône Lets’ Encrypt en fournissant ses outils.

NGINX

La configuration du NGINX est réduite à son stricte minimum afin de se concentrer uniquement sur  la partie Let’s Encrypt.

server {

       listen 80;
       listen 443 ssl;
       server_name domain1;

       ssl_certificate /etc/letsencrypt/live/domain1/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/domain1/privkey.pem;

       root /var/www/html;
       index index.html;
} 

Le serveur est configuré pour servir le site en HTTP et en HTTPS. Les fichiers liés à la sécurité (clé privée et certificat) sont lus dans le dossier de sortie de Let’s Encrypt.

Renouvellement du certificat

Pour le renouvellement, nous allons utiliser le plugin webroot afin d’utiliser notre serveur nginx préalablement configuré. Là encore, l’opération s’effectue simplement grâce à l’agent.

./letsencrypt-auto certonly --webroot -w /var/www/html/ --agree-tos --email letsencrypt@xebia.fr --renew-by-default -d domain1

Il ne reste plus qu’à recharger la configuration pour prendre en compte le nouveau certificat.

/etc/init.d/nginx reload

Périmètre et limites

La limite à laquelle vous allez être confronté en premier lieu est la durée de validité des certificats. Cette dernière de 90 jours est un choix délibéré et assumé. L’article « Why ninety-day lifetimes for certificates? » expose les arguments. En synthèse, cela permet de limiter les dommages causés par la compromission de la clé ou la mauvaise émission de certificats. De plus, dans l’idéal d’un Web HTTPS, il n’est pas envisageable de reposer sur une action humaine pour renouveler les certificats. Cette durée force donc à automatiser la procédure et ainsi à limiter les erreurs.

Parmi les trois types de certificats HTTPS, Let’s Encrypt ne gère que les certificats de type validation de domaine (DV). Pour obtenir un certificat à validation d’organisation (OV) ou à validation étendue (EV), il faudra vous tourner vers une autre autorité de certification.

Les certificats omnidomaines (wildcard) ne sont pour le moment pas supportés car comme indiqué dans ce commentaire, la validation automatique de domaine pour les wildcard n’est pas dans la spécification ACME du fait de la complexité inhérente au problème. Néanmoins, Let’s Encrypt supporte parfaitement les certificats SAN dans lequel vous pouvez glisser jusqu’à 100 sous domaines .

Le projet n’est pas encore fini, certaines fonctionnalités manquent comme la configuration automatique de Nginx, mais nous avons vu que moyennant quelques lignes de configuration il est facile de sécuriser son serveur. Le système de plugins permettra dans le futur de supporter nouvelles fonctionnalités ainsi que nouveaux serveurs.

2 réflexions au sujet de « Vers un Web HTTPS avec Let’s Encrypt »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *