OpenSSL-Problem mit Let's Encrypt

Am 30.09.2021 ist das SSL-Zertifikat DST Root CA X3 abgelaufen, mit dem bislang die von Let’s Encrypt ausgestellten Zertifikate validiert werden konnten. Let’s Encrypt hat wiederum vor längerer Zeit sein eigenes Root-Zertifikat (ISRG Root X1) eingeführt, was inzwischen auf allen halbwegs aktuellen Servern und Geräten akzeptiert wird.

Damit aber auch ältere Endgeräte (insbesondere alte Android-Smartphones) mit den neuen Let’s-Encrypt-Zertifikaten zurecht kommen, wurde ein Sonderweg eingeschlagen: den ausgelieferten Zertifikaten wird noch ein weiteres Zwischenzertifikat mitgeschickt, das vom eigentlich abgelaufenen DST Root CA X3 unterschrieben wurde. Alte Android-Geräte haben kein Problem mit abgelaufenen Root-Zertifikaten, und neuere Geräte sollten einen gültigen (direkten) Validierungspfad finden und das Zertifikat somit auch akzeptieren.

Zertifikat Aussteller Gültig bis Bemerkung
#0 www.example.org Let’s Encrypt R3 (3 Monate) das eigentliche TLS-Zertifikat
#1 Let’s Encrypt R3 ISRG Root X1 15.09.2025 das normale Zwischenzertifikat (R3) (Hash: 8d33f237)
#2 ISRG Root X1 DST Root CA X3 30.09.2024 das “Trick”-Zertifikat

Die Idee ist also, dass jeder “normale” Client dem Aussteller des Zwischenzertifikates #1 (ISRG Root X1) vertraut und somit einen validen Zertifizierungspfad findet. Geräte, welche mit ISRG Root X1 nichts anfangen können, wählen den Weg über das zusätzliche Zwischenzertifikat #2 und akzeptieren dieses aufgrund der Unterschrift von DST Root CA X3.

Soweit die Theorie.

In der Praxis gibt es an einigen Stellen aber leider doch Probleme.

Debian/Ubuntu und c_rehash

LiveConfig speichert alle TLS-Zertifikate in dem bei der jeweiligen Distribution üblichen Verzeichnis - unter Debian/Ubuntu ist das /etc/ssl/certs/. Auch eventuelle Zwischenzertifikate werden dort abgelegt - diese enden mit dem Dateinamen -ca.crt.

Nun gibt es einen besonderen Mechanismus, der symbolische Links zu den Zertifikaten anlegt, die auf dem Fingerprint des jeweiligen Zertifikats basieren. Das wird unter Debian/Ubuntu für alle Dateien in /etc/ssl/certs/ gemacht die auf .crt enden - in diesem Fall also auch mit den Chain-Zertifikaten (-ca.crt).

Das führt dazu, dass ein Symlink mit dem Namen /etc/ssl/certs/8d33f237.0 (kann selten auch .1 oder .2 sein) erstellt wird, der auf das Let’s Encrypt R3-Zwischenzertifikat zeigt. Baut man nun mit OpenSSL (als Client) eine Verbindung zu einem Server auf, der eine Zertifikatsliste wie in der oben gezeigten Tabelle präsentiert, passiert Folgendes: statt den Aussteller ISRG Root X1 zu akzeptieren und den Validierungspfad somit als “gültig” zu beenden, wird interessanterweise auch das Zertifikat #2 geprüft - das eben von einer ungültigen (weil abgelaufenen) CA ausgestellt wurde und somit ungültig ist. Die Validierung schlägt fehl.

Workaround

Es genügt tatsächlich, diesen einen Symlink zu entfernen:

rm /etc/ssl/certs/8d33f237.?

Ab diesem Zeitpunkt funktioniert der Aufbau ausgehender SSL-Verbindungen wieder problemlos.

Immerhin wird dieser Symlink nur dann erzeugt, wenn c_rehash ausgeführt wird (in der Regel über update-ca-certificates, und dann offenbar auch nur wenn es lokale Änderungen am CA-Store gibt, z.B. durch manuell installierte CA-Zertifikate).

LiveConfig 2.13.0

Mit dem Update auf Version 2.13.0 verschiebt LiveConfig unter Debian/Ubuntu alle Zwischenzertifikate von /etc/ssl/certs/*-ca.crt nach /etc/ssl/chains/ und ruft anschließend einmalig c_rehash auf, um die Hash-Symlinks zu aktualisieren. Damit sollte der Spuk behoben sein.