バージョン
- Mac OS X: 10.10.2
- WireShark(Qt): 1.12.3
- VirtualBox: 4.3.20
目的
Mac (boot2docker) の docker コンテナ上で動く mosquitto (MQTT ブローカー) との通信を wireshark (tcpdump) したい。
意外と手間取ったので、メモとして残す。
そもそもパケットが見えない
ネットワークは
Mac(VirtualBox Host) ------- boot2docker(Virtualbox Guest)
vboxnet0
のようになっている。vboxnet0 はホストオンリーアダプタ。
Mac で vboxnet0 を wireshark すると、例えば ping だと ECHO Reply だけ見える。
-
Mac -> boot2docker
方向は見えない -
Mac <- boot2docker
方向は見える
アダプタータイプをいじってみても改善しなかった。
仮想ドライバをいじるのはつらいので、NAT しているインターフェースで port forward することにした。こうすると lo0
で両方向、ちゃんと見える。
port forward はいちいち設定を入れる必要があってめんどくさいから、なるべくホストオンリーアダプタでやりたかったけど、しかたない。
MQTT plugin を有効化する
wireshark 標準では MQTT パケットをデコードしてくれない。MQTT はバイナリプロトコルなので、そのままだとちょっとつらい。
https://raw.githubusercontent.com/menudoproblema/Wireshark-MQTT/master/mqtt.lua を wget とかする。そのままだと動かなかったので、次のように変更した。
--- mqtt.lua 2015-02-05 02:02:54.000000000 +0900
+++ /usr/local/lib/wireshark/plugins/1.12.3/mqtt.lua 2015-02-05 01:15:01.000000000 +0900
@@ -18,14 +18,13 @@
do
-- Create a new dissector
- MQTTPROTO = Proto("MQTT", "MQ Telemetry Transport")
- local bitw = require("bit")
+ MQTTPROTO = Proto("MQTT3", "MQ Telemetry Transport")
local f = MQTTPROTO.fields
-- Fix header: byte 1
f.message_type = ProtoField.uint8("mqtt.message_type", "Message Type", base.HEX, nil, 0xF0)
f.dup = ProtoField.uint8("mqtt.dup", "DUP Flag", base.DEC, nil, 0x08)
f.qos = ProtoField.uint8("mqtt.qos", "QoS Level", base.DEC, nil, 0x06)
- f.retain = ProtoField.uint8("mqtt.retain", "Retain", base.DEC, nil, 0x01)
+ f.retain = ProtoField.uint8("mqtt.retain1", "Retain", base.DEC, nil, 0x01)
-- Fix header: byte 2
f.remain_length = ProtoField.uint8("mqtt.remain_length", "Remain Length")
@@ -71,9 +70,9 @@
repeat
digit = buffer(offset, 1):uint()
offset = offset + 1
- value = value + bitw.band(digit,127) * multiplier
+ value = value + bit32.band(digit,127) * multiplier
multiplier = multiplier * 128
- until (bitw.band(digit,128) == 0)
+ until (bit32.band(digit,128) == 0)
return offset, value
end
これを ~/.wireshark/plugins/mqtt.lua にコピーする。
wireshark は Homebrew からインストールし、--with-lua
を有効にしてある。
まとめ
wireshark を起動しなおして、lo0 をダンプしつつ tcp.port == 1883
でフィルタし、Mac で MQTT クライアントを動かすと、MQTT パケットが見える。
これで MQTT の解析が捗るね。