
Jemand teilt dir mit, dass deine Website unsicher ist. Du öffnest sie: Schloss, keine Warnung, Zertifikat noch vier Monate lang gültig. Du bittest die Person, es erneut zu versuchen, und es funktioniert immer noch nicht, in einem Netzwerk, das du nicht erreichen kannst, in einem Client, den du nicht hast.
Keiner von euch hat Unrecht, und das Zertifikat ist nicht das Problem. Was sich unterscheidet, ist alles darunter.
Ein Zertifikat wird nicht von allein vertraut
Dein Zertifikat behauptet nicht, dass es vertrauenswürdig ist. Es wird von einem Zwischenzertifikat signiert, das von einem Root-Zertifikat signiert wird, und nur das Root-Zertifikat befindet sich im Vertrauensspeicher des Besuchers. Die Aufgabe bei der Verbindung ist es, diesen Pfad aufzubauen, und die Aufgabe deines Servers ist es, die Mitte davon bereitzustellen.
TLS 1.3 sagt aus, was der Server sendet, und die Formulierung lohnt sich zu lesen:
certificate_list: Eine Sequenz (Kette) von CertificateEntry Strukturen, die jeweils ein einzelnes Zertifikat und einen Satz von Erweiterungen enthält.
Und dann die Regel, die normalerweise übersprungen wird:
Das Zertifikat des Absenders MUSS im ersten CertificateEntry in der Liste erscheinen. Jedes folgende Zertifikat SOLLTE das unmittelbar vorhergehende Zertifikat direkt zertifizieren. Weil die Zertifikatvalidierung erfordert, dass Vertrauensanker unabhängig verteilt werden, kann ein Zertifikat, das einen Vertrauensanker angibt, aus der Kette weggelassen werden, vorausgesetzt, dass unterstützte Peers bekannt sind, um alle weggelassenen Zertifikate zu besitzen.
Lies den letzten Satz sorgfältig. Der Vertrauensanker, das heißt das Root-Zertifikat, kann weggelassen werden, weil Clients es bereits haben. Nichts davon entschuldigt das Weglassen des Zwischenzertifikats. Dein Server soll alles zwischen deinem Zertifikat und dem Root-Zertifikat senden, und ein Zwischenzertifikat ist genau das.
Die Fehlkonfiguration, die du selbst nie sehen wirst
Das Weglassen des Zwischenzertifikats führt nicht zu einer halbdefekten Website. Es führt zu einer Website, die für dich perfekt funktioniert und für andere Menschen ausfällt, was ein erheblich teureres Ergebnis ist.
Mozilla hat das Nichtangeben ordnungsgemäßer Zwischen-CA-Zertifikate als “eines der häufigsten Serverkonfigurationsprobleme” beschrieben und hat etwas dagegen getan. Firefox lädt Zwischen-CA-Zertifikate vorab in eine Liste vor, die “über zweitausend Einträge enthält”, speziell um “unbekannte Fehler bei Ausstellern im TLS-Handshake” zu reduzieren.
Denk darüber nach, was das bedeutet. Browser kompensieren diesen Fehler aktiv. Ein Browser, der das Zwischenzertifikat bereits hat, wird die Verbindung abschließen, ob dein Server sie sendet oder nicht, daher ist dein Test erfolgreich und die Fehlkonfiguration bleibt unsichtbar. Die Kompensation ist gute Programmierung und sie ist auch der Grund, warum niemand es bemerkt.
Warum ein Client ausfällt, während ein anderer erfolgreich ist
Es gibt einen zweiten Mechanismus, der das überdeckt, und er kommt vom Zertifikat selbst.
Ein Zertifikat kann angeben, wo das Zertifikat seines issuer gefunden werden kann. RFC 5280 definiert dieses Feld und ist vorsichtig mit dem Zweck:
die id-ad-caIssuers OID wird verwendet, wenn die zusätzlichen Informationen Zertifikate aufzählen, die der CA ausgestellt wurden, die das Zertifikat mit dieser Erweiterung ausgestellt hat. Die beschriebenen CA-issuer sollen Zertifikatbenutzern bei der Auswahl eines Zertifizierungspfads helfen
“Sollen helfen” ist der operative Ausdruck. Es ist ein Zeiger, keine Verpflichtung. Ein Client kann es befolgen und das fehlende Stück abrufen, oder ein Client kann es ablehnen. Beides ist konform.
Die TLS-Spezifikation ist ähnlich offen über den Zustand der Welt und vermerkt, dass Server manchmal zusätzliche oder falsch geordnete Zertifikate senden und “andere einfach falsch konfiguriert sind”, bevor sie Implementierungen bittet, tolerant damit umzugehen.
- Was du getestet hast
- Ein aktueller Desktop-Browser, der Tausende von Zwischenzertifikaten vorab lädt und einen fehlenden issuer bei Bedarf abruft. Der nachsichtigste Client, den du hast
- Was dein Besucher verwendet hat
- Etwas Strengeres oder Älteres, das nur das validiert, was es erhalten hat, und meldet einen unbekannten issuer, wenn die Kette kein Root-Zertifikat erreicht
Toleranz ist also eine Entscheidung des Clients und keine Eigenschaft deiner Konfiguration, und du hast mit dem Client getestet, der dir am ehesten verzeiht.
Die Berichte, die dies tatsächlich erzeugt
Weil die nachsichtigen Clients die Browser sind, landen die Fehler woanders, und sie werden selten als Zertifikatproblem beschrieben.
- Ein Webhook wird nicht mehr zugestellt. Der Server eines anderen ist jetzt der Client, und er hat keine vorgefertigte Liste und kein Interesse daran, deinen issuer zu holen.
- Eine mobile App kann sich nicht anmelden, während dasselbe Konto im Web funktioniert, weil der Netzwerk-Stack der App nicht der Systembrowser ist.
- Eine Zahlungs- oder Versandintegration schlägt gegen deine Callback-URL fehl, normalerweise mit einer Meldung über einen unbekannten oder nicht vertrauenswürdigen issuer.
- Ein Büro oder ein älteres Gerät kann die Website überhaupt nicht erreichen, und alle anderen können.
Keines davon klingt wie “die Zertifikatkette ist unvollständig”, weshalb die Stunden zunächst an die falsche Stelle gehen.
Das Zwischenzertifikat ist die Einheit des Schadensradius
Ein weiterer Grund, um zu wissen, auf welches Zwischenzertifikat du angewiesen bist, getrennt davon, ob du es sendest.
Ein Zwischenzertifikat signiert sehr viele Zertifikate. Wenn eines zurückgezogen, nicht vertraut oder zum Ablaufen freigegeben wird, stoppt die Validierung jedes Zertifikats unter ihm im gleichen Moment. Dein Zertifikat kann Monate vor seinem eigenen Ablaufen bleiben, unverändert, und trotzdem ausfallen, weil das, was kaputtging, eine Stufe über ihm liegt und nie dein war.
Die meisten Zertifikatüberwachungen beobachten ein einzelnes Datum: wenn dein eigenes Zertifikat abläuft. Das ist das richtige Datum, das zu beobachten ist, und es ist nicht das einzige, und das andere gehört zu einem Zertifikat, das du nicht gewählt hast und wahrscheinlich nicht benennen kannst.
Es dauert etwa dreißig Sekunden, das zu überprüfen
Frag den Server, was er tatsächlich sendet, von etwas, das nicht dein Browser ist:
openssl s_client -showcerts -connect example.com:443 -servername example.com </dev/null
Zwei Dinge, die in der Ausgabe zu lesen sind. Zähle die Zertifikate: eine typische öffentliche Kette übergibt dein Zertifikat und mindestens ein Zwischenzertifikat, also ist genau ein Zertifikat das klassische Symptom dieses Fehlers. Dann lies den issuer deines eigenen Zertifikats und überprüfe, dass ein Zertifikat mit diesem subject weiter unten vorhanden ist.
Session Replay
Kostenlose Chrome-Erweiterung. Ein Klick auf die Seite, die sich unangemessen verhält, erfasst den Screenshot, die Konsole und das Netzwerk-Protokoll und gibt dir einen Link zum Einfügen in das Ticket.
Wenn dich stattdessen ein Screenshot eines Warnbildschirms erreicht, lohnen sich die fünf verschiedenen Fehler hinter dieser einen Seite, bevor du beginnst: deine Verbindung ist nicht privat.
Was man daraus mitnehmen sollte
Ein Zertifikat ist ein Link, keine Berechtigung. Es wird vertraut, weil ein Pfad von ihm zu etwas aufgebaut werden kann, dem der Besucher bereits vertraut, und dein Server ist für die Mitte dieses Pfads verantwortlich.
Der Ausfallmodus ist ungewöhnlich grausam, weil die Kompensation so gut ist. Browser laden Tausende von Zwischenzertifikaten vorab und verfolgen einen fehlenden issuer, also ist der Client, mit dem du testest, der Client, der dir am wenigsten sagen wird. Die, die dir mitteilen, sind Webhooks, mobile Apps und Zahlungsintegrationen, und sie teilen es dir in Worten mit, die niemals Zertifikate erwähnen.
Die Spezifikationen sind RFC 8446 für das, was ein Server senden muss, und RFC 5280 für das Feld, das einen issuer-Ort benennt.