Layer 8Ehrlicher Tech-Support

Zertifikat selbst prüfen: openssl s_client richtig lesen

s_client ist ein Testwerkzeug und setzt den Handshake nach Zertifikatsfehlern absichtlich fort. Eine erfolgreiche Verbindung beweist deshalb nichts.

Aufwand:
ca. 20 Min.
Voraussetzung:
OpenSSL auf der Kommandozeile, Der genaue Hostname und Port der Gegenstelle
Gilt für:
OpenSSL, Manpage-Stand master (docs.openssl.org, abgerufen am 23.08.2026)

Das Symptom

Irgendwo klemmt eine HTTPS-Verbindung: Eine App meldet einen Zertifikatsfehler, ein Skript bricht ab, ein Partner beschwert sich. Also der Griff zum Werkzeug, das jeder kennt – openssl s_client -connect host:443. Die Ausgabe rauscht durch, am Ende steht eine aufgebaute Verbindung, und die Sache ist für dich erledigt: Bei dir geht es ja.

Zwei Tage später geht es beim anderen immer noch nicht. Beim genaueren Hinsehen stand ganz unten in deiner Ausgabe eine Zeile mit einem Prüfergebnis ungleich null, die im Scrollen untergegangen ist. Das Werkzeug hat nie behauptet, das Zertifikat sei in Ordnung. Es hat nur nicht widersprochen.

Die „Layer 8“-Wahrheit

s_client ist kein Prüfprogramm. Die eigene Dokumentation sagt das in einem Satz, den man einmal gelesen haben sollte: Dieses Kommando ist ein Testwerkzeug und darauf ausgelegt, den Handshake nach beliebigen Zertifikatsprüfungsfehlern fortzusetzen; im Ergebnis akzeptiert es jede vom Gegenüber gesendete Zertifikatskette, vertrauenswürdig oder nicht. Die Manpage hängt sogar die Warnung an, dass Nicht-Testanwendungen sich so nicht verhalten sollten, weil sie damit für Man-in-the-Middle-Angriffe angreifbar würden. Wer aus einem erfolgreichen Verbindungsaufbau auf ein gültiges Zertifikat schließt, hat das Werkzeug also nicht falsch bedient – er hat es für etwas gehalten, das es ausdrücklich nicht sein will.

Der Schalter, der aus dem Testwerkzeug einen Prüfer macht, heißt -verify_return_error. Er schaltet die Serverzertifikatsprüfung ein wie -verify, gibt Prüffehler aber zurück, statt weiterzumachen, und bricht den Handshake typischerweise mit einem Fatal Error ab. Zum Gegenstück -verify schreibt die Manpage entwaffnend offen, dass die Prüfung ohne diesen Schalter nach Fehlern weiterläuft, damit man alle Probleme einer Kette auf einmal sieht – und dass die Verbindung als Nebeneffekt niemals an einem Prüffehler des Serverzertifikats scheitert. Beide Verhaltensweisen sind sinnvoll. Man muss nur wissen, in welcher der beiden man gerade steckt.

Dieselbe Sorgfalt gilt für -showcerts. Was dort erscheint, ist die vom Server gesendete Zertifikatsliste in der Reihenfolge des Servers, und die Manpage stellt in einem eigenen Satz klar: Es ist keine verifizierte Kette. Das ist genau der Unterschied zwischen „was kam an“ und „was ergibt geprüft einen Pfad zu einem Vertrauensanker“. Für die Fehlersuche ist die rohe Liste trotzdem oft die wertvollste Information überhaupt, weil man an der Anzahl der Einträge sofort sieht, ob der Server seine Zwischenzertifikate überhaupt mitliefert.

Bleiben zwei Stolperstellen, die nichts mit Kryptografie zu tun haben. Erstens die SNI: Ohne -servername füllt OpenSSL die Erweiterung selbst mit dem an -connect übergebenen Namen, sofern der wie ein DNS-Name aussieht, und ohne -connect mit „localhost“ – seit Version 1.1.1 der Standard. Wer per IP-Adresse testet, prüft deshalb schnell ein ganz anderes Zertifikat als gemeint. Zweitens das Hängenbleiben im Skript: Die Manpage beschreibt, dass s_client in nicht-interaktiven Umgebungen die Verbindung vorzeitig schließen kann, vor allem mit TLS 1.3, und empfiehlt dagegen -ign_eof zusammen mit einer Umleitung von /dev/null. Beides sind keine Zertifikatsprobleme. Beides wird regelmäßig für eines gehalten.

Die echte, verifizierte Lösung

1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:

  1. 1.

    Zuerst mit erzwungener Prüfung verbinden

    Der erste Aufruf sollte nicht der bequeme sein, sondern der ehrliche. Mit -verify_return_error bricht der Handshake bei einem Prüffehler ab, statt ihn nur zu protokollieren – das ist die einzige Variante, deren Ausgang dem Verhalten einer echten Anwendung entspricht. Die Umleitung von /dev/null verhindert das in der Manpage beschriebene Hängen in nicht-interaktiven Umgebungen.

    openssl s_client -connect www.example.de:443 -verify_return_error -brief </dev/null
    
  2. 2.

    Erst danach die volle Ausgabe ansehen

    Ohne -verify_return_error setzt s_client den Handshake nach Zertifikatsfehlern fort. Das ist kein Bug, sondern der dokumentierte Zweck des Werkzeugs: So werden alle Probleme einer Kette auf einmal sichtbar, statt beim ersten abzubrechen. Diese Ausgabe ist zum Verstehen gut und zum Beurteilen ungeeignet.

    openssl s_client -connect www.example.de:443 -showcerts </dev/null
    
  3. 3.

    Die gesendete Liste als das lesen, was sie ist

    Die Ausgabe von -showcerts ist die vom Server gesendete Zertifikatsliste in der Reihenfolge des Servers und laut Manpage ausdrücklich keine verifizierte Kette. Nützlich ist sie trotzdem: Man sieht, wie viele Zertifikate überhaupt ankamen. Steht dort nur ein einziges, hat der Server keinerlei Zwischenzertifikat mitgeschickt – das ist eine Aussage über die Serverkonfiguration und noch keine über die Gültigkeit.

  4. 4.

    Den Servernamen bewusst setzen

    Die Manpage zu -servername beschreibt das Standardverhalten: Ohne diese Option wird die TLS-SNI-Erweiterung mit dem an -connect übergebenen Namen gefüllt, sofern dieser einem DNS-Namensformat folgt, und ohne -connect auf „localhost“ gesetzt; das ist seit OpenSSL 1.1.1 so. Wer per IP-Adresse verbindet, sollte den Namen deshalb ausdrücklich mitgeben, sonst prüft er ein Zertifikat, das gar nicht das gesuchte ist.

    openssl s_client -connect 203.0.113.10:443 -servername www.example.de -verify_return_error -brief </dev/null
    
  5. 5.

    Einzelne Felder gezielt ausschneiden statt scrollen

    Für Gültigkeitszeitraum, Aussteller und die abgedeckten Namen genügt es, das erste Zertifikat durch openssl x509 zu schicken. Das ist übersichtlicher als die vollständige Handshake-Ausgabe und liefert genau die drei Angaben, an denen die meisten Fälle hängen.

    openssl s_client -connect www.example.de:443 -servername www.example.de </dev/null \
      | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
    
  6. 6.

    Bei Mail- und Datenbankdiensten das richtige Protokoll wählen

    Dienste, die erst nach einem Klartextdialog auf TLS umschalten, brauchen -starttls mit dem passenden Protokollnamen. Die Manpage listet dafür smtp, pop3, imap, ftp, xmpp, irc, postgres, mysql, lmtp, nntp, sieve und ldap auf. Wer das vergisst, misst nicht das Zertifikat, sondern den eigenen Fehler.

    openssl s_client -connect mail.example.de:587 -starttls smtp -verify_return_error -brief -ign_eof
    

Häufige Fragen (FAQ)

?Die Verbindung kommt zustande. Ist das Zertifikat damit in Ordnung?

Nein, und das ist ausdrücklich so gebaut. Die Manpage zu openssl-s_client hält fest: „This command is a test tool and is designed to continue the handshake after any certificate verification errors. As a result it will accept any certificate chain (trusted or not) sent by the peer.“ Sie warnt im selben Atemzug, dass Nicht-Testanwendungen das nicht tun sollten, weil es sie für einen Man-in-the-Middle-Angriff angreifbar macht. Ein erfolgreicher Verbindungsaufbau mit s_client ist deshalb kein Prüfergebnis, sondern nur der Nachweis, dass überhaupt jemand antwortet.

?Was ändert -verify_return_error?

Genau das, was fehlt. Die Manpage beschreibt die Option als Einschalten der Serverzertifikatsprüfung wie bei -verify, aber mit dem Unterschied, dass Prüffehler zurückgegeben statt übergangen werden – „This will typically abort the handshake with a fatal error.“ Damit verhält sich s_client zum ersten Mal wie eine echte Anwendung: Was hier scheitert, scheitert auch anderswo. Zu -verify selbst schreibt die Manpage umgekehrt, dass die Prüfung ohne -verify_return_error nach Fehlern fortgesetzt wird, damit alle Probleme einer Kette sichtbar werden, und dass die Verbindung als Nebeneffekt niemals an einem Prüffehler des Serverzertifikats scheitert.

?Ist die Ausgabe von -showcerts die geprüfte Kette?

Ausdrücklich nicht. Die Manpage formuliert es ungewöhnlich deutlich: „Displays the server certificate list as sent by the server: it only consists of certificates the server has sent (in the order the server has sent them). It is not a verified chain.“ Was dort steht, ist also eine reine Mitschrift dessen, was über die Leitung kam – in genau der Reihenfolge, in der es kam. Ob daraus ein gültiger Pfad zu einem Vertrauensanker gebaut werden kann, sagt diese Liste nicht.

?Warum bleibt der Befehl in einem Skript hängen?

Das ist ein bekanntes Verhalten, das die Manpage in einem eigenen Abschnitt zur nicht-interaktiven Nutzung behandelt: Läuft s_client in einer nicht-interaktiven Umgebung, etwa in einem Cronjob oder einem Skript ohne gültige Standardeingabe, kann es die Verbindung vorzeitig schließen, besonders mit TLS 1.3. Als Gegenmittel nennt sie die Option -ign_eof, die s_client auch nach dem Erreichen von EOF auf der Standardeingabe weiterlaufen lässt, und zeigt die Verwendung zusammen mit einer Umleitung von /dev/null.

?Wie prüfe ich Mailserver, die erst später auf TLS umschalten?

Mit -starttls. Die Manpage beschreibt die Option als Senden der protokollspezifischen Nachrichten, um für die Kommunikation auf TLS umzuschalten, und listet die unterstützten Protokolle auf: smtp, pop3, imap, ftp, xmpp, irc, postgres, mysql, lmtp, nntp, sieve und ldap. Ohne diese Option redet s_client auf Port 25 oder 143 TLS gegen einen Server, der dort noch Klartext spricht – und scheitert aus einem Grund, der nichts mit dem Zertifikat zu tun hat.

Belege

Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.

  1. [1]
    openssl-s_client – Manpage der OpenSSL-Dokumentation

    docs.openssl.org · abgerufen am

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler