Pour ceux qui ne connaissent pas, Let's Encrypt fourni, gratuitement, des certificats SSL reconnus par les navigateurs (une petite révolution).
Le SSL, qu'est-ce que c'est ? C'est un protocole permettant de sécuriser les échanges sur internet, que ce soit via les protocoles http, ftp ou encore pop (pour les e-mails). Ce protocole ne se nomme plus SSL (Secure Sockets Layer) mais TLS (Transport Layer Security) depuis 1999 (merci wikipedia ^^). Le protocole TLS est le successeur du protocole SSL (ce dernier n'étant plus utilisé) mais le terme SSL est resté.
Pour expliquer rapidement comment ça fonctionne, le SSL utilise une paire de clé (publique et privée) et une autorité de confiance :
La révolution amenée par Let's Encrypt est qu'il a été reconnu comme une autorité de confiance et que, contrairement aux autres autorités de confiance, il propose des certificats gratuitement.
Toutes les commandes indiquées doivent être lancées avec l'utilisateur root (ou avec sudo)
Tout d'abord on va activer le support ssl ainsi que le mode headers dont aura besoin.
a2enmod ssl headers
Maintenant que ça c'est fait, on va installer le client Certbot qui est utilisé pour générer les certificats SSL Let's Encrypt.
Il va nous falloir installer la version présente dans les dépôts backports de Debian. Pour ajouter ces dépôts, ouvrez le fichier
/etc/apt/sources.list
Ajoutez la ligne suivante au fichier
deb http://ftp.debian.org/debian bullseye-backports main
Mettez à jour les dépôts
aptitude update
On va maintenant pouvoir installer Certbot
aptitude install certbot -t bullseye-backports
Maintenant que nous avons tout ce qu’il nous faut, passons à la création.
Si vous avez besoin de créer un certificat wildcard (c’est-à-dire valide pour tous les sous-domaines également), passez au chapitre suivant.
Commencez par créer un fichier lets_encrypt.ini (vous pouvez le nommer comme vous voulez) et mettez-y les lignes suivantes dedans :
authenticator = standalone renew-by-default = True agree-tos=true email = postmaster@votredomaine.fr domains=www.domaine.fr,domaine.fr rsa-key-size = 4096
Ceci va être le fichier de config du client Certbot que l’on va lancer pour générer nos certificats SSL. Si vous vous demandez à quoi correspondent ces lignes :
Le client Certbot a besoin d'utiliser le port 80. Il vous faudra donc arrêter Apache le temps de l'opération.
On va donc commencer par couper Apache
systemctl stop apache2.service
Il ne reste plus qu’à générer notre certificat. Pensez à modifier l’emplacement du fichier ini si vous ne l’avez pas mis dans le home de l’utilisateur root
certbot certonly --config /root/lets_encrypt.ini
Les certificats vont être créés dans le répertoire
/etc/letsencrypt/live/domaine.fr/
Si tout c'est bien passé, vous devriez avoir le message suivant
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/www.domaine.fr/fullchain.pem. Your cert will expire on 2016-05-15. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Si vous allez dans le répertoire /etc/letsencrypt/live/domaine.fr/, vous trouverez 4 fichiers :
Let’s Encrypt permet également de générer des certificats wildcard. Les wildcard sont des certificats qui sont valables pour l’ensemble des sous-domaines.
Avec la méthode du chapitre précédent, il faut lister tous les sous-domaines lors de la création du certificat SSL. Du coup si on crée un nouveau sous-domaine 3 jours après avoir généré le certificat SSL il faut le regénérer en incluant le nouveau sous-domaine. Avec les certificats wildcard, plus besoin.
Pour vérifier que le nom de domaine pour lequel vous souhaitez générer un certificat vous appartient, Let’s Encrypt propose 2 types de challenges :
Dans le chapitre précédent, on a utilisé le challenge http-01, le plus simple à mettre en place. Mais pour les certificats wildcard, seul le challenge dns-01 est accepté. Je ne traiterai dans ce chapitre que le cas du serveur DNS auto-hébergé, dans mon cas Bind. Certbot possède d’autres plugins permettant de compléter le challenge dns-01 dans le cas où votre dns est géré par ovh, ghandi, etc, mais je ne les ai jamais testés.
Il faut donc impérativement que vous ayez suivi la page IP dynamique et DNS sur la mise en place de dns dynamique. Seuls les chapitres 1 et 2 de cet article, qui traitent de la création de la clé et de la configuration de Bind, sont indispensables. L’autre partie traite de la mise à jour de l’adresse ip, qui n’est pas utile pour les wildcard. Par contre, il ne vous faudra pas utiliser “update-policy”comme indiqué au début du chapitre 2, mais “allow-update” comme indiqué à la fin du chapitre 2 (que vous utilisiez ISPConfig ou non).
Il va également nous falloir installer un plugin pour mettre à jour notre zone DNS
aptitude install python3-certbot-dns-rfc2136
Créez un fichier ini, lets_encrypt.ini par exemple (vous pouvez l’appeler comme vous voulez). Voici ce qu’il doit y avoir dedans :
authenticator = dns-rfc2136 renew-by-default = True agree-tos=true email = toto@domaine.fr domains=domaine.fr,*.domaine.fr rsa-key-size = 4096 server = https://acme-v02.api.letsencrypt.org/directory dns-rfc2136-credentials = /root/dns.ini
Expliquons toutes ces lignes :
Et voici ce que doit contenir le fichier dns.ini (pareil, vous pouvez l’appeler comme vous voulez) :
# Target DNS server dns_rfc2136_server = IP du serveur DNS # Target DNS port dns_rfc2136_port = 53 # TSIG key name dns_rfc2136_name = nom de la clé # TSIG key secret dns_rfc2136_secret = contenu de la clé # TSIG key algorithm dns_rfc2136_algorithm = HMAC-SHA512
Si votre serveur DNS et votre serveur web (Apache ou Nginx) sont sur le même serveur, il vous faudra mettre 127.0.0.1 pour l’IP. Le nom de clé correspond au nom que vous avez donné à la clé dans le fichier named.conf.keys. Le contenu correspond au code secret de la clé. Si vous avez utilisé un algorithme autre que le HMAC-SHA512, pensez à modifier cette partie.
Comme ce fichier ini contient le code secret de la clé, chose assez sensible, on va modifier les droits de ce fichier
chmod 600 dns.ini
Comme j’ai mis la clé dans le home de l’utilisateur root, lui seul pourra lire ce fichier.
Il ne reste plus qu’à générer notre certificat. Pensez à modifier l’emplacement du fichier ini si vous ne l’avez pas mis dans le home de l’utilisateur root
certbot certonly --config /root/lets_encrypt.ini
Les certificats vont être créés dans le répertoire
/etc/letsencrypt/live/nomdedomaine/
Une chose à savoir, les certificats créés par certbot ne sont accessibles qu'à l'utilisateur root. Les programmes comme Apache2, Postfix, PureFTP, etc sont exécutés par l'utilisateur root et auront donc accès à ces certificats mais il y peut y avoir d'autres programmes exécuté par un autre utilisateur ayant besoin de ces certificats (Collabora Online par exemple). Le meilleur moyen de donner accès à ces programmes aux certficats est d'utiliser https://fr.wikipedia.org/wiki/Access_Control_List. Commencez par installer le paquet acl :
sudo aptitude install acl
Ensuite tapez les commandes suivantes (remplacez utilisateur par votre utilisateur devant accéder aux certificats et nomdedomaine.fr par votre nom de domaine) :
sudo setfacl -m u:utilisateur:rX /etc/letsencrypt/{live,archive} sudo setfacl -R -m u:utilisateur:rX /etc/letsencrypt/{live,archive}/nomdedomaine.fr
La première commande donne accès à l'utilisateur “utilisateur” aux répertoires /etc/letsencrypt/live/ et /etc/letsencrypt/archive mais pas à leurs sous-dossiers. La seconde commande donne accès à l'utilisateur “utilisateur” aux fichiers se trouvant dans les répertoire /etc/letsencrypt/live/nomdedomaine.fr et /etc/letsencrypt/archive/nomdedomaine.fr.
L'attribution des droits se fait en 2 fois car vous pouvez avoir les certificats de plusieurs noms de domaine dans vos dossiers live et archive mais ne vouloir donner l'accès qu'à un en particulier. Cette modification des droits est perdue après un redémarrage, donc pensez à ajouter un cron pour relancer ces commandes à chaque démarrage.
Maintenant, il nous faut modifier les fichiers de config d'Apache pour intégrer le certificat SSL qui se trouve dans le répertoire /etc/letsencrypt/live/www.domaine.fr/.
Dans votre fichier de configuration Apache pour votre nom de domaine, ajoutez les lignes suivantes :
<VirtualHost *:443> ServerName domaine.fr ServerAlias www.domaine.fr DocumentRoot /var/www/domaine.fr ErrorLog /var/log/apache2/error.example.com.log CustomLog /var/log/apache2/access.example.com.log combined <Directory /var/www/domaine.fr> Options -Indexes +FollowSymLinks +MultiViews AllowOverride none Require all granted </Directory> SSLEngine on SSLCertificateFile /etc/letsencrypt/live/www.domaine.fr/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.domaine.fr/privkey.pem Header always set Strict-Transport-Security "max-age=15768000" </VirtualHost> # intermediate configuration SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off SSLSessionTickets off SSLUseStapling On SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
Petite explication rapide de ces lignes :
Il faut également que toutes les connexions http (port 80) soient redirigées vers https (port 443) car le HSTS ne fonctionne pas sur tous les navigateurs.
Dans votre fichier de configuration Apache2 il faut rajouter ces lignes après <VirtualHost *:80> :
Redirect / https://domaine.fr/
Redémarrez Apache et c'est tout bon.
Si jamais vous utilisez plusieurs fichiers de configurations, c'est mon cas vu que j'ai pas mal de sous-domaines, il peut être plus simple de rentrer les paramètres SSL dans le fichier de configuration SSL d'Apache2. Ça permet d'appliquer ces options à tous les fichiers de configuration ayant le SSL d'activé.
Ouvrez le fichier de configuration SSL :
sudo nano /etc/apache2/mods-enabled/ssl.conf
Les configurations indiquées dans ce fichier seront appliquées à tous les vhosts. Avant la balise “IfModule”, ajoutez les lignes suivantes :
# intermediate configuration SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off SSLSessionTickets off SSLUseStapling On SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" # HTTP Strict Transport Security (mod_headers is required) (63072000 seconds) Header always set Strict-Transport-Security "max-age=63072000"
On redémarre Apache :
sudo systemctl restart apache2
Il existe un site qui teste et note les connexions SSL. C'est https://www.ssllabs.com/ssltest/index.html. Avec ce qu'on a modifié, vous devriez avoir A+ en note.
Les certificats Let’s Encrypt étant valable 3 mois, c’est vite chiant de devoir les renouveler à la main tous les 3 mois. On va donc voir comment automatiser tout ça.
Créez un fichier script_letsencrypt.sh (vous pouvez le nommer comme vous voulez).
Si vous utilisez un certificat standard (pas de wildcard), collez les lignes suivantes dedans (pensez à modifier le chemin des différents fichiers)
#!/bin/sh #Vérification de l'expiration du certificat SSL de domaine.fr" if ! openssl x509 -checkend 86400 -in /etc/letsencrypt/live/www.domaine.fr/fullchain.pem; #Si le certificat expire d'ici 24h (86400 secondes) then systemctl stop apache2.service certbot certonly --config /root/lets_encrypt.ini systemctl start apache2.service fi
Si vous utilisez un certificat wildcard, collez les lignes suivantes (pensez à modifier le chemin des différents fichiers)
#!/bin/sh #Vérification de l'expiration du certificat SSL de domaine.fr" if ! openssl x509 -checkend 86400 -in /etc/letsencrypt/live/www.domaine.fr/fullchain.pem; #Si le certificat expire d'ici 24h (86400 secondes) then certbot certonly --config /root/lets_encrypt.ini systemctl restart apache2.service rm /etc/bind/pri.domaine.fr*jnl systemctl restart bind9 fi
Petite explication sur ce script :
systemctl stop apache2.service
certbot certonly --config /root/lets_encrypt.ini
systemctl start apache2.service
ou
systemctl restart apache2.service
rm /etc/bind/pri.domaine.fr*jnl systemctl restart bind9
Pensez à rendre ce fichier exécutable
chmod +x /root/script_letsencrypt.sh
Il ne nous reste plus qu’à lancer ce script tous les jours via le crontab de l’utilisateur root.
Editez le crontab du root
crontab -e
Ajoutez la ligne suivante
00 01 * * * /root/script_letsencrypt.sh >> /var/log/lets-encrypt.log
Il vous faudra là aussi modifier le répertoire d’accès au script.
Le script sera lancé tous les jours à 1h du matin par l’utilisateur root et votre certificat sera renouvelé automatiquement 24h avant son expiration. Les sorties seront stockées dans le fichier /var/log/lets-encrypt.sh, ce qui vous permettra de voir si des erreurs surviennent.