Анатомия трафика: Практика анализа пакетов с Wireshark и tcpdump

Курс закладывает фундамент визуального анализа сетевых данных, обучая чтению структуры инкапсулированных протоколов на уровне байтов. Вы освоите инструментарий захвата трафика и научитесь выявлять логические паттерны взаимодействия узлов, необходимые для проектирования систем фильтрации.

1. Методология захвата данных: Работа с интерфейсами и синтаксис фильтров захвата в tcpdump

Методология захвата данных: Работа с интерфейсами и синтаксис фильтров захвата в tcpdump

Представьте, что вы подключились к магистральному маршрутизатору с интерфейсом 10 Гбит/с, чтобы отловить специфичную аномалию в TCP-рукопожатиях, возникающую раз в несколько минут. Если вы просто запустите команду захвата всего проходящего трафика с записью в файл, вы будете сохранять на диск более гигабайта данных каждую секунду. Менее чем через минуту сервер либо исчерпает свободное место, либо «захлебнётся» от нехватки производительности подсистемы ввода-вывода (I/O), так и не решив исходную задачу. Искусство сетевого анализа начинается не с умения читать дампы в Wireshark, а с хирургически точного захвата исключительно тех байтов, которые имеют значение для расследования.

Сетевые интерфейсы и барьер аппаратной фильтрации

Сетевая карта (NIC) сервера по умолчанию работает как строгий фильтр. Кадры, летящие по физической среде (медному кабелю или оптике), достигают порта, после чего контроллер проверяет MAC-адрес назначения. Если MAC-адрес в заголовке кадра не совпадает с аппаратным адресом самой сетевой карты и не является широковещательным (broadcast), контроллер молча отбрасывает этот кадр. Центральный процессор сервера и операционная система даже не узнают о существовании этого пакета.

Для анализа транзитного трафика, который проходит через коммутатор (например, при использовании SPAN-порта) или при прослушивании среды с разделяемой средой передачи, такое поведение неприемлемо. Анализатору нужно видеть всё.

Здесь в игру вступает Promiscuous mode (неразборчивый режим). При запуске утилиты захвата, такой как tcpdump, она отправляет ядру ОС запрос на перевод указанного сетевого интерфейса в этот режим. В promiscuous mode аппаратный фильтр MAC-адресов отключается, и сетевая карта начинает передавать в операционную систему копии абсолютно всех кадров, достигающих физического порта.

!Сравнение обработки пакетов сетевой картой в Normal и Promiscuous режимах

В Linux-системах утилита tcpdump позволяет явно указывать интерфейс для прослушивания с помощью флага -i.

  • tcpdump -i eth0 — захват на конкретном физическом интерфейсе.
  • tcpdump -i lo — захват на loopback-интерфейсе (локальный трафик внутри самого хоста, например, от локального сервиса к локальной базе данных).
  • tcpdump -i any — специальный псевдо-интерфейс в Linux, который собирает трафик со всех активных интерфейсов системы. Важный нюанс: при захвате с any используется специальный тип канального заголовка (Linux cooked capture, SLL), что меняет структуру первых байтов пакета и может сломать фильтры, опирающиеся на жесткие смещения MAC-адресов.
  • Архитектура BPF: Фильтрация в пространстве ядра

    Главная проблема высоконагруженных сетей — стоимость копирования данных. Когда пакет попадает в сетевую карту, он копируется в оперативную память, в пространство ядра (kernel space). Если программа-анализатор (например, tcpdump или Wireshark), работающая в пространстве пользователя (user space), захочет проанализировать пакет, ядру придётся скопировать этот пакет из своей памяти в память программы. Операция копирования (context switch и memory copy) требует процессорного времени. Если копировать миллионы пакетов в секунду, процессор будет занят только обслуживанием захвата.

    Чтобы решить эту проблему, в 1992 году была разработана архитектура BPF (Berkeley Packet Filter).

    Идея BPF гениальна в своей простоте: вместо того чтобы копировать все пакеты в user space и позволять программе решать, нужны они ей или нет, программа компилирует правила фильтрации в специальный байт-код и загружает его прямо в ядро ОС. В ядре работает крошечная, невероятно быстрая виртуальная машина. Она применяет этот байт-код к каждому приходящему пакету до того, как он будет скопирован в пространство пользователя. Если пакет не проходит проверку BPF, он просто отбрасывается на уровне ядра, экономя колоссальные ресурсы.

    !Процесс фильтрации пакета виртуальной машиной BPF в ядре операционной системы

    Именно поэтому синтаксис фильтров в tcpdump (Capture Filters) и синтаксис фильтров в строке поиска Wireshark (Display Filters) кардинально различаются. Capture Filters транслируются в низкоуровневый код BPF для ядра, а Display Filters работают уже с захваченными данными в комфортном пространстве пользователя, где можно позволить себе сложные строковые сравнения и сборку фрагментированных сессий.

    Синтаксис примитивов: Построение фильтров захвата

    Синтаксис BPF-фильтров строится из примитивов, которые состоят из идентификатора (имени или числа) и предшествующих ему квалификаторов. Квалификаторы делятся на три типа:

  • Тип (Type): Указывает, к какой сущности относится идентификатор. Возможные значения: host (узел), net (подсеть), port (порт), portrange (диапазон портов). Если тип не указан, по умолчанию подразумевается host.
  • Направление (Dir): Указывает направление потока. Возможные значения: src (источник), dst (назначение), src or dst, src and dst. По умолчанию подразумевается src or dst.
  • Протокол (Proto): Ограничивает проверку конкретным протоколом. Например: ether, ip, ip6, arp, tcp, udp.
  • Комбинируя эти квалификаторы, мы создаем базовые условия. Рассмотрим несколько примеров:

  • dst host 192.168.1.50 — захватить только те пакеты, где IP-адрес назначения равен 192.168.1.50.
  • src net 10.0.0.0/8 — захватить трафик, исходящий из подсети 10.0.0.0/8.
  • tcp dst port 443 — захватить только TCP-сегменты, направляющиеся на 443 порт.
  • Для создания сложных логических конструкций примитивы объединяются операторами:

  • Конъюнкция: and или &&
  • Дизъюнкция: or или ||
  • Отрицание: not или !
  • Рассмотрим практическую задачу. Нам нужно проанализировать веб-трафик (порты 80 и 443) к нашему серверу, но мы хотим исключить из дампа весь административный SSH-трафик (порт 22), который генерируют инженеры из подсети управления 10.5.5.0/24.

    Команда будет выглядеть так:

    Обратите внимание на одинарные кавычки вокруг фильтра. Они критически важны при работе в терминале Linux, так как символы скобок () и амперсандов && интерпретируются командной оболочкой (bash/zsh) как управляющие символы. Кавычки заставляют оболочку передать строку в tcpdump в неизменном виде.

    Хирургия на уровне байтов: Смещения и битовые маски

    Базовые примитивы отлично справляются с IP-адресами и портами. Но что, если нам нужно заглянуть глубже? Например, поймать только пакеты установки соединения или пакеты определенного размера. Для этого BPF предоставляет механизм прямого доступа к памяти пакета по смещению (offset).

    Синтаксис выглядит так: proto[offset:size].

  • proto — протокол, от начала заголовка которого мы считаем байты (например, ip, tcp, udp, icmp).
  • offset — количество байтов от начала заголовка. Нумерация начинается с нуля.
  • size — количество байтов для чтения (1, 2 или 4). Если не указано, читается 1 байт.
  • Самый классический пример использования смещений — фильтрация по флагам TCP. (Детальную структуру заголовка TCP и состояния сессий мы разберем в отдельной главе, сейчас нас интересует механика работы с байтами).

    Флаги TCP находятся в 13-м байте (смещение 13) от начала TCP-заголовка. Этот байт содержит 8 бит, 6 из которых отвечают за основные флаги:

  • Бит 5: URG (значение )
  • Бит 4: ACK (значение )
  • Бит 3: PSH (значение )
  • Бит 2: RST (значение )
  • Бит 1: SYN (значение )
  • Бит 0: FIN (значение )
  • Если пакет представляет собой запрос на установку соединения (только флаг SYN), значение 13-го байта в десятичной системе будет равно . Фильтр tcp[13] == 2 поймает чистые SYN-пакеты.

    Однако в реальной сети пакет может нести несколько флагов одновременно. Например, ответ сервера (SYN-ACK) содержит установленные флаги SYN () и ACK (). Значение байта будет . Фильтр tcp[13] == 2 проигнорирует такой пакет.

    Чтобы проверить, установлен ли конкретный бит независимо от состояния других битов, применяется побитовая операция И (bitwise AND, обозначается как &). Логика операции такова: мы накладываем «маску» на проверяемый байт. Если бит в маске равен 1, мы смотрим на соответствующий бит в байте. Если бит в маске равен 0, мы его игнорируем.

    Маска для флага SYN равна (в двоичном виде ). Проверим пакет с флагами SYN-ACK (значение , или ):

    Результат равен .

    Проверим пакет только с флагом ACK (значение , или ):

    Результат равен .

    Следовательно, универсальный фильтр для захвата абсолютно всех пакетов, в которых присутствует флаг SYN (будь то чистый SYN или SYN-ACK), выглядит так:

    Этот подход применим к любому протоколу. Например, тип ICMP-сообщения хранится в самом первом байте заголовка ICMP (смещение 0). Эхо-запрос (ping) имеет тип . Фильтр icmp[0] == 8 оставит в дампе только запросы ping, отбросив ответы и сообщения об ошибках маршрутизации.

    Управление процессом захвата: Снапшоты и кольцевые буферы

    Даже при идеальной фильтрации BPF, запись полных пакетов (которые могут достигать 1500 байт в стандартном Ethernet) быстро расходует дисковое пространство. Если ваша задача — анализ сетевой маршрутизации или факта установки соединений, вам не нужно содержимое пакета (payload). Вам нужны только заголовки (Ethernet, IP, TCP/UDP).

    Параметр snaplen (Snapshot Length), задаваемый флагом -s, указывает tcpdump, сколько байт от начала каждого пакета нужно сохранить. Команда tcpdump -s 96 -w headers.pcap обрежет каждый пакет до 96 байт. Этого с запасом хватит, чтобы вместить заголовки L2, L3 и L4, но при этом размер итогового файла дампа уменьшится в десятки раз по сравнению с сохранением полных пакетов. Значение -s 0 в современных версиях утилиты означает захват пакета целиком.

    Для долгосрочного мониторинга используется механизм кольцевых буферов. Вместо записи в один бесконечно растущий файл, tcpdump может разбивать дамп на части и перезаписывать старые файлы по кругу.

  • Флаг -C (заглавная C) задает максимальный размер одного файла в мегабайтах.
  • Флаг -W задает максимальное количество файлов.
  • Эта команда создаст файлы capture.pcap0, capture.pcap1 и так далее. Как только размер текущего файла достигнет 100 МБ, начнется запись в следующий. Когда будет записано 5 файлов (суммарно 500 МБ), tcpdump вернется к первому файлу и перезапишет его. Это гарантирует, что захват никогда не переполнит диск сервера, при этом у вас всегда будет доступ к последним 500 МБ трафика.

    Понимание механизмов работы интерфейсов, архитектуры BPF и битовой математики — это фундамент. Инструменты вроде tcpdump лишь предоставляют интерфейс к этим механизмам. Логика побитовых масок и смещений, которую мы рассмотрели на примере TCP-флагов, лежит в основе написания высокопроизводительных правил для межсетевых экранов и создания первых сигнатур для систем глубокого анализа трафика (DPI), к которым мы перейдем на следующих этапах.

    2. Иерархия инкапсуляции: Деконструкция Ethernet-фреймов и механизмы тегирования VLAN на канальном уровне

    Когда сетевой интерфейс принимает электрический или оптический сигнал, он не видит ни HTTP-запросов, ни TCP-сессий, ни IP-адресов. Он принимает непрерывный поток битов. Первой границей, превращающей этот хаос в структурированную единицу данных, выступает канальный уровень и его базовая структура — Ethernet-кадр. Если анализатор трафика или система глубокого инспекции пакетов (DPI) ошибется при чтении хотя бы одного байта на этом этапе, все вложенные протоколы будут интерпретированы как бессмысленный цифровой шум.

    Анатомия стандарта Ethernet II

    В современных сетях доминирует формат кадра Ethernet II (DIX). Его заголовок отличается минимализмом и занимает ровно 14 байт. Эта фиксированная длина долгое время позволяла сетевому оборудованию обрабатывать трафик аппаратно, с минимальными задержками.

    Структура классического заголовка состоит из трех полей:

  • Destination MAC (6 байт) — физический адрес получателя.
  • Source MAC (6 байт) — физический адрес отправителя.
  • EtherType (2 байта) — идентификатор типа вложенного протокола.
  • Рассмотрим шестнадцатеричный дамп начала типичного кадра: c8 4b 31 11 22 33 00 1a 2b 44 55 66 08 00

    Первые шесть байт c8 4b 31 11 22 33 указывают, куда направляется кадр. Если первые три байта (OUI — Organizationally Unique Identifier) принадлежат известному вендору, Wireshark автоматически подставит имя производителя в интерфейсе. Следующие шесть байт 00 1a 2b 44 55 66 — адрес отправителя.

    Критически важным для анализа является поле EtherType — байты 08 00. Это мультиплексор, который сообщает сетевому стеку операционной системы или парсеру анализатора, какому модулю передать полезную нагрузку (payload). Значение 0x0800 означает, что сразу за этим полем начинается заголовок IPv4. Если бы там было значение 0x86DD, парсер ожидал бы структуру IPv6, а значение 0x0806 указало бы на ARP-запрос.

    Именно поле EtherType связывает канальный уровень с сетевым. Без него кадр был бы «слепым» контейнером.

    Вторжение в заголовок: Тегирование 802.1Q

    Концепция виртуальных локальных сетей (VLAN) потребовала способа логически разделять трафик внутри одного физического коммутатора. Поскольку формат Ethernet II не предусматривал дополнительных полей для идентификаторов сетей, инженерам пришлось модифицировать сам заголовок, внедрив стандарт IEEE 802.1Q.

    !Сравнение классического заголовка Ethernet II и заголовка с тегом 802.1Q

    Внедрение VLAN происходит путем инъекции 4 байт (тега) строго между полем Source MAC и оригинальным полем EtherType. Эта операция сдвигает всю полезную нагрузку на 4 байта вправо.

    Структура 4-байтового тега 802.1Q:

  • TPID (Tag Protocol Identifier, 2 байта). Всегда имеет значение 0x8100. Для парсера пакетов это маркер: «Внимание, оригинальный EtherType смещен, перед вами тег VLAN».
  • TCI (Tag Control Information, 2 байта). Содержит метаданные тега и состоит из трех субполей:
  • - PCP (Priority Code Point, 3 бита) — класс обслуживания (CoS) для приоритизации трафика (QoS). - DEI (Drop Eligible Indicator, 1 бит) — флаг, указывающий, можно ли отбросить кадр при перегрузке сети. - VID (VLAN Identifier, 12 бит) — номер самой виртуальной сети.

    Поскольку под идентификатор сети отведено 12 бит, максимальное количество возможных VLAN вычисляется по формуле . Учитывая, что нулевой и 4095-й идентификаторы зарезервированы стандартами, для использования доступно 4094 сети.

    Проанализируем измененный дамп: c8 4b 31 11 22 33 00 1a 2b 44 55 66 81 00 a0 0a 08 00

    Парсер читает MAC-адреса и доходит до 13-го байта. Вместо ожидаемого протокола сетевого уровня он видит 81 00 (TPID). Это заставляет его прочитать следующие два байта a0 0a как TCI.

    Переведем шестнадцатеричное a0 0a в двоичный формат: 1010 0000 0000 1010.

  • Первые 3 бита 101 (десятичная 5) — высокий приоритет трафика (например, голос или видео).
  • Следующий 1 бит 0 — кадр не подлежит первоочередному отбрасыванию.
  • Оставшиеся 12 бит 0000 0000 1010 (десятичная 10) — это VLAN ID 10.
  • Только после обработки этих 4 байт парсер считывает следующее поле — 08 00, которое теперь выступает истинным EtherType, указывающим на IPv4.

    Динамический парсинг и проблема смещений

    Внедрение 802.1Q разрушило парадигму статических смещений. Ранее мы упоминали, что извлечение данных с помощью фиксированных байтовых отступов (например, поиск флагов TCP строго по смещению от начала кадра) является быстрым, но хрупким методом.

    !Алгоритм пошагового чтения полей заголовка парсером

    Если анализатор жестко запрограммирован искать начало IP-заголовка с 15-го байта (смещение 14), то при появлении VLAN-тега он прочитает байты a0 0a (часть тега) и 08 00 (EtherType) вместо версии IP и длины заголовка. Это приведет к полному разрушению логики разбора: анализатор забракует кадр как поврежденный.

    Современные инструменты, такие как tcpdump и механизмы DPI, используют конечные автоматы (state machines) для разбора заголовков. Когда вы пишете фильтр vlan and tcp port 80 в tcpdump, компилятор BPF генерирует динамический код: он проверяет наличие 0x8100, и если находит его, условным переходом увеличивает базовое смещение для всех последующих проверок сетевого и транспортного уровней на 4 байта.

    Двойная инкапсуляция (Q-in-Q) и влияние на MTU

    В сетях провайдеров связи (ISP) ограничения в 4094 VLAN часто оказывается недостаточно. Кроме того, провайдеру необходимо передавать клиентский трафик (уже содержащий теги 802.1Q) через свою магистраль, не смешивая клиентские сети между собой. Для решения этой задачи применяется стандарт 802.1ad, известный как Q-in-Q.

    Q-in-Q подразумевает вставку второго (внешнего) тега перед внутренним. Внешний тег, называемый Service VLAN (S-VLAN), инкапсулирует клиентский трафик. Внутренний тег остается Customer VLAN (C-VLAN).

    Чтобы сетевое оборудование отличало внешний тег от внутреннего, для S-VLAN используется другой TPID — 0x88A8. Структура заголовка Q-in-Q выглядит так: [Dest MAC] [Src MAC] [0x88A8 + S-TCI] [0x8100 + C-TCI] [EtherType] [Payload]

    Заголовок кадра при этом увеличивается с базовых 14 байт до 22 байт (14 + 4 + 4). Это порождает проблему максимального размера передаваемого блока (MTU). Стандартный MTU для Ethernet составляет 1500 байт полезной нагрузки. Если клиент отправляет полные 1500 байт, добавление тегов провайдером увеличит общий размер физического кадра до 1522 байт (без учета концевика FCS). Если транзитные коммутаторы провайдера жестко настроены на отбрасывание кадров крупнее 1518 или 1522 байт (так называемые baby giant frames), трафик будет молча уничтожаться (blackholing). Поэтому при анализе дампов на магистральных линках важно учитывать размер кадра "на проводе" и настройки MTU на всех узлах.

    Практика: Выявление аномалий канального уровня

    Глубокое понимание структуры Ethernet-кадра позволяет выявлять специфические сетевые атаки, которые не видны на уровне IP или TCP. Одной из классических уязвимостей является атака VLAN Hopping методом двойного тегирования (Double Tagging).

    Атакующий, находящийся в VLAN 10, хочет отправить пакет жертве в VLAN 20, не проходя через маршрутизатор (который мог бы заблокировать трафик межсетевым экраном). Если порт коммутатора, к которому подключен атакующий, настроен как транковый с Native VLAN 10 (сеть, трафик которой передается без тега), злоумышленник формирует специальный кадр.

    Он создает пакет с двумя тегами: внешним VID=10 и внутренним VID=20. Когда первый коммутатор получает этот кадр, он видит внешний тег 10. Поскольку VLAN 10 является для этого транка Native, коммутатор снимает внешний тег (согласно правилам обработки Native VLAN) и пересылает кадр дальше по магистрали. Следующий коммутатор получает кадр, в котором остался только внутренний тег VID=20. Он читает его и послушно доставляет пакет в изолированную сеть VLAN 20.

    В Wireshark такой вредоносный кадр на стороне атакующего будет выглядеть как инкапсуляция 81 00 внутри 81 00. Обнаружение подобных паттернов на портах доступа (access ports), где двойных тегов быть не должно в принципе — прямая задача систем обнаружения вторжений (IDS).

    Канальный уровень формирует жесткий фундамент для всего последующего разбора трафика. Значение EtherType и наличие тегов 802.1Q определяют архитектуру парсинга: они диктуют, на сколько байт нужно сдвинуть указатель, чтобы начать чтение IP-адресов. Способность анализатора корректно обрабатывать эти смещения, распознавать вложенные теги и выявлять аномалии инкапсуляции является базовым требованием для разработки любых систем фильтрации, от простых ACL на коммутаторах до сложных движков глубокой инспекции пакетов.

    3. Структурный анализ IP-пакетов: Поля заголовков, фрагментация и логика маршрутизации на уровне байтов

    Структурный анализ IP-пакетов: Поля заголовков, фрагментация и логика маршрутизации на уровне байтов

    Ситуация из реальной практики: ICMP-эхо (ping) до удалённого сервера проходит без потерь, TCP-рукопожатие завершается успешно, но при попытке загрузить веб-страницу соединение зависает намертво. Проблема кроется в единственном бите IP-заголовка — флаге DF (Don't Fragment), который в сочетании с некорректно настроенным MTU на одном из транзитных маршрутизаторов приводит к тихому отбрасыванию пакетов (PMTUD Blackhole). Чтобы диагностировать подобные аномалии и проектировать системы глубокого анализа трафика, необходимо уметь читать сетевой уровень не как абстрактную концепцию, а как строгую последовательность байтов.

    Анатомия IPv4-заголовка в шестнадцатеричном представлении

    Когда сетевая карта принимает кадр, парсер операционной системы (или ваш BPF-фильтр) отсекает заголовок Ethernet. Если поле EtherType содержало значение 0x0800, следующие байты трактуются как заголовок протокола IPv4. Минимальная длина этого заголовка — 20 байт.

    Рассмотрим начало типичного IP-пакета в дампе: 45 00 00 3c 1a 2b 40 00 40 06 b1 e6 ...

    Первый байт 0x45 — это плотная упаковка двух независимых четырехбитных полей (нибблов). Первая цифра 4 означает версию протокола (IPv4). Вторая цифра 5 — это поле IHL (Internet Header Length), длина заголовка.

    IHL измеряется не в байтах, а в 32-битных словах (по 4 байта). Значение байт. Это стандартный заголовок без дополнительных опций. Если вы встречаете первый байт 0x46, это сигнал для систем безопасности: заголовок содержит опции (24 байта), что часто используется для сетевой разведки (например, опции Record Route или Strict Source Routing). Многие современные межсетевые экраны по умолчанию отбрасывают пакеты с IHL больше 5.

    !Структура заголовка IPv4

    Байты со второго по третий (00 3c) определяют Total Length — общую длину пакета (заголовок IP + полезная нагрузка) в байтах. Значение 0x003c в десятичной системе равно 60. Вычтя из этого 20 байт заголовка, мы понимаем, что размер инкапсулированных данных составляет 40 байт.

    Восьмой байт (40 или 64 в десятичной системе) — это TTL (Time to Live). Изначально задуманный как время жизни пакета в секундах, на практике он работает как счетчик прыжков (хопов). Значение TTL крайне полезно для пассивного определения операционной системы (OS Fingerprinting). По умолчанию Linux инициирует пакеты с TTL 64, Windows использует 128, а сетевое оборудование Cisco — 255. Если к вам пришел пакет с TTL 119, с высокой долей вероятности это Windows-машина, находящаяся в 9 маршрутизаторах от вас ().

    Девятый байт (06) — поле Protocol. Оно выполняет ту же роль мультиплексора, что и EtherType на канальном уровне, но уже для транспортного уровня. Значение 0x06 указывает, что полезная нагрузка является сегментом TCP, 0x11 — датаграммой UDP, а 0x01 — сообщением ICMP. Разработчики DPI-систем часто ищут несоответствия: если поле Protocol указывает на TCP, но структура следующих байтов не соответствует TCP-заголовку, это явный признак обфускации или использования нестандартного стека.

    Механика фрагментации и битовая арифметика

    Сетевые среды имеют ограничения на максимальный размер передаваемого блока данных — MTU (Maximum Transmission Unit). Для стандартного Ethernet MTU равен 1500 байт. Если приложению нужно отправить 4000 байт данных, IP-стек обязан разбить эту полезную нагрузку на фрагменты, чтобы каждый из них поместился в кадр.

    За управление фрагментацией отвечают байты с 4 по 7. Байты 4-5 — Identification (Идентификатор). Все фрагменты одного исходного пакета получают одинаковый идентификатор, чтобы принимающая сторона знала, какие куски собирать вместе.

    Байты 6-7 содержат 3 бита флагов и 13 бит Fragment Offset (смещения фрагмента). Флаги:

  • Бит 0: Зарезервирован (всегда 0).
  • Бит 1: DF (Don't Fragment). Если установлен в 1, маршрутизаторам запрещено фрагментировать пакет. Если пакет превышает MTU следующего канала, маршрутизатор уничтожит его и отправит ICMP-сообщение "Fragmentation Needed".
  • Бит 2: MF (More Fragments). Установлен в 1 у всех фрагментов, кроме последнего.
  • Поле Fragment Offset указывает, с какого места в исходном пакете начинаются данные текущего фрагмента. Из-за того, что под смещение выделено всего 13 бит (максимальное значение 8191), а максимальный размер IP-пакета — 65535 байт, смещение измеряется не в байтах, а в 8-байтовых блоках. . Это архитектурное решение требует, чтобы полезная нагрузка всех фрагментов, кроме последнего, была кратна 8 байтам.

    Разберем процесс фрагментации 4000 байт данных (плюс 20 байт IP-заголовка) при MTU 1500. Максимальный размер данных в одном пакете составит байт (число кратно 8).

  • Первый пакет: Total Length = 1500. Флаг MF = 1. Offset = 0. Передаются байты данных с 0 по 1479.
  • Второй пакет: Total Length = 1500. Флаг MF = 1. Offset = 185. Значение 185 получается делением 1480 на 8. Это означает, что данные начинаются с байта . Передаются байты с 1480 по 2959.
  • Третий пакет: Осталось передать байт данных. Total Length = . Флаг MF = 0 (это последний фрагмент). Offset = 370 ().
  • !Визуализация IP-фрагментации

    Уязвимости сборки: Атака Teardrop

    Фрагментация — это не только механизм доставки, но и классический вектор атак на системы обнаружения вторжений (IDS) и DPI. Что произойдет, если злоумышленник специально сформирует пакеты так, чтобы их смещения перекрывали друг друга?

    Допустим, первый пакет заявляет, что несет данные с 0 по 800 байт. А второй пакет имеет Fragment Offset, указывающий на 600-й байт. Возникает коллизия: данные с 600 по 800 байт присутствуют в обоих фрагментах, но их содержимое отличается.

    Стандарт IPv4 не описывает строго, как операционная система должна разрешать такие конфликты. Windows может предпочесть данные из первого пришедшего фрагмента, а Linux — перезаписать их данными из второго. Если DPI-система собирает фрагменты по логике Windows (пропуская вредоносный код, спрятанный во втором фрагменте), а целевой сервер работает на Linux (который этот код исполнит), атака уклонения будет успешной. Это семейство атак (Teardrop, фрагментарное перекрытие) заставляет современные системы глубокого анализа трафика либо нормализовать трафик (собирать фрагменты у себя и отправлять дальше уже пересобранными), либо полностью блокировать перекрывающиеся фрагменты.

    Логика маршрутизации: Изменения заголовка в транзите

    IP-протокол обеспечивает доставку от источника к назначению (end-to-end), но сам пакет физически передается от маршрутизатора к маршрутизатору (hop-by-hop). При прохождении через каждый маршрутизатор IP-заголовок подвергается модификации.

    Во-первых, маршрутизатор уменьшает значение TTL на 1. Если TTL становится равным нулю, пакет отбрасывается, а отправителю генерируется ICMP Time Exceeded (именно на этом механизме работает утилита traceroute).

    Во-вторых, поскольку изменился хотя бы один байт заголовка (TTL), маршрутизатор обязан пересчитать Header Checksum (байты 10-11). Контрольная сумма вычисляется только для самого IP-заголовка, полезная нагрузка в расчет не берется. Алгоритм представляет собой инвертированную сумму 16-битных слов заголовка. Если при транзите бит в адресе назначения случайно исказится из-за наводок на кабеле, следующий маршрутизатор вычислит контрольную сумму, увидит несовпадение с байтами 10-11 и молча уничтожит пакет.

    Важно понимать, что IP-адреса источника (байты 12-15) и назначения (байты 16-19) остаются неизменными на всем пути следования (если в сети не применяется NAT). Маршрутизатор принимает решение о пересылке, накладывая маску подсети из своей таблицы маршрутизации на Destination IP. При этом на канальном уровне MAC-адреса источника и назначения полностью переписываются на каждом прыжке.

    Понимание того, какие поля IP-заголовка статичны, а какие мутируют в процессе доставки, критически важно для разработки сигнатур. Надежная сигнатура никогда не должна опираться на значения TTL, Checksum или канальные идентификаторы, так как они гарантированно изменятся к моменту, когда пакет достигнет анализатора. Фокус всегда смещается на инкапсулированные протоколы транспортного уровня, где формируются устойчивые сессии.