|
Publié le par Gaulthier LALLEMAND

Let's Encrypt

Ajouter des hooks avant/après le renouvellement d'un certificat Let's Encrypt (Debian) ?

Prérequis : avoir créé un certificat Let's Encrypt avec Certbot.

Il peut être intéressant d'exécuter une commande système (ou même un script), avant et/ou après le renouvellement d'un certificat. Pour cela, on peut dire à Certbot d'exécuter une action (un hook).

Important : On ne peut utiliser ces hooks qu'avec la sous-commande renew de Certbot.

Les types de hook

Il existe trois types de hook :

  • pre-hook : se lance avant la procédure de renouvellement des certificats ;
  • post-hook : se lance après la procédure de renouvellement des certificats ;
  • deploy-hook : se lance à chaque fois qu'un certificat est créé ou renouvelé avec succès.

Attention : Pour qu'un renouvellement ait lieu, il faut que les deux conditions suivantes soient vérifiées :

  • lancer Certbot avec la sous-commande renew ;
  • au moins un certificat doit avoir une période de validité inférieure à 30 jours.

Ce qui signifie que si la commande est lancée mais qu'aucun certificat n'est prêt à être renouvelé, aucun hook n'est exécuté !

Par la ligne de commande

Commandes simples

Pour définir un hook, je peux ajouter l'option correspondante à la ligne de commande :

  • --pre-hook [COMMANDE] ;
  • --post-hook [COMMANDE] ;
  • --deploy-hook [COMMANDE].

Quelques exemples de commandes :

# Effectue le renouvellement de TOUS les certificats.
# Redémarre le service "apache2" après chaque renouvellement réussi.
sudo certbot renew --quiet \
             --deploy-hook "systemctl restart apache2"
# Arrête le service "apache2".
# Procède au renouvellement de TOUS les certificats Certbot.
# Relance le service "apache2".
sudo certbot renew --quiet \
             --pre-hook "systemctl stop apache2" \
             --post-hook "systemctl start apache2"

Lors d'un renouvellement général (ie. sans l'option --cert-name), les commandes pre-hook et post-hook ne sont lancées qu'une seule fois (Cf l'ordre d'exécution à la fin de cet article) !

Pour associer des pre-hook et post-hook au certificat abc en particulier, je peux procéder ainsi :

# Vérifie que le certificat "abc" est prêt à être renouvelé.
# Arrête le service "apache2".
# Procède au renouvellement du certificat "abc".
# Démarre le service "apache2".
sudo certbot renew --quiet \
             --cert-name abc \
             --pre-hook "systemctl stop apache2" \
             --post-hook "systemctl start apache2"

De cette manière, je peux gérer plus finement les actions précédent et suivant chaque renouvellement de certificat.

Si je souhaite renouveler chaque certificat séparément, je devrai faire attention à ajouter une ligne dans cron pour chaque certificat. Sinon certains certificats risquent d'arriver au terme de leur période de validité sans crier gare (au mieux, je recevrai un email automatique de Let's Encrypt m'avertissant de l'écheance si j'ai fourni un email lors de la création du certificat).

Supprimer la pré-validation

Certbot effectue un contrôle des commandes passées aux options --xxx-hook, avant d'exécuter pour de vrai la commande elle-même. Il vérifie surtout que les programmes invoqués sont bien dans le PATH.

Cela peut être source de faux positifs, d'erreurs qui n'en sont pas. Aussi pour supprimer ce contrôle, il suffit d'ajouter l'option --disable-hook-validation :

sudo certbot renew --quiet --disable-hook-validation ...
Chemin vers un script

Si une simple commande ne me suffit pas, je peux également spécifier le chemin absolu vers un script :

# Certbot détermine l'interpréteur de commandes grâce au shebang
# présent sur la première ligne du script.
sudo certbot renew --quiet \
             --cert-name abc \
             --pre-hook "/chemin/absolu/vers/mon/script1" \
             --post-hook "/chemin/absolu/vers/mon/script2"
Ecrire plusieurs fois la même option

Il est possible d'écrire plusieurs fois la même option --xxx-hook, mais ça ne sert à rien. En effet, bien que cela ne déclenche pas d'erreur de Certbot, le comportement de celui-ci consiste à ne prendre en compte que la dernière version d'une option.

Par exemple :

# Dans ce cas, seul le script3 sera lancé en PRE-HOOK.
# Le script4 sera lancé en POST-HOOK de façon normale.
sudo certbot renew --quiet \
             --cert-name abc \
             --pre-hook "/chemin/absolu/vers/mon/script1" \
             --pre-hook "/chemin/absolu/vers/mon/script2" \
             --pre-hook "/chemin/absolu/vers/mon/script3" \
             --post-hook "/chemin/absolu/vers/mon/script4"

Grâce au répertoire renewal-hooks

À partir de la version 0.19.0, Certbot dispose d'une série de répertoires dans lesquels je peux mettre des scripts. Ils sont situés dans le répertoire suivant :

/etc/letsencrypt/renewal-hooks/

Il existe un répertoire par type de hook:

  • pre/ : contient les scripts à exécuter avant le renouvellement des certificats ;
  • post/ : contient les scripts à exécuter après le renouvelement des certificats ;
  • deploy/ : contient les scripts à exécuter à chaque fois qu'un certificat est généré ou renouvelé avec succès.

Pour chacun de ces répertoires, les scripts sont exécutés par ordre alphabétique des noms de fichiers.

Ordre d'exécution

Les scripts du répertoire renewal-hooks/ s'exécutent toujours avant la commande indiquée par l'option --xxx-hook correspondante. Par exemple, les scripts situés dans renewal-hooks/pre/ s'exécuteront avant la commande spécifiée par l'option --pre-hook.

En supposant que Certbot identifie au moins un certificat comme devant être renouvelé, l'ordre d'exécution des hooks est le suivant (juste après avoir lancé sudo certbot renew ...) :

Exécution des hook