Приветствую, друг!

Иногда случаются задачи, в которых ты знаешь что делать и решение работает, но как-то не так. Вот это “как-то не так”, если не знаешь куда смотреть, можно искать достаточно долго. Сегодня речь пойдет об одной из таких задач. Небольшой опыт траблшута RTP трафика средствами внутреннего капчера пакетов Fortigate с некоторыми сопутствующими нюансами.

В рамках заметки буду идти по своим следам, т.е более менее по порядку, от загадки к ответу. Тем, кто попал в похожую ситуацию, тыцайте сразу на “Выводы” в оглавлении.

Поиски Offloading в трех соснах

Проблема: Сигнализация SIP работает отлично, но есть проблема с RTP. Звонки проходят отлично, но вот голос на некоторых площадках не проходит.
Задача: Собрать дамп SIP/RTP и предоставить инженеру по телефонии.

Важное условие: Нужно чтобы вкладка Telephony в Wireshark корректно отображала SIP Flows и RTP Streams

Схема взаимодействия

Scheme

Дано: Локальная АТС для SIP сигнализации, некоторое количество медиа-гейтов по регионам для обработки RTP и Fortigate 300E для взаимодействия с внешним миром. С обратной стороны имеем внешнюю АТС и Cisco ASR1001. FG 300E и ASR1001 связаны IPSec туннелем (без GRE и пр.).
Экипировка: Fortigate 300E, FortiOS 7.0.9

Первыми и очевидным решением было пойти в GUI Fortigate и натыкать там Packet Sniffer. Снифер находится в: Network - Packet Capture.

Создаем новый фильтр, от нас требуется обязательно указать интерфейс, остальное по необходимости. Указываем виртуальный интерфейс IPSec туннеля и на этом все. Можно обратить внимание на параметр Maximum Captured Packet установленный в 4000 пакетов, после достижения потолка, захват будет автоматически остановлен, далее идут фильтры, их , в моем случае выставлять не потребовалось т.к мне нужен любой трафик идущий в IPSec туннель.

Capture

Нюанс №1: В GUI нельзя выставить бесконечно количество пакетов для захвата, параметр Maximum Captured Packet выдаст ошибку Please enter a value less than or equal to 10000. если попытаетесь ввести значение больше указанного порога и Please enter a value greater than or equal to 1, если попытаетесь использовать логику команды в CLI, введя 0, что там означает отсутствие лимита.

На этом этапе я решил не обращать на данный нюанс внимания, в случае чего, разобью дебаг на несколько итераций. В последствии выяснилось, один звонок ~1000-1500 пакетов и общий дамп составил ~29 тыс. пакетов.

Фильтр захвата создан, теперь определимся с флоу дебага, у меня он выглядел следующим образом:

  • устанавливаем софтофон на рабочий ноутбук
  • устанавливаем софтину внешней звонилки
  • просим под все это аккаунты, если еще нет
  • составляем список абонентов (была выбрана одна жертва от каждой площадки методом корейского рандома)
    • запускаем созданный фильтр захвата
    • методично идем по списку, делай исходящий звонок
    • просим абонента перезвонить на обратный номер, проверяя входящий звонок
    • останавливаем захват
    • через ПКМ на фильтре из выпадающего списка выбираем download

Тут мы сталкиваемся с еще одним нюансом, а именно Packet size limited during capture: SIP truncated в теле пакета, вместо ожидаемого “мяса”.

Truncated packet

Нюанс №2: При захвате через GUI, размер пакета ограничен стандартным MTU на интерфейсе, с учетом IPSec, в моем случае - 1438, что дает нам Packet size limited during capture: SIP truncated и невозможность увидеть весь пакет.

Подсказка: В фортике значение MTU на VPN интерфейсах можно посмотреть в выводе команды diagnose vpn tunnel list name "<arg>". На месте <arg> имя интерфейса требуется в кавычках.

Но куда интересней было обнаружить основную проблему, после того, как я открыл вкладку Telephony и в SIP Flows увидел многозначительное ничего.

Пакеты есть, а SIP flow нет - непорядок.

CLI Sniffer

Конечно же, я сразу решил, что виноват нюанс с truncated packet и пошел изучать внутреннюю команду disagnose sniffer packet. Ведь ничего более очевидного и быть не могло…(нет)

Спойлер В дальнейшем выяснилось, что это не влияет на построение SIP Flow, но т.к мясо некоторых пакетов все равно срезается, это потенциальная потеря полезной информации при дебаг и далее описанная работа была проделана не напрасно.

В части работы с Fortigate большинство изысканий будут вести вас на их базу знаний, либо форум community. По итогу изысканий, наткнулся на заметку с темой моей проблемы: Technical Tip : How to capture the whole packets when ‘Packet size is limited during capture’ is seen on the captured packets.

Оказалось, команда имеет параметр snaplen, который игнорирует размер пакета и захватывает все в том виде, в котором оно прилетает на выбранный интерфейс. Отлично! Разберем ее подробнее.

Команда имеет вид: diagnose sniffer packet <interface> "<options>" <verbosity level> <count> <timestamp format>

  • diagnose sniffer packet - основная команда
  • interface - тут указываем интерфейс в кавычках
  • options - это наш фильтр, по IP, protocol, etc
  • verbosity level - какую именно информацию собирать (1-6 расписано ниже)
  • count - количество пакетов, которое хотим захватить (0 = Unlimited) А чо так можно было чтоле?
  • timestamp - представление времени в захвате

Параметры verbosity level:

  1. print header of packets
  2. print header and data from ip of packets
  3. print header and data from ethernet of packets (if available)
  4. print header of packets with interface name
  5. print header and data from ip of packets with interface name
  6. print header and data from ethernet of packets (if available) with intf name

Получилось состряпать следующий вариант команды под задачу: diagnose sniffer packet 'SIP Trunk' none 3 0 a snaplen, пробуем запустить и видим, что у нас появилась дополнительная проблема, потому что FG представляет захваченные пакеты следующим образом:

Hex packet

А это значит, что нужно это как-то конвертировать в привычный, хотя бы, .pcap. Идем разбираться дальше.

Продолжая поиски, я наткнулся на еще один документ: Technical Tip: How to import ‘diagnose sniffer packet’ data to WireShark - Ethereal application

Из него следует, что есть инструмент под винду, представленный fgt2eth.exe, либо скрипт на Perl, представленный fgt2eth.pl.zip. Оба файла можно скачать по ссылкам в конце документа.

Заюзаем первый вариант, разобраться оказлось достаточно просто. Копируем fgt2eth.exe в удобную папку -> запускаем в этом месте PS или WinTerminal, в моем случае -> используем саму команду:

fgt2eth.exe -in session.txt -out sip-fgt2eth.pcap

где -in передаваемый текстовый файл, -out ожидаемый файл в формате .cap.

Возможно, что-то я делал не так т.к сперва у меня не составило труда конвертировать полученный дамп, однако в последующие разы, я получил дополнительную ошибку Inconsistent offset. Expecting 10, got 10. Ignoring rest of packet:

fgt2eth error

И, конечно же, очередной нюанс, который уже не зависел от прямоты моих рук:

fg empty ethernet

Нюанс №3: FG не захватывает заголовки канального уровня в VPN/Tunnel интерфейсах. Это можно увидеть по значению 0x45 в начале каждого пакета, что говорит о том, что это IPv4.

Почему происходит ошибка Inconsistent offset. Expecting 10, got 10. Ignoring rest of packet, я пока не понял, но очень похоже на то, что text2pcap некорректно распознает хекс из входного файла, ошибочно считая часть данных заголовком Ethernet и дальше уже едет весь файл. Если сталкивались и знаете, буду рад почитать в комментариях.

editcap

Вернемся к нюансу, его вполне успешно можно победить, объяснив wireshark как нужно распознавать пакеты, а именно, начиная с IP. Сделаем это с помощью стандартной утилиты в комплекте с Wireshark - editcap.

Утилита достаточно комплексная, всю не изучал, но поможет нам следующая команда:

editcap -T rawip -F pcap path_to_src_file\src.pcap path_to_src_fix_file\src_fix.pcap

где -T <тип инкапсуляции="">, означает установить тип инкапсуляции выходного файла; (по умолчанию тот же, что и входной файл.). Иными словами, мы должны в новом файле сказать, что все пакеты нужно воспринимать как чистый IP поток, не смотря на уровни ниже (которых у нас все равно нет).

Подсказка: Чтобы editcap запускался из любого места, проверьте переменную среды PATH на наличие пути до установленного Wireshark, по умолчанию C:\Program Files\Wireshark.

После проделанных манипуляций, Ethernet II мы больше не видим и все пакеты выглядят так, как должны. На месте Ethernet видим, что это “сырой” IP пакет (raw):

rawip

Но получается вот какая штука, у нас изменились и “правильные” пакеты, что наталкивает нас на то, что editcap применяет rawip ко всем пакетам . Снова тупик.

После очередной итерации ресерча интернетов с мыслью “да не может быть, что я один такой”, натолкнулся на fgsniffer.

Работать с ним нужно почти как и с fgt2eth. Качаем zip, внутри exe -> кладем куда нужно и оттуда же запускаем терминал. Работает еще проще, чем fgt2eth т.к съедает на вход .log без каких либо изменений, например из SecureCRT или Putty.
Настраиваете логирование SSH сессии в файл .log -> собираете нужный дамп, схема, описанная выше не изменилась -> используете команду:

fgsniffer session.log

на выходе получаем fgsniffer.pcap, открываем и видим то, что нам и было нужно! Инструмент сконвертировал все без распознавания чего-либо и сделал этот корректно (для текущего этапа). Осталось обработать результат через editcap и вуаял, красивый дамп у нас в кармане. Казалось бы…

editcap fix

Но SIP Flows все равно не появилось. И вот тут стоит сказать спасибо группе FG в телеге, где меня навели на мысль про offloading трафика. Что, в конечном итоге, и оказалось корнем проблемы. Почему я не подумал об этом раньше? Черт его знает, но в свое оправдание, вон сколько полезного откопал в итоге!

Нюанс №4: Некоторые модели FortiGate поддерживают аппаратное ускорение (offloading), т.е оснашены NPU. Типы NPU, которые вы можете увидеть, зависят от модели: NP6, NP6XLite, NP6Lite и NP7. Опция работает по умолчанию и если какой-то трафик может офлоадится, он будет офлоадится.

Победить это очень просто, на момент траблшута, связанного с захватом пакетов, рекомендуется его отключить в связанных с трафиком политиках.

Делается это только в CLI и добраться можно двумя способами:

  1. Либо вы знаете номер (id) политики и тогда команды следующие:
config firewall policy 
(policy) # edit 2

set auto-asic-offload disable
next
end
  1. Если не знаете, в 7.X (с остальными не работал, не знаю) версиях FG точно есть кнопка Edit in CLI в выпадающем меню по каждой политике. Останется только применить команду:
set auto-asic-offload disable
next
end

После этого, желательно, передернуть все сессии, связанные с АТС, например, в моем случае, я дернул сигнализацию SIP на 5060, которая висела в FortiSession как offloading со стороны локальной АТС в сторону внешней АТС.

После описанных злоключений мне удалось собрать нужный дамп и увидеть заветные SIP Flows в полном объеме.

Подсказка: После отключения офлоадинга, SIP Flows стал корректно определяться и в GUI ¯\_(ツ)_/¯. Это не отменяет полезность CLI дампа, но простые дампы можно делать и через GUI.

Выводы

  1. Перед траблшутом на уровне пакетов, отключайте офлоадинг для политик, связанных с трафиком, командой auto-asic-offload disable
  2. Определитесь нужны ли вам следующие моменты, которые без вариантов уведут в CLI. В остальных случаях, хватит и GUI:
    1. Нужен ли Вам расширенный фильтр (например and or not)
    2. Нужен ли Вам объемный дамп (больше 10к пакетов)
    3. Нужен ли Вам захват сразу на всех интерфейсах
    4. Критично ли Вам, если некоторые пакеты будут truncated packet, т.е без “мяса”
  3. Если решили использовать CLI, обратите внимание на инструмент fgsniffer.
  4. Fortigate не добавляет Ethernet заголовки в дампе VPN/Tunnel интерфейсов, небходимо с помощью editcap объяснить шарку смотреть сразу IP, делается командой editcap -T rawip -F pcap path_to_src_file\src.pcap path_to_src_fix_file\src_fix.pcap


Хочешь обсудить тему?

С вопросами, комментариями и/или замечаниями, приходи в чат или подписывайся на Telegram-канал.