Как фильтровать трафик MQTT на основе названия темы в tcpdump

#mqtt #wireshark #tcpdump

#mqtt #wireshark #tcpdump

Вопрос:

Я собираю трафик 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                                    . .(.
  

Комментарии:

1. Вы пробовали использовать tshark версию wireshark для командной строки?

2. Возможно, вам повезет больше с использованием какого-либо клиента MQTT, поскольку он больше подходит для захвата только тем и полезных нагрузок. Есть из чего выбирать. Я сделал свой собственный в качестве учебного эксперимента: github.com/john2exonets/MQTT-Packet-Monitor

Ответ №1:

Я не думаю, что ранее принятый ответ обязательно делает то, что вы думаете, и, возможно, даже не то, что вы хотите, чтобы он делал. В исходном вопросе говорилось: «Но это приводит к очень большому файлу в течение нескольких минут, могу ли я фильтровать tcpdump на основе названия темы»

Если вы пытаетесь ограничить размер файла захвата, то ранее принятый ответ этого не делает, потому что он использует точно такой же фильтр захвата, который был предоставлен изначально, а именно src 10.x.x.x . Это означает, что вы собираете тот же объем данных, что и раньше. То, что имя файла захвата не было указано, не означает, что пакеты не записываются в файл; они есть. В случае tshark , пакеты записываются во временный файл, который будет продолжать расти до завершения сеанса захвата, а затем в идеале он будет удален, но не всегда. Расположение временного файла зависит от платформы, на которой tshark выполняется, но вы должны быть в состоянии легко найти каталог, запустив tshark -G folders | grep "^Temp" .


Теперь, если вы хотите уменьшить размер файла захвата или количество пакетов, которые вы видите, вы должны иметь возможность изменять tcpdump tshark аргументы командной строки or для достижения этой цели.

Во-первых, если вам не нужна вся полезная нагрузка, вы можете применить snaplen для сокращения пакетов после некоторого соответствующего значения. Это делается с помощью -s опции, и это та же опция для любого инструмента захвата.

Хорошо, но независимо от того, решите ли вы применить snaplen или нет, если вы хотите фильтровать на основе названия конкретной темы, скорее всего, вы сможете этого добиться; однако есть пара предостережений, которые я перечислил ниже. Основная идея заключается в использовании оператора slice [] (см. справочную страницу pcap-filter) для сравнения различных байтов полезной нагрузки TCP с определенными значениями. (ПРИМЕЧАНИЕ: ни tcpdump сам, ни pcap-filter ссылается на этот оператор как на оператор среза, но wireshark-filter делает, поэтому я тоже.) Таким образом, фильтр должен:

  • Сопоставляйте пакеты только с / с определенного хоста, в данном случае 10.x.x.x
  • Сопоставляйте только пакеты MQTT (обычно по номеру порта, который, как я предполагаю, является стандартным портом tcp / 1883)
  • Сопоставлять только ПУБЛИКУЕМЫЕ сообщения с QoS 0
  • Сопоставлять только ПУБЛИКУЕМЫЕ сообщения, длина темы которых составляет 26 байт
  • Сопоставлять только ПУБЛИКУЕМЫЕ сообщения, в которых тема «PKGCTRL / 1 / статус / частота»

Вот команда, которая должна работать (по крайней мере, в большинстве случаев -> см. Предостережения ниже):

 tcpdump -i team0 -w mqtt-trace.pcap 
    "(src host 10.x.x.x) and 
    (tcp port 1883) and 
    ((tcp[20]amp;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 из поля смещения данных заголовка TCP, что выполняется в фильтре с использованием ((tcp[12]amp;0xf0)>>4)*4 , а затем заменить каждое вхождение 20 в поле смещения оператора slice на это значение. Так tcp[22:2]=26 , например, tcp[(((tcp[12]amp;0xf0)>>4)*4) 2:2]=26 становится и т.д.

  • Поскольку поле оставшейся длины сообщения MQTT кодируется переменной длиной в соответствии с разделом 2.2.3 оставшейся длины MQTT3.1.1, фильтр, как указано выше, будет работать только для значений поля оставшейся длины от 0 до 127, т.Е. Поле оставшейся длины должно быть только одним байтом. Учитывая, что тема в этом случае составляет 26 байт, а длина самой темы составляет 2 байта, это означает, что фильтр будет работать только для полезной нагрузки сообщений MQTT размером 99 байт или меньше (127 — (2 26)).

Комментарии:

1. Большое спасибо за подробный ответ, да, я подтвердил, что он создавал временный файл в каталоге / tmp.

2. Это хороший и подробный ответ (как обычно). В вашем ответе неясно, почему вы разбиваете тему MQTT на 4 байта каждый. Требуется ли это tcpdump?

3. «В вашем ответе неясно, почему вы разбиваете тему MQTT на 4 байта каждый. Требуется ли это для tcpdump?» Да. Вы не можете указывать произвольную длину в выражениях, таких как tcp[40:4]=0x2f667265 — сравнение должно быть с 1, 2 или 4 байтами.

4. Хотя «сравнение должно быть с 1, 2 или 4 байтами» , я думаю, что, вероятно, отсутствует четкая документация об этом на странице руководства pcap-filter. Я даже не знаю, откуда я это знаю, поскольку я не могу вспомнить, где я впервые узнал об этом. И, может быть, slice — не лучшее имя для этого оператора, поскольку оно относится к фильтрам захвата, потому что оператор среза Wireshark допускает произвольную длину, поэтому семантика отличается? Я не знаю, как еще это назвать.

5. По-видимому, на странице руководства pcap-fitler есть четкая документация, и я просто пропустил ее, потому что мои глаза ранее сканировали цифры, когда вместо этого цифры просто записывались словами. Вот соответствующий текст со страницы руководства: Размер не является обязательным и указывает количество байтов в интересующей области; это может быть один, два или четыре, а по умолчанию один ..

Ответ №2:

Как предложил @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 .

Комментарии:

1. Я получаю сообщение об ошибке tshark: "/" was unexpected in this context.