Loglar bir istemcinin ne gönderdiğini düşündüğünü söyler. Paket yakalama ise hatta gerçekte neyin geçtiğini gösterir. Wireshark yerleşik, eksiksiz bir MQTT dissector'ı ile gelir: CONNECT flag'lerini, topic adlarını, QoS'u, packet identifier'ları, MQTT 5 property'lerini ve reason code'ları çözümler. Böylece kayıp bir mesajın hiç publish edilmediğini mi, hiç onaylanmadığını mı yoksa hiç teslim edilmediğini mi saniyeler içinde görürsünüz.
Bu rehber MQTT trafiğini yakalamayı, her gün kullanacağınız görüntüleme filtrelerini, 8883 portunda TLS şifresini çözmeyi ve grafik arayüzü olmayan sunucular için birkaç tshark komutunu anlatıyor.
Doğru trafiği yakalayın
Wireshark'ı istemcinin çalıştığı makinede (ya da kontrol ediyorsanız broker'da) başlatın ve trafiğin geçtiği arayüzü seçin: uzak broker'lar için Wi-Fi veya Ethernet adaptörünüz, localhost üzerindeki bir broker için loopback arayüzü.
Dosyanın küçük kalması için bir capture filtresi kullanın. Capture filtreleri BPF sözdizimini kullanır ve yakalamayı başlatmadan önce ayarlanır:
tcp port 1883 # şifresiz MQTT
tcp port 1883 or tcp port 8883 # şifresiz ve TLS
host broker.connectmq.com # broker'a giden ve gelen her şeyArdından analiz etmek istediğiniz trafiği üretin — örneğin benzersiz bir topic üzerinde bir subscriber ve bir publisher:
mosquitto_sub -h broker.connectmq.com -p 1883 -t 'testmqtt/wireshark/#' -q 1 -v &
mosquitto_pub -h broker.connectmq.com -p 1883 -t 'testmqtt/wireshark/hello' -q 1 -m 'ping'Bir sunucuda yakalama yapıyorsanız tcpdump -w genellikle daha pratiktir; dosyayı sonra Wireshark'ta açarsınız. tcpdump ile MQTT yakalama yazısına bakın.
İhtiyacınız olan görüntüleme filtreleri
Görüntüleme filtreleri yakalamadan sonra uygulanır ve Wireshark alan adlarını kullanır. MQTT dissector'ının başlıca alanları:
| Amaç | Görüntüleme filtresi |
|---|---|
| Tüm MQTT paketleri | mqtt |
| Yalnızca CONNECT / CONNACK | mqtt.msgtype == 1 || mqtt.msgtype == 2 |
| Yalnızca PUBLISH | mqtt.msgtype == 3 |
| Bir topic veya topic öneki | mqtt.topic contains "testmqtt/wireshark" |
| Bir istemcinin CONNECT'i | mqtt.clientid == "sensor-01" |
| Reddedilen bağlantılar | mqtt.conack.val != 0 |
| Retained publish'ler | mqtt.retain == 1 |
| QoS 1 ve 2 PUBLISH'ler | mqtt.msgtype == 3 && mqtt.qos > 0 |
| Keep-alive trafiği | mqtt.msgtype == 12 || mqtt.msgtype == 13 |
| Sıfırlanan bağlantılar | tcp.flags.reset == 1 |
| TCP yeniden iletimleri | tcp.analysis.retransmission |
mqtt.msgtype sayısal değerleri MQTT kontrol paketi tipleridir:
| Değer | Paket | Değer | Paket |
|---|---|---|---|
| 1 | CONNECT | 8 | SUBSCRIBE |
| 2 | CONNACK | 9 | SUBACK |
| 3 | PUBLISH | 10 | UNSUBSCRIBE |
| 4 | PUBACK | 11 | UNSUBACK |
| 5 | PUBREC | 12 | PINGREQ |
| 6 | PUBREL | 13 | PINGRESP |
| 7 | PUBCOMP | 14 | DISCONNECT |
Tip 15 AUTH'tur (yalnızca MQTT 5). Bu alanların arkasındaki bayt düzeyindeki yapı için MQTT paket yapısı yazısına bakın.
CONNECT ve CONNACK okumak
Bir CONNECT paketi seçin ve MQ Telemetry Transport Protocol bölümünü açın. Şunları göreceksiniz:
- Protokol adı ve sürümü — sürüm 4 (3.1.1) veya 5 ile
MQTT. Broker sürümü kabul etmezse unacceptable protocol version hatasıyla yanıt verir. - Connect flag'leri — clean session / clean start, will flag, will QoS, will retain ve username ile password'ün olup olmadığı.
- Keep alive — istemcinin söz verdiği saniye cinsinden aralık.
- Client ID ve şifresiz 1883 portunda açık metin olarak username ve password.
- MQTT 5 property'leri — session expiry interval, receive maximum ve maximum packet size gibi.
Ardından gelen CONNACK sonucu taşır. MQTT 3.1.1'de bu bir return code'dur (0 kabul edildi demektir); MQTT 5'te ise 0x86 Bad User Name or Password veya 0x87 Not authorized gibi bir reason code'dur ve bazen bir reason string içerir. Herhangi bir değeri reason code aracında arayabilirsiniz. Alan alan dökümü MQTT CONNECT paketi yazısında.
Hiç CONNACK yoksa ve broker bunun yerine bir TCP RST veya FIN gönderiyorsa, broker bağlantıyı MQTT aşamasına gelmeden reddetmiştir — çoğunlukla şifresiz MQTT alan bir TLS listener'ı, bozuk bir paket ya da bir bağlantı limiti.
Bir mesajı uçtan uca takip etmek
Bir mesajın nerede kaybolduğunu kanıtlamak için onu yakalama boyunca takip edin:
mqtt.topic contains "testmqtt/wireshark"filtresini uygulayıp publisher'ın PUBLISH paketini bulun. QoS 1 veya 2 ise Message Identifier değerini not edin.- PUBACK'i (QoS 1) ya da PUBREC / PUBREL / PUBCOMP dizisini (QoS 2) görmek için
mqtt.msgid == <id>filtresini uygulayın. PUBACK yoksa broker mesajı hiç kabul etmemiştir — ACL'leri ve payload boyutunu kontrol edin. - Subscriber tarafında da yakalama yaptıysanız broker'ın teslim ettiği PUBLISH'i arayın. Packet identifier farklıdır, çünkü her atlamanın kendine ait bir identifier'ı vardır.
"Displayed packets" seçeneğiyle Statistics → Flow Graph, alışverişi bir sıralama diyagramı olarak çizer — eksik bir onayı yakalamanın en hızlı yolu budur.
TLS üzerinden MQTT'nin şifresini çözmek (port 8883)
8883 portunda, Wireshark oturum anahtarlarına sahip olana kadar yalnızca TLS kayıtları görürsünüz. Bu anahtarları almanın standart yolu, birçok TLS kütüphanesinin yazabildiği bir key log dosyasıdır.
Python (paho-mqtt 2.x) — SSL context'inde keylog_filename ayarlayın:
import ssl
import paho.mqtt.client as mqtt
ctx = ssl.create_default_context()
ctx.keylog_filename = "/tmp/mqtt-tls-keys.log" # Python 3.8+
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.tls_set_context(ctx)
client.connect("broker.connectmq.com", 8883)
client.loop_start()
client.publish("testmqtt/wireshark/tls", "hello over TLS", qos=1).wait_for_publish()
client.loop_stop()
client.disconnect()Node.js (MQTT.js) — kodu değiştirmeden yerleşik flag'i kullanın:
node --tls-keylog=/tmp/mqtt-tls-keys.log publish.jsTarayıcılar ve curl SSLKEYLOGFILE ortam değişkenini dikkate alır. Ardından Wireshark'ta Edit → Preferences → Protocols → TLS menüsünü açın ve (Pre)-Master-Secret log filename alanına key log dosyasının yolunu yazın. 8883'teki TLS kayıtları, TLS 1.2'de de 1.3'te de çözümlenmiş MQTT paketlerine dönüşür.
TLS handshake'in kendisi başarısız oluyorsa şifre çözmeye gerek yoktur: alert kaydı (örneğin Unknown CA veya Handshake Failure) açıkça görünür. TLS handshake failed yazısına bakın.
Standart dışı portlar ve WebSockets
Wireshark yalnızca kayıtlı portlarında MQTT olduğunu varsayar. Broker'ınız örneğin 11883'te dinliyorsa bir pakete sağ tıklayın, Decode As… seçin ve bu TCP portunu MQTT'ye eşleyin.
WebSockets üzerinden MQTT'de (8083 / 8084) Wireshark HTTP upgrade isteğini ve WebSocket frame'lerini gösterir; MQTT paketleri binary frame'lerin içindedir. Tarayıcı uygulamalarında bu frame'leri doğrudan tarayıcıda okumak genellikle daha hızlıdır — Chrome DevTools ile MQTT hata ayıklama yazısına bakın.
tshark tarifleri
tshark, Wireshark'ın komut satırı ikizidir ve aynı filtreleri kullanır:
# Canlı: zaman, paket tipi, topic ve payload yazdır
tshark -i any -f "tcp port 1883" -Y mqtt \
-T fields -e frame.time_relative -e mqtt.msgtype -e mqtt.topic -e mqtt.msg
# Dosyadan: topic başına PUBLISH sayısı
tshark -r mqtt.pcap -Y "mqtt.msgtype == 3" -T fields -e mqtt.topic | sort | uniq -c | sort -rn
# Keep-alive ping'leri arasındaki boşluklar (keep-alive sınırına yakın değerlere bakın)
tshark -r mqtt.pcap -Y "mqtt.msgtype == 12" -T fields -e frame.time_delta_displayedSonuncusu keep-alive zaman aşımları için kullanışlıdır: boşluklar keep-alive değerinin 1,5 katını aşarsa broker'ın istemcinin bağlantısını kesme hakkı vardır.
Belirtiye göre neye bakmalı
| Belirti | Yakalama ne gösterir |
|---|---|
| İstemci "bağlanamıyor" | CONNECT'in ardından sıfırdan farklı kodlu bir CONNACK ya da CONNACK olmadan RST |
| QoS 1'de kaybolan mesajlar | PUBACK'siz PUBLISH, yeniden bağlandıktan sonra bir kopya (DUP flag'i set) |
| Rastgele bağlantı kopmaları | PINGREQ'lerde boşluklar, TCP yeniden iletimleri, ardından bir taraftan FIN veya RST |
| Büyük mesajlar kayboluyor | Büyük bir PUBLISH'in ardından broker bağlantıyı kapatıyor — maximum packet size ile karşılaştırın ve boyutları paket boyutu hesaplayıcı ile kontrol edin |
| Subscriber hiçbir şey almıyor | 0x80 hata kodlu SUBACK ya da eşleşmeyen bir topic filter |
Bir durumu hızla yeniden üretmek için yakalamayı çalıştırırken online MQTT istemcisinden publish edin ve paketlerin gerçek zamanlı gelişini izleyin.
Wireshark tahminin yerine kanıt koyar. Dar kapsamlı yakalayın, paket tipine ve topic'e göre filtreleyin, TLS şifresini yalnızca gerektiğinde çözün ve çalışan bir oturumun yakalamasını saklayın — bozuk bir yakalamayı sağlam bir yakalamayla karşılaştırmak çoğu zaman en hızlı teşhistir.
Sıkça sorulan sorular
MQTT için Wireshark görüntüleme filtresi nedir?
Çözümlenmiş tüm MQTT paketlerini görmek için 'mqtt' kullanın. PUBLISH için mqtt.msgtype == 3, bir topic için mqtt.topic contains "sensors" veya bir istemcinin CONNECT paketi için mqtt.clientid == "sensor-01" gibi alanlarla daraltın.
Wireshark 8883 portunda neden MQTT yerine TLS gösteriyor?
MQTT paketleri şifrelidir. Wireshark onları ancak TLS oturum anahtarlarını verirseniz çözebilir: istemcinin bir key log dosyası yazmasını sağlayın (SSLKEYLOGFILE, Python'da keylog_filename, Node'da --tls-keylog) ve Wireshark'ın TLS tercihlerinde bu dosyayı gösterin.
MQTT trafiğim neden düz TCP verisi olarak görünüyor?
Wireshark MQTT'yi otomatik olarak yalnızca standart 1883 portunda (ve şifre çözüldükten sonra 8883'te) çözümler. Diğer portlar için bir pakete sağ tıklayın, Decode As seçin ve TCP portunu MQTT'ye atayın.

