Mise en place de HTTPS sur Apache avec Let's Encrypt
Articles techniques –Le HTTPS est aujourd'hui très utilisé sur Internet, notamment sur les sites « sensibles », mais pas seulement : son usage se généralise aujourd'hui à tous types de sites. (dont le mien :p )
C'est une très bonne chose, car si le HTTPS sert surtout à chiffrer les communications entre un site et vous pour les rendre illisibles (on ne pourra pas lire les mots de passe que vous envoyez, par exemple), ce n'est pas sa seule fonction : il permet par exemple aussi de s'assurer de l'authenticité d'un site (c'est-à-dire vérifier que le site est bien celui-là et pas un frauduleux qui se fait passer pour lui)
Pour fonctionner, le HTTPS se base sur des certificats : pour faire très simple, ils permettent de signer l'échange entre deux parties afin de garantir la sécurité de la communication. Le protocole qui définit les règles pour tout cela s'appelle TLS (anciennement SSL).
(Si vous désirez en apprendre beaucoup plus, je vous renvoie vers cet article qui explique précisément son fonctionnement)
Les certificats sont délivrés par des autorités de certifications. Obtenir un certificat pour son site n'a cependant pas toujours été très facile, car ils sont en général coûteux (quelques centaines d'euros par an) et les démarches sont parfois complexes.
Il y a quelques temps, une nouvelle autorité de certification est apparue : nommée Let's Encrypt, elle a la particularité de délivrer des certificats gratuitement sur demande, qui sont voués à être reconnus partout.
Soutenue par de grands noms (Mozilla, EFF, Cisco), elle est aujourd'hui beaucoup utilisée sur les petits et moyens sites, et a permis une démocratisation du HTTPS. C'est donc celle-là que nous allons utiliser :)
Pour obtenir des certificats de Let's Encrypt, il existe plusieurs manières : certbot, acme-tiny... Nous allons, de notre côté, utiliser le script « acme.sh » qui est facile d'utilisation et bien fourni.
Installation de acme.sh
Le script s'installera dans le /home de l'utilisateur actuel (dans mon cas, il sera installé dans /home/ailothaen/.acme.sh/* ). Je recommande de passer en root pour éviter d'éventuels problèmes de permission pendant que l'on va taper les commandes.
La procédure d'installation est très simple, il suffit juste de télécharger le script et de l'exécuter, ce qui lancera son installation :
root@ailoserv:~ # curl https://get.acme.sh | sh
Si vous n'avez pas curl (probable sur certains systèmes minimalistes) la commande classique wget marche aussi :
root@ailoserv:~ # wget -O - https://get.acme.sh | sh
Une fois que tout cela est installé, nous avons donc dans notre dossier le script (que l'on va utiliser), ainsi que d'autres fichiers utiles.
root@ailoserv:~ # ls .acme.sh
account.conf acme.sh acme.sh.env deploy dnsapi
Vous pouvez déplacer le dossier si vous voulez le placer dans un dossier plus approprié. Pour ma part, je mets les scripts dans /etc/scripts, donc je l'ai placé dans /etc/scripts/acme.sh/*
Générer un certificat
Comme le dit le readme du projet, il y a plusieurs méthodes pour générer des certificats : chacune a ses avantages et inconvénients. Comme nous avons un serveur Apache, nous allons utiliser l'option --apache pour interagir avec le serveur Apache, et ainsi éviter d'écrire des fichiers un peu partout (l'option par défaut doit en effet écrire des dossiers à la racine du site web)
La commande pour générer notre certificat est la suivante :
root@ailoserv:/etc/scripts/acme.sh # ./acme.sh --issue --apache -d ailothaen.fr -k 4096
où l'option -d est le nom de domaine du site, et où -k est le nombre de bits pour la clé RSA. (Aujourd'hui, les tailles généralement utilisées sont 2048, 3072 et 4096. Plus le nombre est élevé, plus la sécurité est élevée mais plus les échanges en seront ralentis. À savoir que l'ANSSI déconseille aujourd'hui l'usage du 2048 bits et conseille au moins du 3072.)
Il est possible de spécifier plusieurs noms de domaine en mettant plusieurs options -d à la suite. Cependant, à l'heure actuelle, Let's Encrypt ne supporte pas les wildcards (impossible donc de demander un seul certificat pour tous les *.exemple.fr...) (Mise à jour : c'est maintenant possible, mais la procédure est différente de celle expliquée dans cet article)
Notre certificat est donc généré, mais pour l'instant il se situe dans les dossiers de acme.sh. Pour le déplacer dans un dossier approprié (j'ai pour ma part fait un dossier /etc/apache2/sslcerts pour stocker les certificats, et chaque site a son dossier), il faut taper cette commande :
root@ailoserv:/etc/scripts/acme.sh # ./acme.sh --installcert -d ailothaen.fr --certpath /etc/apache2/sslcerts/ailothaen.fr/cert.pem --keypath /etc/apache2/sslcerts/ailothaen.fr/key.pem --fullchainpath /etc/apache2/sslcerts/ailothaen.fr/fullchain.pem --reloadcmd "service apache2 reload"
Trois fichiers seront dans notre répertoire :
- cert.pem est le certificat ;
- key.pem est la clé privée ;
- fullchain.pem est un fichier qui inclut le certificat et la chaîne complète des autorités de certification.
Une petite précision sur ce dernier point : une autorité de certification, comme nous l'avons dit, sert à générer des certificats qui prouvent que le site avec lequel vous tentez de communiquer est bien le bon (cela évite les attaques de l'homme du milieu).
Mais l'autorité de certification peut également se faire compromettre : elle se fait donc à son tour approuver par une «grande » autorité de certification, appellée autorité racine.
Let's Encrypt étant une autorité relativement récente, son certificat n'est pas très répandu, et tous les navigateurs ne la connaissent pas. Par conséquent, si un navigateur qui ne connaît pas Let's Encrypt reçoit un certificat de Let's Encrypt, il ne lui fera pas confiance.
Il est cependant possible de fournir le certificat de Let's Encrypt et le certificat de son autorité racine (qui est largement reconnu partout) afin d'éviter ce genre de problème et d'avoir un certificat plus organisé. C'est ce que nous allons faire.
Activer le certificat dans son site
La configuration de HTTPS sur son site se fait au niveau du fichier de configuration du site, qui sur Debian se trouve dans /etc/apache2/sites-available
Le fichier de notre site devrait ressembler à ça :
<VirtualHost *:80>
ServerName ailothaen.fr
(autres directives...)
</VirtualHost>
Le port standard pour HTTPS étant le 443, il faut faire un copier/coller du bloc, où l'on mettra en plus les directives relatives au HTTPS. (C'est la seule chose qui changera).
N'oubliez pas de vérifier dans votre config Apache globale que Apache écoute bien sur le port 443 (normalement c'est déjà le cas)
<VirtualHost *:80>
ServerName ailothaen.fr
(autres directives...)
</VirtualHost>
<VirtualHost *:443>
ServerName ailothaen.fr
(autres directives...)
SSLEngine on
SSLCertificateFile /etc/apache2/sslcerts/ailothaen.fr/fullchain.pem
SSLCertificateKeyFile /etc/apache2/sslcerts/ailothaen.fr/key.pem
</VirtualHost>
Pour la directive SSLCertificateFile, nous écrivons ici le chemin complet (ou relatif, mais je ne vous le conseille pas) vers notre fichier qui contient la chaîne complète de certification. Quant à SSLCertificateKeyFile, nous précisons le fichier qui contient notre clé privée.
Le même bloc de configuration doit donc être répété deux fois, une fois pour la version HTTP et une autre pour la version HTTPS. Cependant, sachez qu'il est possible de faire des includes dans les fichiers de configuration : on peut inclure dans les deux blocs un fichier général qui contient toutes les directives non relatives à HTTPS, afin d'éviter de les dupliquer.
Faites un petit
root@ailoserv:/etc/apache2/sites-available # service apache2 reload
et normalement, c'est bon : votre site devrait maintenant implémenter HTTPS !
Il est possible de voir les détails de son certificat. On retrouve ici la chaîne de certification :
Automatiser le renouvellement du certificat
Le certificat que nous venons d'installer sera valide pour une durée de trois mois. Passé ce délai, il ne sera plus valide, et la connexion ne sera plus considérée comme sécurisée.
Nous allons donc faire un petit script qui s'exécutera tous les deux mois et qui lancera automatiquement les commandes pour le renouvellement des certificats.
Voilà le script que j'ai personnellement fait :
#!/bin/bash
# Renouvellement automatique des certificats ssl
# Doit être appellé avec un argument $1 (qui est le nom de domaine)
/bin/sh ./acme.sh/acme.sh --issue --apache -d $1 -k 4096 --force
/bin/sh ./acme.sh/acme.sh --installcert -d $1 \
--certpath /etc/apache2/sslcerts/$1/cert.pem \
--keypath /etc/apache2/sslcerts/$1/key.pem \
--fullchainpath /etc/apache2/sslcerts/$1/fullchain.pem \
--reloadcmd "service apache2 reload"
La variable $1 est le nom de domaine du site. Comme nous pouvons le voir, ce script exécute les commandes que nous avons tapées plus tôt...
L'option --force permet de générer le certificat même si le précédent n'est pas expiré (ce qui sera toujours le cas). Il remplacera le certificat actuel.
Une fois que le script a été écrit et placé au bon endroit, nous allons ajouter une tâche CRON (en tant que root) pour l'exécuter tous les deux mois :
30 0 1 2,4,6,8,10,12 * bash /etc/scripts/sslrenew.sh ailothaen.fr
Pour cet exemple, le script s'exécutera à 00:30 tous les 1er février, avril, juin...
Pour aller plus loin
Et voilà ! HTTPS est maintenant utilisable sur votre site et est « maintenu » automatiquement. Vous pouvez tester la « qualité » de votre connexion HTTPS sur ces deux sites : (1) (2).
Si je parle de cela, c'est car le petit cadenas vert que l'on peut voir, et qui témoigne que la connexion est sécurisée, n'est que la surface de l'iceberg : HTTPS fonctionne sur des algorithmes et protocoles cryptographiques qui évoluent avec le temps. Des algorithmes de chiffrement sont fréquemment cassés et connaissent des failles.
Par conséquent, il faudra vérifier de temps en temps sur un site ci-dessus que vos connexions HTTPS sont toujours de bonne qualité et non vulnérables aux récentes failles. Si vous obtenez une mauvaise note, il vous faudra sûrement mettre à jour votre serveur web et/ou modifier ses configurations afin de retirer ce qui peut causer des problèmes. (N'hésitez pas à regarder cet article dont j'ai déjà mis le lien plus haut pour en savoir plus)
aucun commentaire