Блог

Wireshark на Modbus TCP: 15-минутный захват, что искать в ответах и exception

SCADA раз в несколько минут «подвисает» на опросе котельной: тренды рвутся, аларм «связь с ПЛК» мигает. Ping до контроллера стабильный. Интегратор подключает ноутбук к SPAN-порту коммутатора, запускает Wireshark на 15 минут и получает сотни тысяч пакетов. Вопрос не «как установить Wireshark», а что именно искать в Modbus TCP за один захват, чтобы не утонуть в шуме.

Пятнадцать минут - типичное окно, за которое проявляется периодическая ошибка: таймаут мастера, exception 02 от слейва, дубли Transaction ID, сброс TCP. Статья даёт практический чек-лист: фильтры display, разбор MBAP, Unit ID, function code, exception codes и признаки retransmit. Не заменяет полный разбор Modbus TCP для интегратора и не учебник по трём режимам RTU/TCP с нуля.

Короткий ответ

Захват Wireshark 15 минут на порту рядом с мастером (SCADA или шлюз) или слейвом (ПЛК) сохраняют в .pcapng с меткой времени начала. Display filter modbus или tcp.port == 502 сужает список. Ищите: запросы без ответа (таймаут), ответы с exception (function code + 0x80), неверный Unit ID, повторяющиеся Transaction ID, TCP Retransmission и RST. MBAP: Transaction ID, Protocol ID = 0, Length, Unit ID - сверьте с картой регистров. Один периодический сбой за 15 минут часто виден как пачка retransmit каждые N секунд. После анализа сопоставьте время с журналом SCADA и циклом ПЛК.

Где ставить захват и зачем 15 минут

SPAN (зеркалирование) порта коммутатора, куда уходит трафик 502, - стандарт на объекте. Врезка TAP лучше, если коммутатор режет ошибки. Захват на самом ПЛК возможен реже - не все контроллеры отдают pcap.

Пятнадцать минут покрывают несколько циклов опроса SCADA (часто 1-5 с на группу регистров) и фоновые события: резервное копирование, NTP, случайный ping. Если ошибка раз в час - увеличьте окно или ставьте ring buffer до появления симптома.

Перед стартом запишите: IP мастера, IP слейва, ожидаемый Unit ID, версия карты регистров, точное время по NTP на ноутбуке и SCADA. На время захвата не гоняйте большие файлы по тому же линку - лишний шум в IO Graph.

Фильтры Wireshark для Modbus TCP

Capture filter (при старте): host 192.168.1.10 and tcp port 502 - уменьшает размер файла. Display filter (после): modbus при установленном dissector. Если пакеты видны как «raw TCP», проверьте, что порт 502 в списке Modbus (Edit - Preferences - Protocols - Modbus).

Полезные комбинации: modbus.func_code == 3 - только Read Holding Registers; modbus.exception_code - все exception-ответы; tcp.analysis.retransmission && tcp.port == 502 - повторы TCP; modbus.unit_id == 1 - конкретный слейв на шлюзе.

Статистика Conversations - TCP покажет, кто больше шлёт - мастер или асимметрия ответов. Statistics - IO Graph по tcp.port==502 - всплески и провалы по времени.

MBAP и Unit ID: первые поля в разборе

Каждый ADU Modbus TCP начинается с MBAP: 2 байта Transaction ID, 2 байта Protocol ID (должен быть 0), 2 байта Length, 1 байт Unit ID, далее PDU (function + data).

Transaction ID мастер увеличивает на каждый запрос; в ответе слейв эхом возвращает тот же ID. Если в захвате ответ с другим ID - шлюз или баг стека. Два запроса с одним ID без ответа между ними - признак повторной отправки после таймаута.

Unit ID на TCP формально «не нужен», но на практике шлюз RTU-TCP маршрутизирует по нему. Неверный Unit ID даёт exception или тишину от нужного слейва при живом трафике на другом ID. Подробнее - в статье про Unit ID и транзакции.

Function code, ответы и exception

Нормальный ответ повторяет function code из запроса (3, 4, 6, 16…). Exception: function code запроса + 0x80, второй байт PDU - код exception.

Частые коды на объекте: 01 Illegal Function - нет такой функции в устройстве; 02 Illegal Data Address - регистр вне карты (самая частая при смене прошивки ПЛК без обновления SCADA); 03 Illegal Data Value - длина или значение запроса неверны; 04 Slave Device Failure - ПЛК в STOP, fault I/O; 06 Slave Device Busy - слейв временно не готов; 0B Gateway Target Failed - slave за шлюзом недоступен.

В Wireshark колонка Info покажет Read Holding Registers или Exception: Illegal data address. Отфильтруйте modbus.exception_code == 2 за 15 минут - если сотни штук, карта регистров не совпадает с проектом.

Таймауты, retransmit и «тишина»

Запрос SYN без ответа до повторного SYN - сеть или firewall. Запрос Modbus ушёл, ACK есть, ответа PDU нет до retransmit мастера - слейв не успел или потерял пакет. Сравните таймауты Modbus RTU vs TCP на реальном объекте: на TCP inter-frame меньше, но SCADA с таймаутом 200 мс при тяжёлом цикле ПЛК 300 мс даёт ложные обрывы.

Паттерн «каждые 60 с пачка retransmit» часто совпадает с фоновой задачей на ПЛК или антивирусом на сервере SCADA, сканирующим подсеть. TCP RST после серии запросов - перезагрузка стека на слейве, смена IP или лимит соединений.

Практический чек-лист на 15 минут

  1. Синхронизировать время ноутбука с SCADA.
  2. Запустить capture на SPAN с filter по IP мастера и слейва.
  3. Воспроизвести симптом (или ждать естественно).
  4. Остановить, сохранить modbus_issue_YYYYMMDD_HHMM.pcapng.
  5. Display modbus.exception_code - выписать коды и адреса регистров.
  6. Display tcp.analysis.retransmission - отметить метки времени.
  7. Statistics - IO Graph по tcp.port==502 - всплески/провалы.
  8. Сопоставить с журналом OPC/SCADA и циклом ПЛК.
  9. Если шлюз RTU/TCP - сверить Unit ID и режим с тремя режимами Modbus.

Не делайте вывод по одному exception без контекста - единичный 06 Busy при download в ПЛК нормален.

Firewall, VLAN и асимметрия

Ping проходит, Modbus нет - классика ACL: разрешён ICMP, закрыт TCP 502 на межсегментном firewall. В pcap на стороне мастера видны SYN без SYN-ACK или RST от фильтра. Асимметричная маршрутизация даёт «обрывчатые» таймауты раз в несколько минут - 15-минутный захват как раз ловит такой паттерн.

Отличие от проблем физического RS-485

На TCP нет CRC RTU и межсимвольных таймаутов - ошибки чаще логические (адрес, Unit ID) или сетевые. Если с шлюзом RTU over TCP в pcap виден только TCP между SCADA и шлюзом, физику RS-485 смотрят на другом порту - Wireshark на 502 не покажет кадры RTU.

Разбор инцидента по временной шкале

Пример: в 14:07:12 SCADA шлёт Read Holding Registers addr 40001, count 20. Ответ exception 02. В 14:07:14 повтор с тем же Transaction ID. В журнале SCADA «timeout», хотя ответ был - драйвер не принял exception как валидный кадр. Действие: исправить карту (регистр смещён после обновления ПЛК). Без pcap спорили бы «сеть рвётся».

Другой пример: каждые 300 с пачка TCP retransmit, exception нет. ПЛК в это время пишет на SD - CPU busy. Решение: сдвинуть опрос SCADA или увеличить интервал «медленной» группы тегов.

Экспорт pcap и передача заказчику

Файл pcapng с промышленной сети - чувствительные данные. Перед отправкой обезличьте IP в отчёте или приложите текстовую выжимку: время, exception code, register. Храните захват с меткой объекта и тикетом - через месяц без контекста «modbus.pcapng» бесполезен.

Несколько мастеров на один ПЛК

Если на одном слейве два мастера (SCADA и панель, или SCADA и MES), в pcap видны переплетённые Transaction ID и редкие коллизии по таймаутам. Симптом: «отваливается раз в 10 минут» без exception. Решение: развести интервалы опроса, увеличить таймаут одного мастера, или ввести шлюз с очередью. В материале для интегратора это разобрано подробнее - в 15-минутном захвате ищите два разных IP source на порт 502 слейва.

Перед пуском объекта один раз снимите «эталонный» pcap при нормальной работе - 15 минут без аварий. При сбое сравнение «было/стало» по IO Graph и частоте exception быстрее, чем абсолютные значения с нуля.

Follow TCP Stream в Wireshark по одной проблемной сессии показывает полный диалог запрос-ответ - удобно приложить скрин к тикету вместо мегабайтного pcap. Для длинных захватов включайте File - Export Packet Dissections - As Plain Text только по отфильтрованным строкам.

На ноутбуке с Wi-Fi отключите обновления и облачную синхронизацию на время захвата - диск и CPU иногда пропускают пакеты при фоновой нагрузке, и вы получите ложные retransmit в отчёте. Для промышленного ПК-анализатора это менее критично, но на объекте чаще именно ноутбук у шкафа.

Пакет, поле и следующий шаг

Пакет / поле Значение / симптом Следующий шаг
MBAP Protocol ID не 0 Не Modbus TCP Проверить порт и протокол
Unit ID не тот Ответ не от того слейва Карта шлюза; настройки RTU
Exception 02 Адрес вне карты Сверить holding map SCADA и ПЛК
Exception 04 Ошибка устройства STOP ПЛК; fault I/O; лог контроллера
Exception 06 подряд Перегрузка слейва Увеличить интервал опроса; разбить запросы
Exception 0x0B Шлюз не видит slave RS-485 за шлюзом; Unit ID
Нет ответа, TCP retransmit Таймаут сети или CPU Нагрузка ПЛК; firewall
TCP RST Сброс соединения Лимит сокетов; перезапуск стека
Дубли Transaction ID Повтор мастера Увеличить timeout; дубликат запроса
Трафик есть, SCADA «нет связи» Неверный mapping OPC Журнал SCADA; не только pcap

Вопросы с пуска

Достаточно ли ping при «нет Modbus»?
Нет. ICMP может проходить, а 502 фильтровать ACL.

Нужен ли dissector modbus в Wireshark 4.x?
Обычно встроен; при «TCP 502» без разбора проверьте Preferences - Protocols.

Можно ли захватывать на производстве без остановки?
Да, SPAN пассивен; согласуйте с ИБ и не нагружайте диск ноутбука.

15 минут мало?
Для редких сбоев - ring buffer до события или ночной захват по cron.

Exception 02 - всегда SCADA виновата?
Чаще карта регистров; но ПЛК мог сменить offset после обновления проекта.

Ссылки по теме

Обсуждение