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_pubundmosquitto_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.
Ist es legal, MQTT-Traffic mitzuschneiden?
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.



