Génération des certificats Let's Encrypt par challenge DNS avec le client acme.sh

Voici une méthode afin de générer des certificats Let's Encrypt par challenge DNS avec le client acme.sh grâce à l'API Gandi LiveDNS.

L'avantage de ce client, c'est qu'il :

  • est maintenu par la communauté sur GitHub
  • supporte à ce jour plus de 25 API tels que celles de Gandi LiveDNS et OVH pour ne citer qu'eux
  • ne possède aucune dépendance
  • est très portable
  • s'installe très proprement, à comprendre qu'il ne pourrit pas le système

Le client acme.sh permet donc lors de la génération des certificats de s'interfacer avec Gandi LiveDNS et ça tombe bien, mon domaine est enregistré chez Gandi.

Pour les autres registars, il suffira d'adapter légèrement ce guide et vous devriez trouver l'aide nécessaire sur le wiki acme.sh.

Dans ce guide, je prendrais pour exemple :

  • Un domaine domain.tld
  • Des sous-domaines sub1.domain.tld et sub2.domain.tld
  • Une clé API Gandi LiveDNS HaBP4Bht2zdtR9bKDKvoJdP2

On peut commencer à attaquer.

  1. Pré-requis
  2. Installation du client acme.sh
  3. Génération des certificats
  4. Installation des certificats
  5. Mise en place du renouvellement automatique
  6. Références et remerciements

1. Pré-requis

  • Un domaine chez Gandi
  • Générer une clé API si ce n'est pas déjà fait sur https://account.gandi.net/fr/ dans l'onglet Sécurité
  • Le client acme.sh (que l'on va installer dans ce guide)

2. Installation du client acme.sh

L'installation de base va mettre en place une tâche cron qui se lancera tous les jours et renouvellera les certificats 30 jours avant expiration, ce qui ne me plait pas, je vais donc spécifier le paramètre --nocron et mettrais en place une tâche manuellement dans la suite du guide.

L'argument --nocron est donc facultatif et si vous souhaitez utiliser la tâche par défaut, ne le spécifiez pas.

Tout se déroule en root :

[root@serveur ?]# cd ~
[root@serveur ~]# wget https://github.com/Neilpang/acme.sh/archive/master.tar.gz
[root@serveur ~]# tar zxvf master.tar.gz
[root@serveur ~]# rm master.tar.gz
[root@serveur ~]# cd acme.sh-master/
[root@serveur acme.sh-master]# ./acme.sh --install --nocron
[root@serveur acme.sh-master]# cd ..
[root@serveur ~]# rm -rf acme.sh-master/

À ce stade, le client est installé dans /root/.acme.sh/ et nulle part ailleurs.

3. Génération des certificats

Vous devrez adapter les lignes ci-dessous :

[root@serveur ~]# export GANDI_LIVEDNS_KEY="HaBP4Bht2zdtR9bKDKvoJdP2"
[root@serveur ~]# ~/.acme.sh/acme.sh --dns dns_gandi_livedns --issue --keylength 4096 -d domain.tld -d sub1.domain.tld -d sub2.domain.tld

Cela devrait vous retourner à peu près ceci :

Registering account
Registered
Update success.
ACCOUNT_THUMBPRINT='YKbTJs87QDp76tGYVWzKXSTF8dir9A2xizMXa3wFLkn'
Creating domain key
The domain key is here: /root/.acme.sh/domain.tld/domain.tld.key
Multi domain='DNS:sub1.domain.tld,DNS:sub2.domain.tld'
Getting domain auth token for each domain
Getting webroot for domain='domain.tld'
Getting new-authz for domain='domain.tld'
The new-authz request is ok.
Getting webroot for domain='sub1.domain.tld'
Getting new-authz for domain='sub1.domain.tld'
The new-authz request is ok.
Getting webroot for domain='sub2.domain.tld'
Getting new-authz for domain='sub2.domain.tld'
The new-authz request is ok.
Found domain api file: /root/.acme.sh/dnsapi/dns_gandi_livedns.sh
Add success
Found domain api file: /root/.acme.sh/dnsapi/dns_gandi_livedns.sh
Add success
Found domain api file: /root/.acme.sh/dnsapi/dns_gandi_livedns.sh
Add success
Sleep 120 seconds for the txt records to take effect
Verifying:domain.tld
Success
Verifying:sub1.domain.tld
Success
Verifying:sub2.domain.tld
Success
Verify finished, start to sign.
Cert success.
Your cert is in  /root/.acme.sh/domain.tld/domain.tld.cer
Your cert key is in  /root/.acme.sh/domain.tld/domain.tld.key
The intermediate CA cert is in  /root/.acme.sh/domain.tld/ca.cer
And the full chain certs is there:  /root/.acme.sh/domain.tld/fullchain.cer

À noter que vous n'aurez plus à taper votre clé API car cette dernière est enregistrée dans /root/.acme.sh/account.conf.

4. Installation des certificats

Maintenant que les certificats sont générés, il faut les installer et encore une fois, n'oubliez pas d'adapter la commande :

[root@serveur ~]# ~/.acme.sh/acme.sh --installcert -d domain.tld --cert-file /etc/ssl/certs/domain.tld-cert.pem --key-file /etc/ssl/private/domain.tld-privkey.key --ca-file /etc/ssl/certs/domain.tld-chain.pem --fullchain-file /etc/ssl/certs/domain.tld-fullchain.pem

Cela devrait vous retourner ceci :

Installing cert to:/etc/ssl/certs/domain.tld-cert.pem
Installing CA to:/etc/ssl/certs/domain.tld-chain.pem
Installing key to:/etc/ssl/private/domain.tld-privkey.key
Installing full chain to:/etc/ssl/certs/domain.tld-fullchain.pem

5. Mise en place du renouvellement automatique

Cette partie est facultative si vous n'avez pas installer le client avec l'argument --nocron.

Le renouvellement automatique va consister en une tâche cron appelée chaque jour qui vérifiera si le certificat expire dans moins de 24h et qui dans ce cas effectuera les actions suivantes :

  • Mise à jour du client acme.sh
  • Renouvellement des certificats pour le ou les domaines en fonction du script utilisé
  • Redémarrage des services utilisant les certificats

N'oubliez pas d'adapter le chemin, le domaine, les services, vous pouvez aussi adapter le temps.

Création du script /etc/cron.d/acme.sh, vous pouvez utiliser un autre emplacement si vous le souhaitez :

#!/bin/sh

if ! openssl x509 -checkend 86400 -in /root/.acme.sh/domain.tld/domain.tld.cer 1> /dev/null
then
    /root/.acme.sh/acme.sh --upgrade
    /root/.acme.sh/acme.sh --renew -d domain.tld
    systemctl reload dovecot nginx postfix
fi

Si vous avez plusieurs domaines, on pourra imaginer un script comme celui-ci :

#!/bin/sh

for domains in domain.tld domain2.tld domain3.tld domain4.tld; do
    if [ -f /root/.acme.sh/$domains/$domains.cer ] && [ ! `openssl x509 -checkend 86400 -in /root/.acme.sh/$domains/$domains.cer 1> /dev/null` ]
    then
        if [ ! $temoin ]; then
            /root/.acme.sh/acme.sh --upgrade
        fi

        /root/.acme.sh/acme.sh --renew -d $domains
        temoin=1
    fi
done

if [ $temoin ]; then
    systemctl reload dovecot nginx postfix
fi

Attribution des permissions d'exécution sur le fichier /etc/cron.d/acme.sh :

[root@serveur ~]# chmod +x /etc/cron.d/acme.sh

Planification à 03h00 tous les jours en ajoutant la ligne suivante dans crontab -e :

0 3 * * * /etc/cron.d/acme.sh

6. Références et remerciements