Letsencrypt Probleme

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.

1 „Gefällt mir“

Fügen Sie einfach Ihre E-Mail-Adresse in die Konfigurationsdatei ein.

/var/discourse/containers/app.yml

## Wenn Sie die Lets Encrypt-Vorlage hinzugefügt haben, entfernen Sie unten das Kommentarzeichen, um ein kostenloses SSL-Zertifikat zu erhalten
 LETSENCRYPT_ACCOUNT_EMAIL: gavin@truecode.co.za

Führen Sie dann ./launcher rebuild app aus.

Danach sollte alles bereit sein.

Wir haben das vor ein paar Wochen behoben. Hast du einen Neuaufbau versucht?

3 „Gefällt mir“

Nein, habe ich nicht. Ich verwende Build 2.8.0.beta4, und es wird angezeigt, dass ich auf dem neuesten Stand bin. Muss ich nach Updates einen Rebuild durchführen, oder werden zwischen den Updates Dinge „on the fly" heruntergeladen, die einen Rebuild erfordern? Ich habe eine E-Mail-Adresse in LETSENCRYPT_ACCOUNT_EMAIL hinterlegt.

Ich kann einen Rebuild durchführen. Muss ich zuerst die ursprüngliche Version des Letsencrypt-Skripts wiederherstellen, oder wird es durch den Rebuild aktualisiert? Soll ich nach jedem Update einen Rebuild durchführen, oder gibt es eine Methode, die mich informiert, wenn dies notwendig ist? Bisher habe ich seit der ersten Einrichtung der Website vor etwa sechs Monaten noch nie einen Rebuild durchgeführt, obwohl ich regelmäßig Updates eingespielt habe.

Obwohl Sie die App über die Weboberfläche aktualisieren können, müssen wir gelegentlich ein Update für die zugrunde liegende Umgebung von Discourse (das Container-Image) bereitstellen. Solche Umgebungsupdates erfordern einen Neuaufbau.

Um Ihre lokalen Änderungen rückgängig zu machen, können Sie diese möglicherweise mit folgendem Befehl zwischenspeichern:

cd /var/discourse
git stash
./launcher rebuild app
1 „Gefällt mir“

Sind diese „Umgebungs-Updates" die „docker-manager"-Updates, die ich sehe, nachdem ich auf dem Admin-Einstellungsbildschirm auf den Link „Hier Upgrades durchführen" geklickt habe? Ich bin jetzt etwas verwirrt darüber, welche Updates ich woher und wann beziehen soll und wann ich einen Rebuild durchführen muss. Obwohl ich auf dieser Seite ein Upgrade sehe, steht auf der vorherigen Seite weiterhin, dass ich auf dem neuesten Stand bin.

Nein, um diese zu erhalten, müssen Sie über die Befehlszeile auf den Server zugreifen und einen Rebuild ausführen.

OK. Ich habe den Neuaufbau durchgeführt, bin mir aber nicht sicher, ob er in 90 Tagen funktionieren wird, da das Zertifikat noch nicht abgelaufen ist und daher nicht versucht wird, ein neues zu erhalten. Ich habe das letsencrypt-Skript geprüft, und es zeigt ein neues Änderungsdatum (heute) an. Beim Vergleich mit der alten Version des Skripts (dem Original, nicht nach meinen Änderungen) sind sie jedoch identisch. Ich habe versucht, das Skript manuell aus dem Container heraus mit --force aufzurufen, wie in einer der Ausgabe-Nachrichten kommentiert, aber das hat nicht funktioniert. An diesem Punkt muss ich also einfach darauf vertrauen, dass das Zertifikat bei Ablauf ordnungsgemäß erneuert wird.