MQTT-Sicherheit

MQTT-Wireshark-Tutorial: MQTT-Traffic mitschneiden und analysieren

Schneiden Sie Ihren eigenen MQTT-Traffic mit Wireshark mit, lesen Sie jedes Paketfeld auf Port 1883 und sehen Sie genau, was TLS auf Port 8883 schützt, mit dem kostenlosen öffentlichen MQTT-Broker broker.connectmq.com.

MQTT-Wireshark-Mitschnitt mit dekodierten CONNECT- und PUBLISH-Paketen neben verschlüsselten TLS-Records auf Port 8883
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

Ein MQTT-Mitschnitt mit Wireshark zeigt Ihnen Feld für Feld, was Ihr Client genau an den Broker sendet. In diesem Tutorial schneiden Sie Ihren eigenen Traffic zum kostenlosen öffentlichen MQTT-Broker broker.connectmq.com auf Port 1883 mit, dekodieren CONNECT-, SUBSCRIBE- und PUBLISH-Pakete und wiederholen den Test anschließend auf dem TLS-Port 8883, um zu sehen, was die Verschlüsselung verbirgt. Das ist der schnellste Weg, Verbindungsprobleme zu debuggen und sich selbst zu beweisen, warum Produktions-Traffic TLS nutzen muss.

Schneiden Sie Traffic nur in Netzen und auf Geräten mit, die Ihnen gehören oder für deren Überwachung Sie autorisiert sind.

Was Sie brauchen

  • Wireshark 3.x oder 4.x von der offiziellen Website, mit Mitschnittrechten auf Ihrem Rechner.
  • Die Mosquitto-Kommandozeilen-Clients (mosquitto_pub und mosquitto_sub).
  • Optional Python 3 mit paho-mqtt 2.x für den Schritt zur TLS-Entschlüsselung.
  • Ein eindeutiges Topic-Präfix, zum Beispiel connectmq/demo/ws-4821/.

Der öffentliche Broker ist für alle offen, publizieren Sie daher nur Testdaten. Der Artikel zum kostenlosen öffentlichen MQTT-Broker listet seine Limits auf.

Schritt 1: Einen Mitschnitt mit Portfilter starten

Öffnen Sie Wireshark, wählen Sie die Netzwerkschnittstelle, die Sie für den Internetzugang nutzen, und geben Sie einen Capture-Filter ein, damit nur MQTT-Traffic aufgezeichnet wird:

tcp port 1883 or tcp port 8883

Starten Sie den Mitschnitt. Wireshark erkennt MQTT auf Port 1883 automatisch und wendet seinen MQTT-Dissector an.

Schritt 2: Unverschlüsselten MQTT-Traffic erzeugen

Abonnieren Sie in einem Terminal:

mosquitto_sub -h broker.connectmq.com -p 1883 -i ws-sub-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/#' -v

Publizieren Sie in einem zweiten Terminal eine Retained Message und eine normale Nachricht:

mosquitto_pub -h broker.connectmq.com -p 1883 -i ws-pub-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/temp' -m '{"celsius":21.7}' -q 1

mosquitto_pub -h broker.connectmq.com -p 1883 -i ws-pub-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/status' -m 'online' -r

Beenden Sie den Subscriber mit Strg+C und stoppen Sie den Mitschnitt.

Schritt 3: MQTT-Anzeigefilter anwenden

Geben Sie oben in der Leiste einen Anzeigefilter ein. Diese sind am nützlichsten:

Anzeigefilter Zeigt
mqtt Alle dekodierten MQTT-Pakete
mqtt.msgtype == 1 CONNECT
mqtt.msgtype == 2 CONNACK
mqtt.msgtype == 3 PUBLISH
mqtt.msgtype == 8 SUBSCRIBE
mqtt.msgtype == 12 or mqtt.msgtype == 13 PINGREQ und PINGRESP
mqtt.msgtype == 14 DISCONNECT
mqtt.topic contains "ws-4821" Pakete für Ihr Topic-Präfix
mqtt.clientid == "ws-pub-4821" CONNECT eines bestimmten Clients
tls Verschlüsselter Traffic, typischerweise auf 8883

Feldnamen können sich zwischen Wireshark-Versionen leicht unterscheiden. Wird ein Filter abgelehnt, klappen Sie ein Paket auf, klicken Sie mit der rechten Maustaste auf ein Feld und wählen Sie „Als Filter anwenden", um den exakten Namen zu erhalten.

Schritt 4: Die dekodierten Pakete lesen

CONNECT

Wählen Sie ein CONNECT-Paket aus und klappen Sie „MQ Telemetry Transport Protocol" auf. Sie sehen:

  • Protokollname und Version (MQTT, Version 5 bzw. 4 für 3.1.1).
  • Connect Flags: Clean Start, Will Flag, Flags für Benutzername und Passwort.
  • Keep Alive in Sekunden.
  • Properties (MQTT 5), etwa das Session Expiry Interval.
  • Client ID, hier ws-pub-4821.

Hätte ein Client Benutzername und Passwort über Port 1883 gesendet, wären beide hier im Klartext sichtbar. Diese eine Beobachtung ist das stärkste Argument für TLS, das Sie jemals brauchen werden.

CONNACK

Das CONNACK zeigt den Reason Code (0x00 bedeutet Erfolg) und bei MQTT 5 Server-Properties wie maximale Paketgröße, Receive Maximum, ob Retained Messages und Wildcard-Subscriptions verfügbar sind, und die maximale QoS. Diese Werte zu lesen ist ein schneller Weg, die Limits eines Brokers zu verstehen.

SUBSCRIBE und SUBACK

Das SUBSCRIBE-Paket listet Topic-Filter mit Optionen auf. Das SUBACK liefert einen Reason Code pro Filter. Ein Code von 0x80 oder höher bedeutet, dass die Subscription abgelehnt wurde, was in Anwendungslogs leicht übersehen wird, in Wireshark aber sofort auffällt.

PUBLISH

Jedes PUBLISH zeigt Topic, QoS, Retain Flag, Paket-Identifier bei QoS 1 und 2, Properties und die rohe Payload. Ihre Nachricht {"celsius":21.7} ist im Bereich der Paket-Bytes lesbar. Auf den QoS-1-Publish folgt ein PUBACK des Brokers mit demselben Paket-Identifier. Was jeder Austausch bedeutet, erfahren Sie unter MQTT-QoS-Stufen erklärt.

Schritt 5: Den Test über TLS auf Port 8883 wiederholen

Starten Sie einen neuen Mitschnitt mit demselben Filter und wiederholen Sie den Publish, diesmal mit TLS:

mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -i ws-pub-tls-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/temp' -m '{"celsius":22.1}' -q 1

Unter Windows oder macOS geben Sie statt --capath mit --cafile ein CA-Bundle an. ConnectMQ verwendet ein Let's-Encrypt-Zertifikat, dem Standard-CA-Bundles vertrauen.

Wenden Sie den Anzeigefilter tls an. Jetzt sehen Sie:

  • Einen TLS-Handshake: ClientHello, ServerHello und, je nach Version, Zertifikatsnachrichten.
  • Die Server Name Indication (broker.connectmq.com) im ClientHello, die nicht verschlüsselt ist.
  • „Application Data"-Records ohne sichtbares Topic, ohne Client ID und ohne Payload.

Ein Beobachter im Netz kann weiterhin sehen, dass Sie mit dem Broker kommuniziert haben, wann und ungefähr wie viele Daten Sie gesendet haben. Zugangsdaten, Topics oder Nachrichteninhalte sieht er nicht. Das ist der Schutz, den TLS Ihnen bietet, und der Leitfaden zur MQTT-TLS-Konfiguration erklärt, wie Sie es auf jedem Client einrichten.

Schritt 6: Eigenen TLS-Traffic zum Debuggen entschlüsseln

Manchmal müssen Sie während der Entwicklung TLS-Traffic Ihres eigenen Clients untersuchen. Wireshark kann TLS entschlüsseln, wenn der Client seine Session-Schlüssel in eine Key-Log-Datei schreibt. Das Python-Modul ssl unterstützt das:

import ssl
import time
import paho.mqtt.client as mqtt

ctx = ssl.create_default_context()
ctx.keylog_filename = "tls-keys.log"  # nur für die Entwicklung, niemals in Produktion

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="ws-py-tls-4821",
                     protocol=mqtt.MQTTv5)
client.tls_set_context(ctx)

def on_connect(c, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    c.publish("connectmq/demo/ws-4821/debug", "decrypt me", qos=1)

client.on_connect = on_connect
client.connect("broker.connectmq.com", 8883, keepalive=30)
client.loop_start()
time.sleep(3)
client.loop_stop()
client.disconnect()

Gehen Sie in Wireshark zu Bearbeiten > Einstellungen > Protocols > TLS und setzen Sie „(Pre)-Master-Secret log filename" auf die Datei tls-keys.log. Da Wireshark nicht weiß, dass Port 8883 MQTT überträgt, klicken Sie mit der rechten Maustaste auf ein TLS-Paket, wählen „Dekodieren als..." und ordnen Port 8883 MQTT zu. Die entschlüsselten Pakete zeigen nun dieselben Felder, die Sie auf 1883 gesehen haben.

Löschen Sie die Key-Log-Datei anschließend. Wer sie besitzt, kann diesen Mitschnitt entschlüsseln.

Fehlersuche mit Wireshark

Symptom im Mitschnitt Wahrscheinliche Ursache
SYN gesendet, kein SYN-ACK Firewall blockiert den Port oder falscher Hostname
TCP verbindet, Client sendet CONNECT, Broker schließt sofort Protokollverletzung, leere Client ID oder ungültige Zugangsdaten
CONNACK mit Reason 0x86 oder 0x87 Falscher Benutzername/falsches Passwort oder nicht autorisiert
CONNACK mit 0x85 Client Identifier ungültig
TLS-Alert „unknown CA" oder „bad certificate" Client vertraut der Zertifikatskette nicht
PINGREQ ohne PINGRESP, dann Reset Netz trennt inaktive Verbindungen; Keep Alive verringern
DISCONNECT mit 0x97 Quota auf dem Broker überschritten
Viele CONNECT-Pakete im Abstand von Sekunden Reconnect-Schleife, oft durch eine doppelte Client ID

Der Fall der doppelten Client ID ist besonders häufig: Zwei Geräte mit derselben ID werfen sich abwechselnd gegenseitig hinaus, und Wireshark zeigt das Muster sofort.

Der Schritt in die Produktion

Der öffentliche Broker ist für Tests gedacht. Für echte Daten erstellen Sie einen privaten Broker, verwenden den generierten Benutzernamen, das Passwort und die Client ID und verbinden sich nur über TLS auf 8883 oder sichere WebSockets auf 8084. Bei ConnectMQ umfassen private Broker zusätzlich Mandantenisolation, Quotas, Flood Protection und IP-Sperre nach wiederholten fehlgeschlagenen Logins. Wireshark bleibt auch dort nützlich: Ein Mitschnitt auf Ihrer Seite bestätigt, dass nichts unverschlüsselt Ihr Gerät verlässt. Im Werksnetz liefert ein solcher Mitschnitt außerdem einen einfachen Beleg für Sicherheitsprüfungen nach IEC 62443, dass zwischen OT-Zone und Cloud nur verschlüsselter MQTT-Verkehr fließt. Was auf ungeschützten Brokern sonst noch schiefgehen kann, lesen Sie im Artikel über offen erreichbare MQTT-Broker.

Starten Sie mit ConnectMQ

Probieren Sie die obigen Mitschnitte gleich jetzt gegen broker.connectmq.com aus und erstellen Sie dann unter app.connectmq.com einen privaten Broker im kostenlosen Serverless-Plan, ganz ohne Kreditkarte. Ihr Client-Code braucht nur einen Hostnamen, Zugangsdaten und Port 8883, um vom Test auf einen verwalteten MQTT-Broker umzuziehen. Allgemeine Tipps zur Härtung finden Sie unter Best Practices für MQTT-Sicherheit.

Häufig gestellte Fragen

Warum zeigt Wireshark auf Port 8883 kein MQTT an?

Traffic auf 8883 ist mit TLS verschlüsselt, daher sieht Wireshark nur TLS-Records. Sie können Ihre eigenen Sessions mit einer Key-Log-Datei entschlüsseln und dann mit „Dekodieren als" den MQTT-Dissector anwenden.

Wie lautet der Wireshark-Filter für MQTT?

Verwenden Sie den Anzeigefilter mqtt für alle dekodierten Pakete oder mqtt.msgtype == 3 nur für PUBLISH-Pakete. Ein Capture-Filter tcp port 1883 beschränkt die Aufzeichnung auf unverschlüsseltes MQTT.

Kann Wireshark MQTT über WebSockets sehen?

Ja, auf einem unverschlüsselten WebSocket-Port dekodiert Wireshark die WebSocket-Frames und kann den MQTT-Dissector auf deren Payload anwenden. Sichere WebSockets auf 8084 sind wie Port 8883 verschlüsselt.

Traffic auf eigenen Geräten und in eigenen Netzen zum Debuggen mitzuschneiden ist gängige Praxis. Den Traffic anderer ohne Autorisierung mitzuschneiden ist es nicht, beschränken Sie Mitschnitte daher auf Systeme, die Ihnen gehören oder die Sie überwachen dürfen.

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.