MQTT-Sicherheit

MQTT-TLS-Handshake fehlgeschlagen: Ursachen finden und beheben

Eine Schritt-für-Schritt-Anleitung zur Fehlersuche bei fehlgeschlagenen MQTT-TLS-Handshakes: Mit openssl s_client finden Sie falsche Ports, fehlende CAs, SNI-Probleme, falsche Uhrzeiten, TLS-Versionskonflikte und abfangende Proxys.

Illustration zur Fehlersuche bei fehlgeschlagenem MQTT-TLS-Handshake mit einem abgebrochenen Handshake zwischen Client und Broker und Diagnoseausgabe im Terminal
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Wenn der Fehler „MQTT TLS Handshake fehlgeschlagen“ auftritt, bricht die Verbindung ab, bevor MQTT überhaupt beginnt, und die meisten Client-Bibliotheken melden das mit einer wenig hilfreichen Nachricht. Dieser Leitfaden zeigt Ihnen, wie Sie die Ursache mit openssl s_client in wenigen Minuten eingrenzen, und geht dann die sechs Probleme durch, die hinter fast jedem Fehlschlag stecken: falscher Port, fehlende CA, SNI, falsche Uhrzeit, TLS-Versionskonflikt und abfangende Proxys. Alle Tests laufen gegen broker.connectmq.com auf Port 8883, sodass Sie einen bekanntermaßen funktionierenden Endpunkt mit Ihrem eigenen vergleichen können.

Was bei einem TLS-Handshake passiert

Bevor Ihr Client das MQTT-CONNECT-Paket sendet, muss er einen TLS-Handshake mit dem Broker abschließen:

  1. Der Client sendet ein ClientHello mit unterstützten TLS-Versionen, Cipher Suites und dem Servernamen (SNI).
  2. Der Broker antwortet mit der gewählten Version und dem Cipher sowie seiner Zertifikatskette.
  3. Der Client prüft die Kette gegen vertrauenswürdige Roots, kontrolliert die Gültigkeitsdaten und gleicht den Hostnamen ab.
  4. Beide Seiten leiten Schlüssel ab und wechseln zu verschlüsseltem Verkehr.

Ein Fehler in einem dieser Schritte schließt die Verbindung. Ihre MQTT-Bibliothek zeigt dann etwa A TLS error occurred (mosquitto), ssl.SSLError (Python), ECONNRESET oder einen Zertifikatsfehler (Node.js) oder state=-2 (PubSubClient auf dem ESP32). Was Sie brauchen, ist die eigentliche Ursache, und OpenSSL zeigt sie direkt an. Die korrekten Basiseinstellungen finden Sie in unserem Leitfaden zur MQTT-TLS-Konfiguration.

Schritt 1: Den Handshake mit openssl s_client nachstellen

Führen Sie diesen Befehl auf demselben Rechner oder im selben Netzwerk aus wie den fehlschlagenden Client:

openssl s_client -connect broker.connectmq.com:8883 \
  -servername broker.connectmq.com -showcerts </dev/null

Ein gesundes Ergebnis endet mit Zeilen wie:

Verify return code: 0 (ok)

und zeigt das ausgehandelte Protokoll und den Cipher. Wenn OpenSSL erfolgreich ist, Ihre Anwendung aber scheitert, liegt das Problem in der Konfiguration der Anwendung (CA-Pfad, Hostname, Bibliotheksoptionen). Scheitert auch OpenSSL, liegt das Problem beim Netzwerk, beim Trust Store oder bei der Uhr. Dieser eine Vergleich halbiert den Suchraum.

Nützliche Varianten:

# Kurze Zusammenfassung von Protokoll, Cipher und Prüfung
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -brief </dev/null

# Gegen eine bestimmte CA-Datei prüfen, wie es ein Embedded-Gerät tun würde
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com \
  -CAfile isrgrootx1.pem </dev/null

# Zertifikatsdaten und Namen anzeigen
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

MQTT-TLS-Handshake fehlgeschlagen: Symptome und Ursachen

Symptom Wahrscheinliche Ursache Lösung
wrong version number oder packet length too long TLS-Client spricht mit einem Klartext-Port (1883) Port 8883 für TLS verwenden
Verbindung hängt und läuft dann in einen Timeout Klartext-MQTT-Client auf Port 8883 oder Port durch Firewall blockiert TLS im Client aktivieren; Erreichbarkeit testen
unable to get local issuer certificate (Code 20) Client vertraut der Root-CA nicht Korrektes CA-Bundle installieren oder darauf verweisen
self-signed certificate in certificate chain (Code 19) Abfangender Proxy oder Virenscanner ersetzt das Zertifikat Inspektion umgehen oder der Proxy-CA bewusst vertrauen
certificate is not yet valid (Code 9) Geräteuhr geht nach Zeit vor dem Verbinden per NTP synchronisieren
certificate has expired (Code 10) Uhr geht vor oder das Serverzertifikat ist tatsächlich abgelaufen Geräteuhr und Serverdaten prüfen
Hostname mismatch / IP address mismatch Verbindung per IP oder mit falschem Namen Über den Hostnamen im Zertifikat verbinden
no protocols available / unsupported protocol Client auf TLS-Versionen beschränkt, die der Server nicht anbietet TLS 1.2 oder neuer im Client zulassen
alert handshake failure Keine gemeinsame Cipher Suite oder fehlendes SNI TLS-Bibliothek aktualisieren; SNI senden

Ursache 1: falscher Port oder falsches Schema

Das ist der häufigste Fehler. Port 1883 spricht reines MQTT; Port 8883 erwartet TLS ab dem ersten Byte. Startet Ihr Client TLS gegen 1883, meldet OpenSSL wrong version number, weil die Antwort des Servers kein TLS-Record ist. Verbindet sich ein Klartext-Client mit 8883, wartet der Broker auf ein ClientHello, das nie kommt, und die Verbindung wird schließlich geschlossen.

Prüfen Sie auch Ihr URL-Schema. In MQTT.js bedeutet mqtt:// Klartext und mqtts:// TLS; im Browser verwenden Sie wss://broker.connectmq.com:8084/mqtt. In Python aktiviert erst der Aufruf von tls_set() TLS; nur den Port zu ändern, reicht nicht.

So prüfen Sie, ob der Port überhaupt erreichbar ist:

# Linux/macOS
nc -vz broker.connectmq.com 8883

# Windows PowerShell
Test-NetConnection broker.connectmq.com -Port 8883

Firmen- und Gastnetzwerke blockieren 8883 häufig. Ist der Port gesperrt, ist Secure WebSocket auf 8084 ein gängiger Ausweg; siehe MQTT über WebSocket.

Ursache 2: fehlendes oder falsches CA-Zertifikat

Prüffehler 20 bedeutet, dass der Client keine Kette zu einer vertrauenswürdigen Root aufbauen konnte. Typische Situationen:

  • mosquitto-Clients nutzen den System-Store nur, wenn Sie --capath /etc/ssl/certs (Linux) oder --cafile übergeben. Unter Windows laden Sie das PEM von ISRG Root X1 herunter und übergeben --cafile.
  • Minimale Docker-Images enthalten oft das Paket ca-certificates nicht.
  • Embedded-Geräte haben die falsche Root, ein abgeschnittenes PEM oder das Leaf-Zertifikat statt der Root erhalten.
  • Python unter macOS, von python.org installiert, braucht einmalig die Ausführung seines Zertifikats-Installers; Details finden Sie unter SSL CERTIFICATE_VERIFY_FAILED bei MQTT.

Das Broker-Zertifikat von ConnectMQ wird von Let's Encrypt ausgestellt, daher enthält jeder aktuelle System-Trust-Store bereits die benötigte Root.

Ursache 3: fehlendes SNI

Server Name Indication teilt dem Server mit, welchen Hostnamen Sie erreichen wollen. Lastverteilte und mandantenfähige Endpunkte präsentieren bei fehlendem SNI unter Umständen ein Standardzertifikat oder lehnen den Handshake ab. Die meisten Bibliotheken senden SNI automatisch, wenn Sie sich mit einem Hostnamen verbinden. Probleme treten auf, wenn Code zuerst die IP-Adresse auflöst und sich mit der IP verbindet, oder wenn sehr alte TLS-Stacks verwendet werden. Übergeben Sie der Client-Bibliothek immer den Hostnamen, und geben Sie bei OpenSSL-Tests immer -servername an.

Ursache 4: falsche Uhrzeit

Zertifikate sind nur zwischen zwei Daten gültig. Ein Raspberry Pi ohne Netzwerkzeit, ein ESP32, der NTP noch nicht abgeschlossen hat, oder eine VM, die aus einem alten Snapshot wiederhergestellt wurde, können Tage oder Jahrzehnte danebenliegen. Prüfen Sie das unter Linux mit date -u, und warten Sie auf Mikrocontrollern auf NTP, bevor Sie die TLS-Verbindung öffnen. Der Leitfaden zum ESP32 Certificate Pinning enthält eine fertige NTP-Warteschleife.

Ursache 5: TLS-Versions- oder Cipher-Konflikt

Alte Firmware, veraltete Java-Laufzeitumgebungen oder fest codierte Einstellungen wie Pythons ssl.PROTOCOL_TLSv1 bieten unter Umständen nur Versionen an, die moderne Server deaktiviert haben. Testen Sie, welche Versionen ein Server akzeptiert:

openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -tls1_2 </dev/null
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -tls1_3 </dev/null

Konfigurieren Sie Ihren Client so, dass er automatisch aushandelt (zum Beispiel ssl.PROTOCOL_TLS_CLIENT in Python), statt eine einzige Version festzulegen. Unser Artikel zu MQTT über TLS 1.3 erklärt die Wahl von Versionen und Ciphern ausführlicher.

Ursache 6: TLS-Inspektion und Proxys

Manche Firmen-Firewalls und Antivirenprodukte fangen TLS ab, indem sie ihr eigenes Zertifikat präsentieren. Das Symptom ist Prüffehler 19 und ein Ausstellername, der zum Sicherheitsprodukt gehört. Bitten Sie Ihr Netzwerkteam, den Broker-Hostnamen auszunehmen, oder vertrauen Sie, falls die Inspektion vorgeschrieben ist, der CA der Organisation ausdrücklich und nur in dieser Umgebung. Liefern Sie niemals Geräte mit deaktivierter Prüfung aus, um einen Proxy zu umgehen. In Werksnetzen, die nach dem Zonen-und-Conduit-Modell der IEC 62443 segmentiert sind, lohnt außerdem ein Blick auf die Firewall zwischen OT- und IT-Zone: Dort wird ausgehender Verkehr von Edge-Gateways oder SPS-nahen Rechnern häufig gefiltert oder inspiziert, und die Freigabe für den Broker-Hostnamen auf 8883 muss ausdrücklich beantragt werden.

Systematische Checkliste

  1. Führen Sie openssl s_client mit -servername in der fehlschlagenden Umgebung aus.
  2. Stellen Sie sicher, dass der Port zum Transport passt: 1883 Klartext, 8883 TLS, 8084 Secure WebSocket.
  3. Stellen Sie sicher, dass sich der Client per Hostname verbindet, nicht per IP.
  4. Prüfen Sie, ob Trust Store oder CA-Datei die richtige Root enthalten.
  5. Prüfen Sie die Systemuhr in UTC.
  6. Lassen Sie die automatische Aushandlung der TLS-Version zu.
  7. Schließen Sie Proxys aus, indem Sie aus einem anderen Netzwerk testen, etwa über einen Handy-Hotspot.
  8. Erst wenn der Handshake gelingt, debuggen Sie Fehler auf MQTT-Ebene wie falsche Zugangsdaten oder einen Client-ID-Konflikt.

Der letzte Punkt ist wichtig: Ein erfolgreicher Handshake, auf den eine Trennung mit einem CONNACK-Reason-Code folgt, ist ein Authentifizierungs- oder Protokollproblem, kein TLS-Problem.

Weniger Handshake-Probleme mit einem verwalteten MQTT-Broker

Viele TLS-Vorfälle bei selbst betriebenen Brokern entstehen auf der Serverseite: abgelaufene Zertifikate, unvollständige Ketten oder ein nach einem Upgrade falsch konfigurierter Listener. Ein verwalteter MQTT-Broker verlagert diese Verantwortung auf den Anbieter. ConnectMQ stellt TLS auf 8883 und Secure WebSocket auf 8084 mit automatisch erneuerten Let's-Encrypt-Zertifikaten bereit; wenn also ein Handshake fehlschlägt, wissen Sie, dass Sie auf der Client-Seite suchen müssen. Sie können jeden Client zunächst gegen den öffentlichen MQTT-Broker testen (nur für Tests, nicht für Produktionsdaten), und unser Leitfaden zum Cloud-MQTT-Broker zeigt, wie gehostete Broker in die Produktion passen.

Starten Sie mit ConnectMQ

Erstellen Sie unter app.connectmq.com einen kostenlosen Broker im Serverless-Plan ohne Kreditkarte, kopieren Sie die generierten Zugangsdaten und bestätigen Sie mit dem MQTT-Client im Browser, der im Portal integriert ist, dass der Broker funktioniert, bevor Sie Ihren eigenen Gerätecode debuggen.

Häufig gestellte Fragen

Warum meldet mosquitto_sub nur „A TLS error occurred“?

Die mosquitto-Clients verbergen die OpenSSL-Details. Führen Sie openssl s_client mit demselben Host, Port und derselben CA-Datei aus, um den genauen Prüffehler zu sehen.

Kann ein falscher Benutzername oder ein falsches Passwort einen TLS-Handshake-Fehler verursachen?

Nein. Zugangsdaten werden nach dem Handshake geprüft, im Rahmen des MQTT-CONNECT-Austauschs. Ein Problem mit den Zugangsdaten zeigt sich als CONNACK-Ablehnung, nicht als TLS-Fehler.

Mein Client funktioniert zu Hause im WLAN, aber nicht im Büro. Warum?

Das Büronetzwerk blockiert wahrscheinlich Port 8883 oder untersucht TLS-Verkehr. Testen Sie mit Test-NetConnection oder nc und probieren Sie Secure WebSocket auf Port 8084.

Sollte ich die Zertifikatsprüfung deaktivieren, um eine Verbindung herzustellen?

Nein. Das Deaktivieren der Prüfung verdeckt das eigentliche Problem und entfernt den Schutz vor gefälschten Brokern. Korrigieren Sie stattdessen CA, Hostname oder Uhrzeit.

Verwandte Artikel

MQTT-Zugangsdaten ohne Ausfallzeit rotieren

Eine Schritt-für-Schritt-Strategie mit zwei parallelen Zugangsdaten, um MQTT-Benutzernamen und -Passwörter in einer Geräteflotte zu rotieren: neue Zugangsdaten bereitstellen, mit Fallback umschalten, prüfen und erst dann die alten widerrufen.

7 Min. Lesezeit

MQTT-Zugangsdaten sicher auf Embedded-Geräten speichern

Ein praxisnaher Vergleich der Möglichkeiten, MQTT-Benutzernamen und -Passwörter auf ESP32- und Linux-Geräten zu schützen, von verschlüsseltem NVS und Flash-Verschlüsselung bis zu Secure Elements und TPM-gestützten systemd-Credentials.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.