微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在tcpdump中基于主题名称过滤MQTT通信

如何解决如何在tcpdump中基于主题名称过滤MQTT通信

我正在使用以下命令捕获MQTT流量以进行故障排除

 tcpdump -i team0 -w mqtt-trace.pcap src 10.x.x.x

但是它会在几分钟之内生成非常大的文件,我可以根据主题名称过滤tcpdump

以下是tcp有效负载,我希望它仅捕获具有PKGCTRL/1/status/frequency的有效负载,或者tcpdump是否可以直接支持wireshark mqtt.topic == PKGCTRL/1/status/frequency之类的应用层协议上的过滤器

0000   00 13 95 36 2e ef 00 10 7e 07 87 3d 08 00 45 00   ...6....~..=..E.
0010   00 77 2e 0d 40 00 40 06 f6 78 0a 0b 80 f3 0a 0b   .w..@.@..x......
0020   80 f2 c3 6a 75 83 e4 f8 f7 7a 0a 89 67 76 50 18   ...ju....z..gvP.
0030   ea 60 59 f8 00 00 30 4d 00 1a 50 4b 47 43 54 52   .`Y...0M..PKGCTR
0040   4c 2f 31 2f 73 74 61 74 75 73 2f 66 72 65 71 75   L/1/status/frequ
0050   65 6e 63 79 0a 11 09 c2 7a 85 14 d0 71 37 16 12   ency....z...q7..
0060   06 08 01 10 01 18 00 12 1c 0a 0d 09 0b 46 25 75   .............F%u
0070   02 f2 48 40 10 21 18 00 11 00 60 76 14 d0 71 37   ..H@.!....`v..q7
0080   16 20 00 28 00                                    . .(.

解决方法

按照@hardillb的建议,改用tshark。由于tshark的体系结构,您不能与显示过滤器同时写入文件(太慢了)。

要获得所需的信息,它看起来像这样

$ tshark -i team0 -f "src 10.x.x.x" \
  -Y "mqtt.topic == PKGCTRL/1/status/frequency" -T fields -e mqtt.topic
  • -i team0:在界面team0上过滤
  • -f "src 10.x.x.x":使用捕获过滤器,与tcpdump的过滤相同。这将加快处理速度,因为它比显示过滤器(下一个项目符号)要快。
  • -Y "mqtt.topic == PKGCTRL/1/status/frequency":过滤与该显示过滤器匹配的数据包
  • -T fields -e mqtt.topic:仅输出mqtt.topic字段,因为这是目标信息。

-T fields将输出由换行符垂直分隔的列数据。它不会水平定界,因为只有一列,但默认值为\t

,

我认为先前接受的答案不一定像您想的那样做,甚至不一定要您做。最初的问题是“但是它会在几分钟内导致文件很大,我可以根据主题名称过滤tcpdump吗?”

如果您试图限制捕获文件的大小,那么先前接受的答案就不会这样做了,因为它使用与最初提供的捕获过滤器完全相同的捕获过滤器,即src 10.x.x.x。这意味着您正在捕获与以前相同数量的数据。仅仅因为未指定捕获文件名并不意味着未将包写入文件;他们是。对于tshark,数据包被写入临时文件,该文件将继续增长,直到捕获会话终止,然后理想情况下将其删除,但并非总是如此。临时文件的位置因运行tshark的平台而异,但是您应该能够通过运行tshark -G folders | grep "^Temp"轻松地找到目录。


现在,如果要减小捕获文件的大小或看到的数据包数量,则应该可以将tcpdumptshark命令行参数修改为完成。

首先,如果不需要整个有效负载,则可以应用 snaplen 将数据包缩短一些适当的值。这是使用-s选项完成的,并且对于任何一个捕获工具都是相同的选项。

好,但是无论您决定是否应用快照,如果要基于特定主题名称进行过滤,最有可能实现此目标;但是,我在下面列出了一些警告。主要思想是使用 slice 运算符[](请参见pcap-filter手册页)将TCP有效负载的各个字节与特定值进行比较。 (注意tcpdump本身和pcap-filter都没有将此操作符称为 slice 操作符,但是wireshark-filter确实如此,所以我做到了以及。)因此过滤器应:

  • 仅与进出特定主机的数据包进行匹配,在本例中为10.x.x.x
  • 仅匹配MQTT数据包(通常按端口号,我将其假定为标准tcp / 1883端口)
  • 仅匹配QoS为0的PUBLISH消息
  • 仅匹配主题长度为26个字节的PUBLISH消息
  • 仅匹配主题为“ PKGCTRL / 1 /状态/频率”的PUBLISH消息

这是一个应该起作用的命令(至少在大多数情况下->请参见以下警告):

tcpdump -i team0 -w mqtt-trace.pcap \
    "(src host 10.x.x.x) and \
    (tcp port 1883) and \
    ((tcp[20]&0xf6)=0x30) and \
    (tcp[22:2]=26) and \
    (tcp[24:4]=0x504b4743 and tcp[28:4]=0x54524c2f and \
     tcp[32:4]=0x312f7374 and tcp[36:4]=0x61747573 and \
     tcp[40:4]=0x2f667265 and tcp[44:4]=0x7175656e and tcp[48:2]=0x6379)"

从上面对所需过滤器的描述中可以明显看出,过滤器的每个单独组件为您做什么。

在这里,您将获得所需数据包的捕获文件,以后可以根据需要参考。如果愿意,甚至可以将相同的过滤器应用于tshark解决方案,并且还可以写入命名的捕获文件,因为正如我之前解释的那样,无论您是否明确指定,tshark都将数据包写入文件中一个或没有。

注意事项:

  • 为便于说明该解决方案,该过滤器假定TCP头为20个字节,但事实并非如此。如果您想使用更健壮的解决方案来容纳任何TCP标头大小,则需要根据TCP标头的 data offset 字段确定TCP标头大小,该操作可在过滤器中使用{ {1}},然后用该值替换slice运算符的offset字段中每次出现的20。例如,((tcp[12]&0xf0)>>4)*4变成tcp[22:2]=26,等等。

  • 由于MQTT剩余消息长度字段是根据MQTT3.1.1 section 2.2.3 Remaining Length进行可变长度编码的,因此,如上所述,该过滤器仅适用于剩余长度字段的值(从0到127),即剩余长度字段只能是一个字节。鉴于本例中的主题为26个字节,主题长度本身为2个字节,这意味着该过滤器仅适用于99字节或更小(127-(2 + 26))的MQTT消息有效负载。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。