Утіліта для аналізу мережового трафіку tshark

Опублікував Сергій Макаренко 8-05-2015 об 08:40

Якось я підзакинув свій блог. Це перший пост за останні пів року. Весь цей час я займався дуже цікавими речами, які, на жаль, не залишали мені вільного часу для того, щоб шкрябнути сюди кілька рядків. Але на щастя, все змінилося. Чи це, може, через те, що я став трохи дисціплінованішим і зміг знаходити вільні хвилини.

Однією з тих самих цікавих речей, яка віднімає у мене дуже багато часу стала нова робота. Дуже стисло я написав про те, чим зараз займаюся ось тут. Аналіз мережевого трафіку для мене в останні три місяці — річ буденна. До того ж це я вимушений роботи в найсуворіший спосіб: через командний рядок за допомогою утіліти tcpdump. Раніше я не дуже часто стикався з задачами, які потребували використання tcpdump, а зараз вони, м’яко кажучи, дуже специфічні.

Так от, почалося все з того, що на роботі ми знайшли кілька досить серьйозних для нас багів, які не дозволяли повноцінно використовувати свічі Edge Core ECS 4620-52T в нашому продукті. Однією з таких проблем було те, що при певних умовах SNMP-трапи про стан портів на свічі приходили далеко не в реальному режимі часу. В свою чергу для нас критично оброблювати цей потік даних, оскільки певна частина функціональності продукту, в якому ми їх використовували, була зав’язана саме на них.

Ми відправили баг-репорт виробнику і через певнй проміжок часу отримали нову версію прошивки, в якій ця проблема повинна була бути усунена. Звісно, що треба було добряче протестувати нову прошивку і впевнитися в тому, що все працює так, як нам треба. Тест був досить простим. Треба було навантажити свіч і під навантаженням перевірити як приходять трапи про зміну стану певної кількості портів. І ось тут постала проблема. Справа в тому, що tcpdump не має функціональності (або ж я її не знайщов, що вірогідніше), яка б дозволяла відфільтрувати конкретні порти і зміну їх статусів. Інакше кажучи, трапи від всіх портів свіча я побачити можу, а от відфільтрувати трапи тільки від певних портів і їх стан, (наприклад, отримувати трапи тільки коли ifOperStatus змінується з LowLayerDown на Up) у мене змоги немає.

Спочатку я вирішив скористатися для цього утілітою grep і склав команду наступного вигляду дещо поступившись початковими вимогами:

tcpdump -nnn -i eth0 -vvv udp and dst port 162 and src host 10.0.0.0 | grep -E "=1|=57|=58|=59|=60"    

І він успішно працював, показавши, що трапи приходять не тільки з затримкою, але і в хаотичному порядку (наприклад, може прийти трап про зміну статусу двох портів з LowLayerDown на Up, а суттєво пізніше трапи про зміну аналогічного характеру ще трьох портів і п’ять трапів про зміну статусу всіх портів з Up на LowLayerDown). На жаль так відстежувати трапи тільки з конкретними подіями було не можна. Але і це годилося для грубого тесту. Дивлячись на загальну картину надходження трапів без фільтра я помітив, що вони приходять вчасно. Порівнюючи роботу запиту з використанням умови для grep і без неї я звернув увагу на те, що без grep запит працював так, як треба і відображав вчасне надходження трапів. Така поведінка в роботі grep була для мене справжньою несподіванкою. Розбиратися з тим, чому grep так уповільнює вивід tcpdump не було часу і я вирішив погуглити на предмет авльтернативи для tcpdump.

Невдовзі я знайшов консольну утіліту tshark. Це частина потужного аналізатора мережевого траіфку Wireshark. На відміну від tcpdump вона має вичерпну, просту і зрозумілу документацію (наприклад, це частина, яка присвячена аналізу SNMP). Фактично, tshark є консольним аналогом Wireshark. Розібравшись з документацією і скориставшись допомогою Cisco SNMP Object Navigator я склав запит, який повністю відповідав моїм потребам:

tshark -i eth0 dst host 10.0.0.0 and dst port 162 -R "(snmp.name == 1.3.6.1.2.1.2.2.1.1.57 or snmp.name == 1.3.6.1.2.1.2.2.1.1.58 or snmp.name == 1.3.6.1.2.1.2.2.1.1.59 or snmp.name == 1.3.6.1.2.1.2.2.1.1.60 or snmp.name == 1.3.6.1.2.1.2.2.1.1.1) and (snmp.value.oid == 1.3.6.1.6.3.1.1.5.4 or snmp.value.oid == 1.3.6.1.6.3.1.1.5.3)"    

Запит призначений для фільтрації трапів по назві порта (а точніше, для п’яти портів у випадку зміни їх статусів ifOperStatus з LowLayerDown на Up та навпаки) і по значенню Value (OID). Так, запит трохи завеликий, але він працює. До речі, використовував я його в сукупності з tcpdump на зміні статусу групи цільових портів (тому що це дозволяло використовувати запит з tcpdump без grep і, тим самим, перевірити швидкість роботи tshark) і маю задоволення відмітити, що обидві утіліти відображували синхронно інформацію, що надходила від свіча. Є у мене бажання засісти і остаточно розібратися з подібною функціональностю для tcpdump, але це вже, мабуть, тема для окремого поста.