有时,在排除副本集的健康状况时,我想特别过滤掉心跳包,跟踪它们,然后回复(或缺less),而没有其他数据stream集。
不幸的是,这些数据包的结构与正常的命令/查询和响应非常相似。 虽然Wiresharkparsing器让我能够接触到MongoDB的有线协议,但是我不能用tcpdump的这个技术来过滤掉源数据包。
所以,问题是 – 如何过滤tcpdump中的MongoDB副本集心跳?
在这个文件的基础上,首先我们需要决定我们的特征是什么,以便filter是成功的,只有挑选出心跳。 然后,我们需要得到该标识符的hex表示。 从出站检测信号本身(本质上只是一个查询/命令)开始,它是一个pipe理命令,包含以下string:
replSetHeartBeat = 0x7265706c536574486561727446265174 (16 bytes)
现在我们有了识别string,我们需要弄清楚TCP里面的内容。 偏移量计算如下:
TCP的32个字节让你到达MongoDB有线协议 ,然后:
因此总的偏移量是:(32 + 4 + 4 + 4 + 4 + 4 + 11 + 4 + 4 + 4 + 1)= 76字节
因此,你会认为这样的是什么是必需的:
sudo tcpdump -i eth0 'tcp[76:16] = 0x7265706c536574486561727446265174'
可悲的是,tcpdump一次最多只允许4个字节的匹配,所以你实际上需要把它分解成4×4个字节的块,并使用一个逻辑与来组合这些匹配:
sudo tcpdump -i eth0 '(tcp[76:4] = 0x7265706c) and (tcp[80:4] = 0x53657448) and (tcp[84:4] = 0x65617274) and (tcp[88:4] = 0x62656174)'
这涵盖了心跳的外出部分,但是答复呢?
谢天谢地,对心跳的回复更容易匹配 – 我们正在寻找文档的rs:true部分,并且翻译如下,方便地适合4个字节:
rs : true = 0x72730001 (4 bytes)
以类似的方式计算偏移量(唯一真正的区别是8字节的光标ID而不是11字节的集合名称),我们得到一个73字节的偏移量,得到这个filter:
sudo tcpdump -i eth0 'tcp[73:4] = 0x72730001'
最后,让我们把这些放在一起,并添加一些我喜欢的tcpdump选项。 最后我们得到这个命令:
sudo tcpdump -Xs0 -nnpi eth0 -w heartbeats.pcap '((tcp[76:4] = 0x7265706c) and (tcp[80:4] = 0x53657448) and (tcp[84:4] = 0x65617274) and (tcp[88:4] = 0x62656174)) or tcp[73:4] = 0x72730001'
(在Mac OS X和Linux上成功使用MongoDB 2.4.4进行testing)
当然,这也可以更一般地应用,您只需要制定出适当的匹配标准,偏移和字节匹配。
作为参考,您可以使用相同的标准,但使用稍微不同的语法来testingWireshark中的这种types的过滤。 上述标准的等效Wiresharkfilter是:
tcp[76:16]==72:65:70:6c:53:65:74:48:65:61:72:74:62:65:61:74 tcp[73:4]==72:73:00:01