Question Comment puis-je filtrer les pulsations de l'ensemble de répliques MongoDB avec tcpdump?


Parfois, lors du dépannage de la santé d'un jeu de réplicas, j'aimerais filtrer spécifiquement les paquets de pulsation, les suivre en sortant et la réponse ultérieure (ou l'absence de réponse) sans tout le bruit des autres données qui circulent entre les données. ensembles.

Malheureusement, ces paquets sont structurés de la même manière que les commandes / requêtes et réponses normales. Bien que Wireshark a des dissecteurs qui me permettent d’atteindre le protocole filaire MongoDB, je ne peux pas utiliser cette technique pour tcpdump pour filtrer les paquets à la source.

La question est donc: comment filtrer les pulsations du jeu de réplicas MongoDB dans tcpdump?


6
2017-07-09 16:00


origine




Réponses:


Bâtir sur ce document, nous devons d’abord décider de notre caractéristique d’identification afin que le filtre réussisse et ne détecte que les battements de cœur. Ensuite, nous devons obtenir la représentation hexadécimale de cet identifiant. Commençant par le battement de coeur sortant lui-même (qui est essentiellement une requête / commande), il s'agit d'une commande admin et contient la chaîne suivante:

replSetHeartBeat = 0x7265706c536574486561727446265174 (16 bytes)

Maintenant que nous avons la chaîne d'identification, nous devons déterminer où chercher dans TCP. Le décalage est calculé comme suit:

32 octets pour TCP vous amène à la Protocole filaire MongoDB, et alors:

  • 4 octets - longueur du message
  • 4 octets - ID de demande
  • 4 octets - réponse à
  • 4 octets - opcode
  • 4 octets - drapeaux
  • 11 octets - nom de la collection (c'est toujours le même dans ce cas, mais peut varier en général)
  • 4 octets - numtoskip
  • 4 octets - numéro de retour
  • 4 octets - longueur de la documentation
  • 1 octet - type

Par conséquent, le décalage total est: (32 + 4 + 4 + 4 + 4 + 4 + 11 + 4 + 4 + 4 + 1) = 76 octets

Par conséquent, vous penseriez que quelque chose comme ceci est ce qui est requis:

sudo tcpdump -i eth0 'tcp[76:16] = 0x7265706c536574486561727446265174'

Malheureusement, tcpdump n'autorise que jusqu'à 4 octets à la fois, vous devez donc le scinder en blocs de 4 x 4 octets et utiliser un ET logique pour combiner les correspondances:

sudo tcpdump -i eth0 '(tcp[76:4] = 0x7265706c) and (tcp[80:4] = 0x53657448) and (tcp[84:4] = 0x65617274) and (tcp[88:4] = 0x62656174)'

Cela couvre la partie sortante du battement de coeur, mais qu'en est-il de la réponse?

Heureusement, la réponse concernant le battement de coeur est beaucoup plus facile à égaler - nous recherchons la partie vraie du document rs: true, et cela se traduit comme suit, cadrant aisément dans 4 octets:

rs : true = 0x72730001 (4 bytes)

En calculant le décalage de manière similaire (la seule différence réelle est un identifiant de curseur de 8 octets plutôt que le nom de la collection de 11 octets), nous obtenons un décalage de 73 octets, ce qui nous donne ce filtre:

sudo tcpdump -i eth0 'tcp[73:4] = 0x72730001'

Enfin, mettons cela ensemble et ajoutons certaines de mes options préférées de tcpdump. En fin de compte, nous obtenons cette commande:

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'

(Testé avec succès avec MongoDB 2.4.4 sur Mac OS X et Linux)

Bien sûr, cela peut aussi s'appliquer de manière plus générale, il vous suffit de définir les critères de correspondance, les décalages et les correspondances d'octets appropriés.

Pour référence, vous pouvez utiliser les mêmes critères, mais avec une syntaxe légèrement différente pour tester ce type de filtrage dans Wireshark. Les filtres Wireshark équivalents pour les critères ci-dessus sont:

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

10
2017-07-09 16:00