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:

Commande tree dans le répertoire courant

Les deux fichiers — que je renommerai — à transférer sur le serveur web sont:

  • live/privkey.pem comme SSLCertificateKeyFile et
  • live/fullchain.pem comme SSLCertificateFile

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.


  1. 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