Offensichtlich haben sich ab dem 1. August Änderungen beim letsencrypt-Dienst ergeben. Mein Zertifikat lief erst heute ab, sodass ich erst heute von den Änderungen betroffen war. Die Skripte, die Discourse zur Verwaltung des letsencrypt-Dienstes verwendet, wurden so aktualisiert, dass standardmäßig ein neuer Dienst namens ZeroSSL anstelle von letsencrypt verwendet wird. Leider erfordert ZeroSSL anscheinend eine Registrierung mit einer E-Mail-Adresse, bevor er funktioniert. Als mein bestehendes Zertifikat heute Morgen abgelaufen ist, funktionierte die Website daher nicht.
Nach einiger Recherche habe ich herausgefunden, worum es sich bei dem Problem handelte. Zwar habe ich es irgendwie umgangen, aber ich glaube nicht, dass meine Lösung die „richtige" ist. Zuerst hier die Fehlermeldungen, die ich im Log erhalten habe:
[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
Ich habe versucht, das Konto manuell innerhalb des Containers zu registrieren. Obwohl die Registrierung erfolgreich war, erhielt ich beim Neustart des Containers denselben Fehler. Daraufhin habe ich die Skripte durchsucht; das entsprechende Skript befindet sich im Container unter /etc/runit/1.d/letsencrypt. Hier ist das ursprüngliche Skript:
#!/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
Da die E-Mail-Registrierung nicht funktionierte, entschied ich mich, die Option einzufügen, damit das acme.sh-Skript wieder den ursprünglichen letsencrypt-Dienst anstelle von ZeroSSL verwendet. Anweisungen dazu finden sich auf dieser Website: https://community.letsencrypt.org/t/the-acme-sh-will-change-default-ca-to-zerossl-on-august-1st-2021/144052
Zuerst habe ich versucht, dies als dritte Zeile im Skript direkt nach der Anweisung /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf einzufügen:
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt
Das Log zeigte eine Meldung an, dass der Standard geändert wurde, aber unmittelbar danach erhielt ich denselben Fehler bezüglich der fehlenden E-Mail-Registrierung für ZeroSSL. Im Log lag eine Verzögerung von etwa 6 Sekunden zwischen dieser Meldung und den Fehlermeldungen. Das lässt mich vermuten, dass das acme.sh-Skript Zustandsinformationen über Umgebungsvariablen verwaltet und dass nachfolgende Ausführungen des Befehls in einem anderen Kontext liefen und somit die Variable verloren gingen. Was ich schließlich tun musste, war, alle Aufrufe von acme.sh im letsencrypt-Skript so zu ändern, dass das Argument --server letsencrypt zum Befehl hinzugefügt wird. Als ich das tat und den Container neu startete, wurde ein neues Zertifikat von letsencrypt anstelle von ZeroSSL generiert, und die Website war wieder erreichbar.
Hier ist die modifizierte Version des letsencrypt-Skripts, die ich verwendet habe:
#!/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
Ich habe den ursprünglichen Befehl, den ich eingefügt hatte, um den Standarddienst festzulegen, der Einfachheit halber beibehalten, auch wenn er möglicherweise nicht notwendig ist.
Was also geschehen muss, ist, dass dieses Skript so geändert wird, dass entweder der zu verwendende letsencrypt-Dienst bei allen Aufrufen von acme.sh explizit definiert wird, oder dass herausgefunden wird, wie acme.sh Zustandsinformationen speichert, damit ein einzelner Aufruf des Standardbefehls funktioniert. Alternativ muss Unterstützung für ZeroSSL hinzugefügt werden, einschließlich der Notwendigkeit, eine E-Mail-Adresse zu erfassen und zu speichern.
Ich gehe davon aus, dass meine Änderung beim nächsten Upgrade der Versionen überschrieben wird und ich sie erneut vornehmen muss, falls dies nicht behoben wird.
Falls ich hier etwas übersehen habe oder das Problem auf eine andere Weise gelöst wurde, die keine Änderung der Skripte erfordert, lassen Sie es mich bitte wissen.