Weil ich regelmäßig neue Seiten unter neuen Hostnamen aufsetze, schaue ich mir sehr viele Zertifikate an. Und der Browser — das Werkzeug, zu dem alle zuerst greifen — ist so ziemlich die schlechteste Art, das zu tun.
So sieht ein Zertifikatsproblem in Chrome aus:

"Zertifikat ist ungültig." Danke. Welches Zertifikat? Ausgestellt auf welchen Namen? Gültig bis wann? Ist die Kette vollständig, oder fehlt ein Intermediate? Liefert der Server überhaupt das Zertifikat aus, von dem ich denke, dass ich es installiert habe?
Du bekommst einen Fehlercode und ein Schloss. Und schlimmer noch: Der Browser-Cache lässt sich zwar leeren, ist aber nervtötend — du reparierst das Zertifikat, lädst neu, und der Browser zeigt dir fröhlich wieder den alten Fehler.
openssl s_client, der eine Befehl, den man sich merken sollte
openssl s_client -connect example.com:443 -servername example.com
Das druckt den kompletten Handshake: die Kette, die der Server geschickt hat, das ausgehandelte Protokoll und Cipher, und das Zertifikat selbst.
-servername ist in der Praxis nicht optional. Es setzt den SNI-Hostnamen, und ohne ihn reicht dir ein Server, der mehrere Seiten auf einer IP hostet, sein Default-Zertifikat statt dem, nach dem du fragst. Lass es weg, und du debuggst ein Zertifikat, das nie das Problem war.
Die rohe Ausgabe ist eine Wand aus Text, deshalb leite ich sie in der Praxis immer in etwas Engeres um.

Die vier Dinge, die ich tatsächlich prüfe
Wann läuft es ab?
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
notBefore=Jun 3 08:14:22 2026 GMT
notAfter=Sep 1 08:14:21 2026 GMT
Das echo | ist wichtig: s_client hält die Verbindung sonst offen und wartet auf Eingaben, und du sitzt davor und wunderst dich, warum nichts passiert.
Welche Namen deckt es ab?
Das ist der Punkt, der die Leute erwischt, und es ist genau der Fehler aus dem Screenshot oben — ERR_CERT_COMMON_NAME_INVALID heißt, das Zertifikat ist in Ordnung, es ist nur nicht für diesen Hostnamen:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
Moderne Clients ignorieren den Common Name vollständig und schauen nur auf die SAN-Liste. Ein Zertifikat mit CN=example.com, das aber nur www.example.com in den SANs hat, scheitert also auf der nackten Domain — und der CN sieht im Zertifikatsviewer des Browsers dabei völlig korrekt aus.
Ist die Kette vollständig?
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| grep -E "^(Verify return code|depth=)"
Ein fehlendes Intermediate ist der klassische "geht in meinem Browser, scheitert auf dem Handy der Kundin und in curl"-Bug. Desktop-Browser cachen Intermediates, die sie anderswo gesehen haben, oft und füllen die Lücke stillschweigend; andere Clients tun das nicht. Wenn Verify return code irgendetwas anderes als 0 (ok) ist, repariere es, bevor dir jemand sagt, es sei schon in Ordnung, weil es bei ihm lädt.
Ist das überhaupt das Zertifikat, das ich installiert habe?
Vergleich den Fingerprint, den der Server ausliefert, mit der Datei auf der Platte:
# was der Server herausgibt
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -fingerprint -sha256
# was in der Datei steht, von der du denkst, dass er sie nutzt
openssl x509 -in /etc/ssl/certs/example.com.pem -noout -fingerprint -sha256
Zwei identische Strings, oder du hast deine Antwort: Der Reload ist nicht passiert, oder der Proxy liest einen anderen Pfad, als du denkst. Diese eine Prüfung hat mir mehr Zeit gespart als alles andere in diesem Artikel zusammen.
Testen, bevor das DNS auf den neuen Server zeigt
Das andere, was der Browser überhaupt nicht kann. Um ein Zertifikat auf einem bestimmten Server zu prüfen und dabei trotzdem den richtigen Hostnamen zu präsentieren:
curl -Iv --resolve example.com:443:203.0.113.10 example.com
Korrektes SNI, korrekter Host-Header, geschickt an eine IP deiner Wahl. Du kannst überprüfen, dass alles stimmt, bevor du das DNS umstellst, statt umzustellen und es dann herauszufinden.
SSL Labs, und sein Cache
Für das komplette Bild — Protokollunterstützung, Cipher Suites, eine Note, und wie sich verschiedene echte Clients verhalten würden — ist SSL Labs immer noch das beste kostenlose Werkzeug:

SSL Labs cached Ergebnisse. Führ es direkt nach einer Korrektur aus, und du kannst den alten Report zurückbekommen — nutz "Clear cache" auf der Ergebnisseite, sonst debuggst du ein Problem, das du schon gelöst hast.
Zwei weitere Grenzen: Es erreicht nur öffentliche Hosts, hilft also bei nichts Internem, und ein vollständiger Scan dauert ein paar Minuten. Es ist das Werkzeug für die abschließende Kontrolle, nicht für die zwölfte Iteration einer Konfigurationsänderung.
Mein tatsächlicher Ablauf
Konfiguration ändern. Fingerprint prüfen, um zu bestätigen, dass der Server sie übernommen hat. Daten und SANs prüfen. Prüfen, dass die Kette verifiziert. Und dann, ganz am Ende, einen Browser aufmachen — als Plausibilitätskontrolle, dass ein echter Client zustimmt, nicht als das, was mir sagt, ob es funktioniert hat.
Der letzte Punkt ist die allgemeine Regel, und sie geht weit über Zertifikate hinaus: ein Browser ist das falsche Werkzeug, um Infrastrukturänderungen zu testen, weil alles, was er tut, um für Nutzer schnell zu sein, ihn für dich als Tester zum Lügner macht.
Noch eins, für das, was du vergessen wirst
Den Ablauf. Zertifikate erneuern sich automatisch — bis zu dem Tag, an dem der Renewal-Hook still scheitert und es neunundachtzig Tage lang niemandem auffällt.
for host in example.com api.example.com stage.example.com; do
printf '%-28s ' "$host"
echo | openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null \
| openssl x509 -noout -enddate
done
Lass das gelegentlich über deine Hosts laufen. Besser noch: Pack es ins Monitoring mit einer Schwelle von zwei Wochen, und hör auf, von Kunden über abgelaufene Zertifikate zu erfahren.