Let's Encrypt-Zertifikat-Erneuerungen schlagen (plötzlich) fehl

Vor einiger Zeit – es ist nicht klar, wie lange, aber mindestens mehrere Monate – begannen die Let’s Encrypt-Erneuerungen auf meinem Discourse-Forum fehzuschlagen, nachdem sie jahrelang problemlos funktioniert hatten. Als ich dies vor einigen Tagen bemerkte, war das Zertifikat im August 2021 abgelaufen. Nachdem ich einige manuelle Erneuerungen und Nginx-Neustarts versucht hatte, stellte ich fest, dass das Zertifikat nur noch wenige Tage gültig war. Offensichtlich immer noch kein aktuelles Zertifikat. Das manuelle Ausführen von acme.sh, um eine Erneuerung zu erzwingen (innerhalb des Discourse-Containers), liefert diesen Fehler (wobei [site] natürlich meine Website-Adresse ist):

[site]:Verify error:Fetching http://[site]/.well-known/acme-challenge/[long alpha challenge string]: Error getting validation data

Ich sollte anmerken, dass die Website für den gesamten Benutzerzugriff eine Anmeldung erfordert, aber dies war in den Jahren des früheren Betriebs kein Problem für die Erneuerung von SSL-Zertifikaten.

Irgendwelche Ideen? Vielen Dank!

UPDATE: Das Testen der Verifizierung mit wget gibt einen 404 zurück. Ich weiß jedoch nicht, wo diese Daten in Nginx für Discourse in einem Container konfiguriert sind und wie sie sich auf das zugehörige Nginx beziehen, das außerhalb des Containers proxyed.

2 „Gefällt mir“

Wenn es ein paar Monate her ist, hat es etwas damit zu tun:

2 „Gefällt mir“

Hallo. Das sollte keinen Zusammenhang haben, da dieses Problem dazu führen würde, dass Zertifikate vom Browser mit anderen Fehlern abgelehnt werden, nicht mit abgelaufenen Fehlern, wie in meinem Fall. Es scheint, dass Let’s Encrypt plötzlich keine Authentifizierung mehr mit Discourse durchführen kann, um neue Zertifikate auszustellen. Danke.

2 „Gefällt mir“

Nicht, wenn die erste Ablaufzeit im August war. Sie hätte sich danach erneuern sollen.

4 „Gefällt mir“

Bei einer App, die nach Juni nicht aktualisiert wurde, könnte dieses Problem aufgetreten sein: Letsencrypt certificate failure to renew - #11 by pfaffman

Ich bin mir nicht sicher, ob es das ist, wonach Sie suchen, aber: discourse_docker/templates/web.letsencrypt.ssl.template.yml at main · discourse/discourse_docker · GitHub

2 „Gefällt mir“

Hallo. Diese scheinen nicht zu zutreffen. Ich sehe einen 404-Fehler, nicht die anderen Fehler, die Builds wurden die ganze Zeit aktualisiert, und diese Vorlage von GitHub ist tatsächlich die Version, die bereits in meiner Installation installiert ist. Danke!

3 „Gefällt mir“

Verwenden Sie Cloudflare mit der orangefarbenen Wolke oder einen anderen Reverse-Proxy?

2 „Gefällt mir“

Negativ. Lokal gehostet auf Ubuntu 18.04 mit der Standard-Docker-Installation.

3 „Gefällt mir“

Der manuell ausgeführte Cron-Job (im Container) zur Erneuerung des Zertifikats schlägt immer mit demselben Fehler fehl. Der Versuch, Folgendes abzurufen:

http://[site]/.well-known/acme-challenge/[challenge-string]

schlägt mit „Fehler beim Abrufen der Validierungsdaten“ fehl.

2 „Gefällt mir“

Da der Prozess nicht vertraut ist, könnte es sein, dass der Container sich in einem Zustand befindet, der nicht der Fall ist, wenn das Skript allein ausgeführt wird? Erwartet es vielleicht einen anderen Cronjob, der Nginx darauf vorbereitet, den Zugriff auf eine solche URL zu ermöglichen.

Haben Sie versucht, einen Rebuild durchzuführen? (Dadurch wird versucht, ein neues Zertifikat zu erhalten.)

Sie erwähnen, dass es lokal gehostet wird. Können Sie von außerhalb Ihres Netzwerks über den Domainnamen auf die Instanz zugreifen?

2 „Gefällt mir“

Hallo, ja mehrere Neuerstellungen. Keine Änderung. Ich verwende Let’s Encrypt auf vielen Nicht-Discourse-Websites und alle erneuern sich problemlos. Ja, ich kann von einer externen Website darauf zugreifen und habe es mit wget getestet, das Ergebnis ist 404. Frage: Wo genau befindet sich der nginx-HTML-Baum in diesem Fall, der Teil, der das Verzeichnis .well-known enthalten würde (oder enthalten sollte)? Ich konnte es nicht finden. Danke.

2 „Gefällt mir“

Ich konnte keinen Cronjob finden, nur ein Runlevel-Skript unter /etc/runit/1.d/letsencrypt. Es sieht so aus, als würde dieses Skript eine neue Instanz von nginx mit einer Konfiguration starten, die Folgendes enthält:

location ~ /.well-known {
  root /var/www/discourse/public;
  allow all;
}

Ich denke, das bedeutet, dass der Pfad /var/www/discourse/public/acme-challenge wäre, obwohl er möglicherweise erstellt wird, bevor die Herausforderung stattfindet, und danach wieder entfernt wird.

Wenn das das Skript ist, das Sie manuell auszuführen versucht haben, haben Sie nginx zuerst gestoppt? Die Instanz, die das Skript zu starten versucht, versucht, auf Port 80 zu lauschen, daher vermute ich, dass dies fehlschlagen würde, wenn nginx bereits für Discourse läuft.

2 „Gefällt mir“

Ich glaube, ich sehe das Problem. Aber ich weiß nicht, wie ich es beheben kann. Es scheint, dass alle Versuche, auf das Forum über den HTTPS-Port 80 zuzugreifen, (wie erwartet) auf HTTPS 443 umgeleitet werden. Richtig. Aber das bedeutet, dass Let’s Encrypt fehlschlägt, wenn es versucht, die Erneuerung zu validieren, da das aktuelle Zertifikat abgelaufen ist. Ich kann die Umleitung mit wget sehen. Die Frage ist also, wie kann ich die Umleitung vorübergehend deaktivieren, damit Let’s Encrypt validieren und mir ein neues, nicht abgelaufenes Zertifikat besorgen kann? Eine zusätzliche mögliche Komplikation ist, dass die Umleitung eine dauerhafte 301 ist. Danke.

2 „Gefällt mir“

Diese Umleitung befindet sich in /etc/nginx/conf.d/discourse.conf und wird nicht verwendet, wenn nginx gestoppt und dann mit der in meinem vorherigen Beitrag erwähnten Konfiguration gestartet wird.

Ich bin mir nicht sehr sicher, wie das automatische Upgrade funktioniert, daher bin ich mir nicht sicher, welche die geeignete Methode wäre, um die Erneuerung durchzuführen, während der Container läuft. Theoretisch sollte das Stoppen und Starten des Containers zu einer Erneuerung führen, aber da Sie sagten, dass ein Rebuild dies nicht getan hat, wird dies wahrscheinlich auch nicht funktionieren.

acme.sh hat Optionen wie --renew-all, aber ich bin mir nicht sicher, welche anderen Optionen benötigt werden, damit es hier das Richtige tut. Das Folgende ist möglicherweise alles, was Sie brauchen, aber ich kann es nicht mit Sicherheit sagen.

LE_WORKING_DIR="/shared/letsencrypt" /root/acme.sh/acme.sh --renew-all
2 „Gefällt mir“

Und tatsächlich erlaubt dies Let’s Encrypt, ohne die Umleitung hineinzukommen, aber anscheinend existiert die gesuchte Datei nicht, was letztendlich zum gleichen Verifizierungsfehler führt.

2 „Gefällt mir“

Ich habe dasselbe Problem. Hat jemand ein klares Verfahren zur Behebung des Problems gefunden?

2 „Gefällt mir“

Ich verwende dies jetzt, um das Zertifikat erfolgreich zu erhalten. Es scheint, dass das Validierungstoken VON curl abgerufen wird, aber acme.sh erklärt trotzdem jedes Mal einen Validierungsfehler! Also immer noch offline.

„/shared/letsencrypt“/acme.sh --renew-all --force --insecure --home „/shared/letsencrypt“ --debug

2 „Gefällt mir“

Hallo @L30110 :slightly_smiling_face:

Ich bin einer der Stammgäste im Let’s Encrypt Forum. @JimPas hat mich geschickt, um mir diesen Thread anzusehen, was ich tun werde, sobald ich vom Mittagessen zurück bin.

3 „Gefällt mir“

Bei vielen ACME-Clients (wie acme.sh) wird, wenn Nginx als Authentifizierungsmethode angegeben ist, die Datei der http-01-Herausforderung in einem bestimmten Verzeichnis erstellt, das auf einer Ausnahme/Umleitung in der Nginx-Serverkonfiguration basiert, anstatt direkt im Verzeichnis ‘.well-known/acme-challenge’ im Webroot-Verzeichnis. Oft existiert diese Umleitung nur vorübergehend für die Dauer der Herausforderungsüberprüfung, ebenso wie die Herausforderungsdateien selbst.

Daher:


Eine weise Überlegung. Ein richtig geschriebenes Erneuerungsskript sollte es unnötig machen, Nginx zu stoppen. Typischerweise wird Nginx verwendet, um die Herausforderungsdatei(en) bereitzustellen, und dann wird etwas wie nginx -s reload verwendet, um den Webserver/Proxy nach dem Erhalt des neuen Zertifikats ordnungsgemäß neu zu laden.


Nein. :wink:

Gemäß Challenge Types - Let's Encrypt

Unsere Implementierung der HTTP-01-Herausforderung folgt Umleitungen bis zu 10 Umleitungen tief. Sie akzeptiert nur Umleitungen zu „http:“ oder „https:“ und nur zu Ports 80 oder 443. Sie akzeptiert keine Umleitungen zu IP-Adressen. Wenn zu einer HTTPS-URL umgeleitet wird, validiert sie keine Zertifikate (da diese Herausforderung dazu dient, gültige Zertifikate zu bootstrapen, kann sie auf selbstsignierte oder abgelaufene Zertifikate stoßen).


Typischerweise, wenn wir solche Probleme sehen, ist einer der folgenden Punkte der Schuldige:

  • Eine Firewall lässt keinen Datenverkehr zum Webserver/Proxy zu, der die Herausforderungsdatei(en) bereitstellt.
  • Ein Router/Proxy ist falsch zugeordnet/konfiguriert, sodass die Herausforderungsüberprüfungsanfrage von Boulder (dem Let’s Encrypt CA-Server) versucht, die Datei(en) von einem falschen Webserver oder Verzeichnis abzurufen.
  • Eine Art von Rewriting/Umleitung (z. B. .htaccess-Dateien in Apache) stört den Webserver/Proxy, sodass dieser die Herausforderungsdateien vom richtigen Speicherort aus bereitstellen kann.
  • Verwendung von Nicht-Standard-Ports, normalerweise mit falscher Zuordnung.
  • Der Container, der den ACME-Client ausführt, erstellt die Herausforderungsdatei(en) an einem Ort, an dem der Webserver/Proxy (z. B. Nginx) sie nicht bereitstellt. Wenn Docker beteiligt ist, ist dies fast immer das Problem.
2 „Gefällt mir“

Hallo. Von den verschiedenen von Ihnen aufgeführten Punkten treffen mehrere eindeutig nicht auf meinen Fall zu. Kein Firewall-Problem – ich kann das Token mit wget oder curl manuell von allen folgenden Orten aus abrufen: 1) innerhalb der Docker-Discourse-App, 2) von außerhalb des Docker-Containers auf dem Host-System und 3) einem verwandten System.

Für diese manuellen Fälle erhalte ich die Token-Inhalte vom erwarteten Speicherort, vorausgesetzt, --ignore oder -k wird angegeben, um das abgelaufene Zertifikat zu umgehen, wenn Discourse automatisch zu HTTPS weiterleitet.

Ich habe keinen Aspekt der von Discourse erstellten Nginx-Konfiguration geändert, weder innerhalb noch außerhalb des Discourse-Docker-Containers. Ich führe keine Kopien von Nginx aus, und Apache läuft auf komplett anderen Ports nur für den lokalen Gebrauch. Beachten Sie, dass all dies über zwei Jahre lang einwandfrei funktioniert hat, mit routinemäßigen Zertifikatserneuerungen und ohne andere App-Änderungen – es ist eine sehr stabile Box.

Keine ungewöhnlichen Ports.

Da ich die Token-Inhalte manuell abrufen kann, sehe ich nicht, wie falsche Speicherorte beteiligt sein könnten. AUSSER …

Ich habe Nginx für meine Tests nicht manuell gestoppt. Ich habe dies jetzt getan, und es gab keinen signifikanten Unterschied – dieselben Fehler von acme.sh (derzeit wieder Fehler 56). Wenn Nginx aus dem Container gestoppt wird, sehe ich auf dem Host eine laufende sv Nginx-Instanz, aber sie hat keine Worker- oder Cache-Prozesse. Wenn ich Nginx im Container neu starte, erscheinen die Worker- und Cache-Prozesse auf dem Host zusammen mit dem laufenden sv Nginx, das geblieben war. Die sv start/stop nginx-Befehle im Container geben die erwarteten Bestätigungen dieser Aktionen.

Aber es gibt noch etwas anderes, das oben erwähnt wurde und Anlass zur Sorge geben könnte. Und ich verstehe nicht, warum dies plötzlich ein Problem sein sollte, angesichts der langen Zeit, in der die Dinge bisher funktioniert haben.

Die statische IP-Adresse des Forums, die von außerhalb meines lokalen Netzwerks verwendet wird, ist für die Verbindung zu den eigenen Diensten dieser Maschine von dieser Maschine aus nicht nutzbar, aufgrund von Komplexitäten bei der Bereitstellung statischer IPs durch den ISP. Ich habe routinemäßig Einträge in /etc/hosts verwendet, um lokale Netzwerk-IP-Adressen für diese Namen bereitzustellen. Wenn ich also mit curl auf derselben Maschine teste (sowohl innerhalb als auch außerhalb des Containers, beide haben die /etc/hosts-Ergänzung für das Forum), verwendet der Test eine andere (und lokale) IP-Adresse als eine externe Website, die sie über DNS nachschlagen würde. Könnte dies irgendwie relevant sein? Danke.

2 „Gefällt mir“