Il semble que des changements aient eu lieu avec le service Let’s Encrypt à partir du 1er août. Mon certificat n’expirant que ce jour-là, je n’ai été affecté par ces modifications qu’aujourd’hui. Les scripts utilisés par Discourse pour gérer le service Let’s Encrypt ont été mis à jour afin d’utiliser par défaut un nouveau service appelé ZeroSSL au lieu de Let’s Encrypt. Malheureusement, ZeroSSL nécessite apparemment une inscription avec une adresse e-mail avant de pouvoir fonctionner. Ainsi, ce matin, lorsque mon certificat existant a expiré, le site ne fonctionnait plus.
Après une investigation assez poussée, j’ai compris quel était le problème. Bien que j’aie en quelque sorte contourné la difficulté, je ne pense pas que la solution que j’ai appliquée soit nécessairement la « bonne » correction. Voici d’abord les messages d’erreur que j’ai obtenus dans le journal :
[Wed 01 Sep 2021 05:33:58 PM UTC] Reload error for :
[Wed 01 Sep 2021 05:34:03 PM UTC] Using CA: https://acme.zerossl.com/v2/DV90
[Wed 01 Sep 2021 05:34:04 PM UTC] No EAB credentials found for ZeroSSL, let's get one
[Wed 01 Sep 2021 05:34:04 PM UTC] acme.sh is using ZeroSSL as default CA now.
[Wed 01 Sep 2021 05:34:04 PM UTC] Please update your account with an email address first.
[Wed 01 Sep 2021 05:34:04 PM UTC] acme.sh --register-account -m my@example.com
[Wed 01 Sep 2021 05:34:04 PM UTC] See: https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA
[Wed 01 Sep 2021 05:34:04 PM UTC] Please check log file for more details: /shared/letsencrypt/acme.sh.log
J’ai essayé d’enregistrer manuellement le compte depuis l’intérieur du conteneur. Bien que cela ait indiqué que l’enregistrement avait été effectué, au redémarrage du conteneur, j’ai obtenu la même erreur. J’ai donc localisé les scripts ; celui qui gère cela se trouve à l’intérieur du conteneur dans /etc/runit/1.d/letsencrypt. Voici le script original :
#!/bin/bash
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
issue_cert() {
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --issue $2 -d mudtoemanor.baronshire.org --keylength $1 -w /var/www/discourse/public
}
cert_exists() {
[[ "$(cd /shared/letsencrypt/mudtoemanor.baronshire.org$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
}
########################################################
# RSA cert
########################################################
issue_cert "4096"
if ! cert_exists ""; then
# Try to issue the cert again if something goes wrong
issue_cert "4096" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org.key \
--reloadcmd "sv reload nginx"
########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"
if ! cert_exists "_ecc"; then
# Try to issue the cert again if something goes wrong
issue_cert "ec-256" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert --ecc \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org_ecc.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org_ecc.key \
--reloadcmd "sv reload nginx"
if cert_exists "" || cert_exists "_ecc"; then
grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
fi
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
Comme l’enregistrement par e-mail n’a pas fonctionné, j’ai décidé d’ajouter l’option pour que le script acme.sh revienne simplement à l’utilisation de Let’s Encrypt original au lieu de ZeroSSL. Les instructions pour le faire étaient fournies sur ce site web : https://community.letsencrypt.org/t/the-acme-sh-will-change-default-ca-to-zerossl-on-august-1st-2021/144052
J’ai d’abord essayé d’insérer ceci comme troisième ligne du script, juste après l’instruction /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf :
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt
Le journal a affiché un message indiquant que la valeur par défaut avait été modifiée, mais immédiatement après, j’ai obtenu la même erreur concernant l’absence d’e-mail enregistré pour ZeroSSL. Il y avait un délai d’environ 6 secondes dans le journal entre ce message et les messages d’erreur, ce qui me fait penser que le script acme.sh doit conserver des informations d’état via des variables d’environnement et que les exécutions ultérieures de la commande s’exécutaient dans un contexte différent, perdant ainsi la variable. Ce que j’ai fini par devoir faire, c’est modifier toutes les invocations de acme.sh dans le script letsencrypt pour ajouter cet opérande à la commande : --server letsencrypt. Lorsque j’ai fait cela et redémarré le conteneur, un nouveau certificat a été généré par Let’s Encrypt au lieu de ZeroSSL, et le site est revenu en ligne.
Voici la version modifiée du script letsencrypt que j’ai utilisée :
#!/bin/bash
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt
issue_cert() {
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --server letsencrypt --issue $2 -d mudtoemanor.baronshire.org --keylength $1 -w /var/www/discourse/public
}
cert_exists() {
[[ "$(cd /shared/letsencrypt/mudtoemanor.baronshire.org$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
}
########################################################
# RSA cert
########################################################
issue_cert "4096"
if ! cert_exists ""; then
# Try to issue the cert again if something goes wrong
issue_cert "4096" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org.key \
--server letsencrypt \
--reloadcmd "sv reload nginx"
########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"
if ! cert_exists "_ecc"; then
# Try to issue the cert again if something goes wrong
issue_cert "ec-256" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert --ecc \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org_ecc.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org_ecc.key \
--server letsencrypt \
--reloadcmd "sv reload nginx"
if cert_exists "" || cert_exists "_ecc"; then
grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
fi
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
J’ai également laissé la commande originale que j’avais insérée pour essayer de définir le service par défaut, au cas où, mais elle pourrait ne pas être nécessaire.
Ce qui doit donc se produire, c’est que ce script doit être modifié soit pour définir explicitement le service Let’s Encrypt à utiliser lors de toutes les invocations de acme.sh, soit pour déterminer comment acme.sh enregistre les informations d’état afin qu’une seule invocation de la commande par défaut fonctionne, ou enfin pour ajouter le support de ZeroSSL et la nécessité de collecter et d’enregistrer une adresse e-mail.
Je suppose que ce que j’ai fait sera écrasé la prochaine fois que je mettrai à niveau les versions, et que je devrai le refaire si cela n’est pas corrigé.
Si j’ai manqué quelque chose ici ou si cela a été résolu d’une autre manière ne nécessitant pas de modification des scripts, faites-le-moi savoir.