Une manière de mettre en place un certificat Letsencrypt avec Certbot sans les privilèges de root
La rédaction de ce billet a débuté en mai 2017… j'ai un peu trainé.
C'est dans l'air du temps de passer du web (world wide web) non chiffré au
web chiffré. Pour passer de http
à https
, il faut mettre en place un
échange de clés cryptographiques entre le client (le navigateur) et le serveur
(le site web visité). Cet échange de clé doit être certifié par une autorité
de… certification (voir Wikipedia pour les détails).
Pour vérifier que les intervenants sont bien qui ils prétendent être, l'autorité de certification fait certaines vérifications. Les plus élémentaires sont de voir si le demandeur à accès, au choix, à l'hébergement web, aux mails ou à la zone DNS.
Cette vérification à un coût. La vérification la plus simple coûte ±12€/an et
peut aller jusqu'à 200€ voire plus. Letsencrypt est
une société qui désire permettre à qui veut de mettre en place un certificat
ssl — son site en https
— gratuitement et simplement.
https à la portée de tous
La contrainte de letsencrypt est que le certificat doit être renouvelé tous les 90 jours alors que les certificats payants sont généralement valables au minimum 1 an. Ce n'est pas bien grave car le renouvellement peut être automatisé.
Quand j'ai commencé à rédiger ce billet, letsencrypt était moyennement connu. Aujourd'hui — presque un an plus tard parce que certains billets trainent — beaucoup d'hébergeurs proposent https directement grâce à letsencrypt. Même si l'on n'a plus aucune excuse pour ne pas proposer https, l'on peut quand même se poser la question de son utilité pour une page ne contenant aucun formulaire… mais c'est une autre histoire.
La force de letsencrypt — en plus du fait que ce soit gratuit — est de fournir un programme — officiel car il en existe plein d'autres — permettant d'automatiser le travail. Il est possible d'utiliser certbot et — en lui donnant les droits root — de lui demander de faire (quasi) tout le boulot. Voir ce tutorial par exemple. C'est très simple.
Si pour diverses raisons vous ne voulez pas lancer certbot en root ou utiliser d'autres outils comme getssl ou dehydrated, il est possible de faire autrement.
J'ai choisi de faire la demande de certificat sur ma machine locale et de tout mettre dans un même répertoire. Ensuite je copie les deux fichiers qui vont bien sur mon serveur. J'ai évidemment fait la configuration du serveur web — apache — manuellement.
C'est cette approche sans doute particulière que je présente ici.
Voici l'allure de la manipulation.
apt install certbot
Génération des certificats de manière manuelle et en utilisant la
vérification dns. Imaginons que je travaille dans le répertoire
~/elsewhere/ssl
. Je demande à certbot de tout mettre dans le répertoire
courant.
certbot certonly --manual \
--preferred-challenges dns \
-d elsewhere.example.org \
--config-dir . --logs-dir . --work-dir .
certbot me demande mon email et me demande de placer un enregistrement DNS dans la zone concernée. Je m'exécute.
_acme-challenge 10800 IN TXT "UPailéchalotte52xawazaa_Qu4HV81bkBim\
paf-Plop-I"
Dès que c'est fait, il me génère tout le merdier qui a l'allure suivante:
Les deux fichiers — que je renommerai — à transférer sur le serveur web sont:
live/privkey.pem
commeSSLCertificateKeyFile
etlive/fullchain.pem
commeSSLCertificateFile
J'ajoute une configuration apache à l'allure suivante:
ServerAdmin webmaster@elsewhere.example.org
ServeName elsewhere.example.org
DocumentRoot /var/www/html/elsewhere.example.org/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile
/etc/apache2/ssl/elsewhere.example.org.fullchain.pem
SSLCertificateKeyFile
/etc/apache2/ssl/elsewhere.example.org.privkey.pem
… et tout roule.
Il reste à prévoir le renouvellement du certificat lors de la réception du mail de letsencrypt. C'est mieux si ce renouvellement est un peu automatisé.
Comme la commande est lancée manuellement, pas de renew possible, il faut relancer la commande initiale. Nous allons l'adapter un peu pour notre facilité.
pour le nenouvellement, il est nécéssaire d'actualiser le challenge.
Dans notre cas, il faudrait adapter l'enregistrement dns ce qui nécessite une connexion chez l'hébergeur ou un client spécifique (exemple avec lexicon). Le challenge http demande qu'un fichier soit présent sur l'hébergement… ce qui peut être fait via scp. C'est plus facile et ça peut être automatisé.
certbot a un système de hooks qui peuvent être déclenchés avant la vérification et après.
Dès que letsencrypt nous communique notre challenge — que ce soit l'enregistrement dns à placer ou le fichier à déposer — c'est le hook qui se chargera de la faire.
J'ajoute deux scripts à l'allure suivante:
le premier sera exécuté avant et va donc déposer le challenge
$ cat before.sh #! /usr/bin/env bash echo $CERTBOT_VALIDATION > /tmp/$CERTBOT_TOKEN scp /tmp/$CERTBOT_TOKEN \ user@host.example.org:\ /var/www/elsewhere.example.org/.well-known/acme-challenge rm /tmp/$CERTBOT_TOKEN
le second ira déposer les certificats sur le serveur1
$ cat after.sh #! /usr/bin/env bash scp live/elsewhere.example.org/privkey.pem \ user@host.examble.org:/home/user/ssl/elsewhere.example.org.key.pem scp live/elsewhere.example.org/fullchain.pem \ user@host.examble.org: /home/user/ssl/elsewhere.example.org.fullchain.pem
Lors du renouvellement, j'entre alors une commande à l'allure suivante (le paramètre manual-public-logging-ok évite le prompt Y/N pour le log de l'IP et max-log-backups limite le nombre de logs à 3… au lieu de 1000):
certbot certonly --manual \
--preferred-challenges http \
-d elsewhere.example.org \
--config-dir . --logs-dir . --work-dir . \
--manual-public-ip-logging-ok \
--manual-auth-hook ../before.sh \
--manual-cleanup-hook ../after.sh \
--max-log-backups 3
… et tout est fait… presque car il faut encore faire un reload du serveur apache.
Cette méthode a ses défauts, elle permet de comprendre le fonctionnement de letsencrypt et de garder la main sur toute la chaine. C'est pédagogique ;-)
Enjoy !
Crédit photo chez Gratisography. Sérieux avec un grain de folie.
-
Si tu es attentif, tu vois que je ne copie pas dans
/etc/apache2
mais dans le home de l'utilisateur… les fichiers dans/etc/apache2
sont des liens softs. Ceci permet de ne pas se connecter en ssh (via scp) avec les droits root. ↩