Problèmes Letsencrypt

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.

1 « J'aime »

ajoutez simplement votre adresse e-mail dans le fichier de configuration.

/var/discourse/containers/app.yml

## Si vous avez ajouté le modèle Lets Encrypt, décommentez ci-dessous pour obtenir un certificat SSL gratuit
 LETSENCRYPT_ACCOUNT_EMAIL: gavin@truecode.co.za

exécutez ./launcher rebuild app

ensuite, vous devriez être prêt à partir.

Nous avons corrigé cela il y a quelques semaines. Avez-vous essayé de reconstruire ?

3 « J'aime »

Non, je ne l’ai pas fait. J’exécute la version 2.8.0.beta4 et le système indique que je suis à jour. Dois-je effectuer une reconstruction après les mises à jour, ou y a-t-il des éléments téléchargés à la volée entre les mises à jour qui nécessiteraient une reconstruction ? J’ai bien configuré une adresse e-mail dans LETSENCRYPT_ACCOUNT_EMAIL.

Je peux effectuer une reconstruction. Je devrai d’abord remettre la version originale du script letsencrypt, ou la reconstruction le rafraîchira-t-elle automatiquement ? Dois-je faire une reconstruction après chaque mise à jour, ou existe-t-il une méthode pour me notifier lorsque cela est nécessaire ? Jusqu’à présent, je n’ai jamais effectué de reconstruction depuis la mise en place initiale du site il y a environ six mois, bien que j’aie appliqué plusieurs mises à jour.

Bien que vous puissiez mettre à jour l’application depuis l’interface web, nous devons de temps en temps publier une mise à jour de l’environnement sous-jacent sur lequel Discourse s’exécute (l’image du conteneur). Ces mises à jour de l’environnement nécessitent une reconstruction.

Pour annuler vos modifications locales, vous pouvez éventuellement les mettre en réserve avec :

cd /var/discourse
git stash
./launcher rebuild app
1 « J'aime »

Ces « mises à jour environnementales » correspondent-elles aux mises à jour de « docker-manager » que je vois après avoir cliqué sur le lien « effectuer les mises à jour ici » dans la page des paramètres d’administration ? Je suis un peu confus maintenant quant à savoir quelles mises à jour je dois obtenir, d’où et quand je dois procéder à une reconstruction. Bien que je vois une mise à jour sur cette page, la page précédente indique toujours que je suis à jour.

Non, pour les obtenir, vous devez accéder au serveur via la ligne de commande et lancer une reconstruction.

OK. J’ai effectué la reconstruction, mais je ne suis pas certain que cela fonctionnera dans 90 jours, car le certificat n’est pas encore expiré, donc il ne tente pas d’en obtenir un nouveau. J’ai vérifié le script letsencrypt et il affiche une nouvelle date de modification (aujourd’hui), mais lorsque je le compare à l’ancienne version du script (l’originale, avant mes modifications), ils sont identiques. J’ai essayé d’exécuter le script manuellement depuis le conteneur avec l’option --force, comme suggéré dans l’un des commentaires du message de sortie, mais cela n’a pas fonctionné. À ce stade, je vais donc devoir faire confiance au fait que le certificat se renouvellera correctement à son expiration.