MTU, фрагментация и чёрные дыры PMTUD
Это урок про самый неприятный класс аварий в сетях: тот, при котором все проверки зелёные. Пинг проходит, трассировка доходит, счётчики чистые, канал свободен — а сервис не работает. Причина в размере пакета, и её невозможно увидеть, пока не начнёшь искать целенаправленно. Инженер, который умеет за минуту проверить эту гипотезу, экономит команде сутки.
«Подняли клиенту туннель до второго офиса. Проверили: пинг идёт, потерь нет, задержка 8 мс, трассировка чистая. Клиента включили. Через час заявка: файловая шара из второго офиса открывается, список файлов виден, а копирование виснет на нуле процентов. Почта уходит, но письма с вложениями застревают. Инженер проверяет ещё раз: пинг идёт, потерь нет. Пишет „у нас всё в порядке, проблема на стороне клиента“.»
Проблема ровно на нашей стороне, и она была создана в момент поднятия туннеля. Разберёмся, что именно произошло и почему стандартная проверка её не видит.
- Почему список файлов виден, а копирование виснет? Ведь и то и другое — один и тот же протокол по одному каналу.
- Пакет не помещается в линию. Кто должен об этом узнать: отправитель, получатель или маршрутизатор на пути?
- В IPv6 маршрутизаторы вообще не режут транзитные пакеты. Это упрощение или усложнение жизни инженера?
- Разведёшь понятия «размер кадра», «предельный размер пакета» и «размер сегмента»
- Посчитаешь накладные расходы VLAN, QinQ, метки транспорта, туннеля и шифрования в октетах
- Разберёшь фрагментацию IPv4 по полям: флаги, смещение, единица измерения смещения
- Поймёшь, почему в IPv6 фрагментацию на пути запретили и что это меняет для эксплуатации
- Объяснишь классический механизм определения предельного размера и где именно едет число
- Научишься с первого взгляда узнавать чёрную дыру и проверять гипотезу за минуту
- Внедришь правку объявляемого размера сегмента — рабочее лечение для трафика TCP
- Освоишь механизм, который работает даже при полностью отфильтрованных служебных сообщениях
- Ping с запретом фрагментации мы уже пробовали — сегодня он станет главным инструментом урока.
- Сообщения об ошибке порождают устройства на пути. Сегодня увидим, что бывает, когда одно конкретное такое сообщение теряется.
- Фильтрация служебных сообщений — обычная практика. В прошлом уроке она мешала диагностике; здесь она ломает работу сервиса.
1. Три числа, которые постоянно путают
MTU
Максимальный размер пакета IP, который линия переносит целиком. Заголовки канального уровня в него не входят. Для обычного Ethernet это 1500 октетов.
Размер кадра
Всё, что летит по проводу: заголовок Ethernet, пакет IP, контрольная сумма кадра. Всегда больше MTU — на величину служебных полей канального уровня.
MSS
Максимальный размер данных в сегменте TCP. Меньше MTU на размер фиксированных заголовков: для IPv4 это 20 октетов заголовка IP плюс 20 октетов заголовка TCP.
Правило пересчёта зафиксировано в RFC 6691: «When calculating the value to put in the TCP MSS option, the MTU value SHOULD be decreased by only the size of the fixed IP and TCP headers and SHOULD NOT be decreased to account for any possible IP or TCP options». То есть классическое «MTU минус 40» для IPv4 — это не упрощение, а прямое требование стандарта. Опции при этом учитываются отдельно: отправитель обязан сам урезать данные, если добавляет опции в конкретный пакет.
- 1500 — MTU обычного Ethernet, отсюда MSS 1460 для IPv4.
- 1492 — MTU поверх PPPoE. RFC 2516: заголовок PPPoE 6 октетов плюс идентификатор протокола PPP 2 октета, поэтому «the PPP MTU MUST NOT be greater than 1492».
- 1280 — минимальный размер, который обязана нести любая линия в IPv6 (RFC 8200).
- 576 — размер, который обязан принять любой узел IPv4 (RFC 791).
- 68 — размер, который обязан переслать без фрагментации любой узел IPv4 (там же).
2. Куда девается место: накладные расходы по октетам
Каждый слой упаковки отъедает от полезного размера. Считать это нужно уметь в уме, потому что ошибка в четыре октета — это работающий пинг и неработающий сервис.
Каждый слой упаковки уменьшает полезный размер. Пропорции на схеме условные — важен принцип и точные числа справа.
| Что добавляется | Октетов | Источник числа |
|---|---|---|
| Метка VLAN | 4 | Тег IEEE 802.1Q |
| Вторая метка (QinQ) | ещё 4 | Второй тег того же формата |
| Одна метка транспорта | 4 | Метка MPLS фиксированной длины |
| PPPoE | 8 | RFC 2516: 6 заголовок + 2 идентификатор протокола |
| Туннель GRE поверх IPv4 | 24 | RFC 2784: обязательный заголовок GRE 4 + внешний IPv4 20 |
| Внешний заголовок IPv6 | 40 | RFC 8200: фиксированный заголовок |
Шифрование добавляет больше и, что хуже, переменную величину: к внешнему заголовку добавляются служебные поля и выравнивание до размера блока шифра. Именно поэтому для шифрованных туннелей размер никогда не считают «по формуле из памяти», а измеряют приёмом из раздела 6 этого урока.
3. Фрагментация IPv4: как это работает и почему это плохо
Когда пакет не помещается в следующую линию, у маршрутизатора IPv4 есть два выхода: разрезать пакет или отбросить его. Выбор определяет один бит в заголовке. RFC 791 задаёт поле флагов так: «Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment; Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments». Смещение фрагмента при этом измеряется «in units of 8 octets» — отсюда, кстати, требование кратности восьми при подборе размеров.
Почему фрагментация — плохой вариант, даже когда она разрешена:
- Собирает только получатель. Промежуточные узлы фрагменты не склеивают, поэтому разрезанный пакет едет фрагментами до самого конца, занимая больше ресурсов.
- Потеря одного фрагмента убивает весь пакет. Потеряли один из трёх — придётся передавать заново все три. Эффективная вероятность потери растёт.
- Заголовки транспорта есть только в первом фрагменте. Устройства, принимающие решения по номеру порта — фильтры, балансировщики, распределение по путям, — во втором и третьем фрагменте портов не видят и вынуждены гадать.
- Резать приходится процессору. Микросхема пересылки этого обычно не делает, и трафик уходит на медленный путь внутри устройства.
Поэтому все нормальные реализации TCP ставят запрет фрагментации и полагаются на механизм определения предельного размера пути. А в IPv6 вопрос решён радикально.
4. IPv6: фрагментации на пути нет вообще
RFC 8200 формулирует прямо: «fragmentation in IPv6 is performed only by source nodes, not by routers along a packet's delivery path». Маршрутизатор, которому пакет не влезает в следующую линию, обязан его отбросить и отправить сообщение «пакет слишком велик» с указанием размера.
Чтобы такая жёсткость была безопасной, стандарт задаёт минимум: «IPv6 requires that every link in the Internet have an MTU of 1280 octets or greater», а линия, которая физически этого не может, обязана резать и собирать пакеты сама, ниже уровня IPv6. Для линий с настраиваемым размером рекомендуется 1500 октетов и больше — прямо ради возможных инкапсуляций.
И ещё одна практичная деталь оттуда же: узел, который не хочет реализовывать определение предельного размера, вправе просто никогда не слать пакеты больше 1280 октетов. Это законный и рабочий, хотя и неэффективный способ никогда не сталкиваться с проблемой.
5. Классический механизм определения предельного размера
Механизм описан в RFC 1191 и устроен так:
- Отправитель ставит на пакеты запрет фрагментации и шлёт их размером своей линии.
- Маршрутизатор, которому пакет не влезает, отбрасывает его и отправляет обратно сообщение «узел недостижим, код 4: нужна фрагментация, а она запрещена».
- Ключевая деталь: RFC 1191 добавил в это сообщение размер следующего участка. Он лежит в младших 16 битах поля заголовка, которое в RFC 792 было помечено как неиспользуемое. Это «the size in octets of the largest datagram that could be forwarded without being fragmented at this router».
- Отправитель уменьшает размер до полученного числа и повторяет передачу.
В IPv6 та же логика оформлена аккуратнее: под это выделен отдельный тип сообщения — «пакет слишком велик» — с полем MTU в явном виде (RFC 4443).
RFC 1191 требует и стареть найденное значение: «When a PMTU value has not been decreased for a while (on the order of 10 minutes), the PMTU estimate should be set to the first-hop data-link MTU» — иначе после устранения узкого места отправитель навсегда остался бы с заниженным размером.
6. Чёрная дыра: когда механизм ломается
Весь механизм держится на одном служебном сообщении. Если оно не доходит — отфильтровано на межсетевом экране, отброшено при ограничении частоты, потеряно на асимметричном обратном пути, — отправитель не узнаёт ничего. Он продолжает слать пакеты полного размера, они молча исчезают, и он лишь повторяет передачу с тем же результатом.
RFC 4821 называет это прямо: «Classical Path MTU Discovery is subject to protocol failures (connection hangs) if ICMP Packet Too Big (PTB) messages are not delivered or processed for some reason».
Разница между исправной сетью и чёрной дырой — одно служебное сообщение. Именно поэтому симптом выглядит как «всё зелёное, но не работает».
- «Сайт открывается, но не полностью» / «страница висит на загрузке».
- «Список файлов виден, копирование зависает на нуле».
- «Почта ходит, письма с вложениями застревают».
- «Соединение с сервером устанавливается, потом обрыв по таймауту».
- «Через туннель не работает, напрямую работает».
- И при этом: пинг идёт, потерь нет, трассировка чистая.
Общий признак один: маленькое проходит, большое — нет. Установка соединения, запросы имён, короткие команды — всё это мелкие пакеты. Передача данных — крупные.
Проверка гипотезы занимает минуту:
# Точка перелома ищется перебором с запретом фрагментации.
# Данные + 8 (ICMP) + 20 (IP) = размер пакета.
Linux: ping -M do -s 1472 -c 2 <цель> # пакет 1500
ping -M do -s 1400 -c 2 <цель> # пакет 1428
ping -M do -s 1372 -c 2 <цель> # пакет 1400
Windows: ping -f -l 1472 -n 2 <цель>
macOS: ping -D -s 1472 -c 2 <цель>
Смотри не только на факт прохождения, но и на вид отказа. Если приходит «требуется фрагментация» с указанием размера — механизм работает, отправителю просто надо подчиниться. Если пакет исчезает молча — служебное сообщение отфильтровано, и это и есть чёрная дыра.
7. Рабочее лечение: правка объявляемого размера сегмента
Чинить чёрную дыру «правильно» — значит найти того, кто фильтрует служебные сообщения, и убедить его перестать. В чужой сети это не всегда возможно, и никогда — быстро. Поэтому существует лечение, которое работает на своей стороне и не требует ничего ни от кого.
Идея: перехватить пакеты установки соединения TCP и уменьшить в них объявляемый размер сегмента до значения, которое гарантированно проходит. Стороны договорятся о меньшем размере с самого начала и никогда не создадут слишком крупный пакет — служебное сообщение просто не понадобится.
Linux (iptables):
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
Cisco IOS (на интерфейсе туннеля):
ip tcp adjust-mss 1360
Juniper Junos (на интерфейсе):
set security flow tcp-mss all-tcp mss 1360
Откуда 1360: если по туннелю реально проходит пакет 1400 октетов, то для IPv4 размер сегмента равен 1400 − 40 = 1360. Значение подбирается по измеренному предельному размеру, а не «по опыту».
Приём работает только для TCP: он опирается на согласование размера при установке соединения. Трафик UDP — а это, например, туннели, голос и часть современных веб-протоколов — им не лечится вовсе. Для UDP остаётся либо чинить фильтрацию, либо задавать размер на самом приложении.
8. Механизм, которому служебные сообщения не нужны
RFC 4821 предлагает решение на уровне самого протокола передачи: не спрашивать сеть, а пробовать. Отправитель шлёт пробы растущего размера и делает вывод по факту:
- «When the probe is delivered, it is an indication that the Path MTU is at least as large as the probe size» — доставленная проба поднимает нижнюю границу.
- Если потеряна только проба, а соседние пакеты дошли, это трактуется как признак ограничения размера, «and not as a congestion indicator» — важная деталь, иначе алгоритм спутал бы это с перегрузкой и зря снизил скорость.
Документ приводит и ориентиры для старта: значение 1024 октета названо достаточно безопасной нижней границей, 1400 — разумным компромиссом для начального значения, 1280 — минимум для IPv6. При полной остановке передачи предписано считать ситуацию чёрной дырой и опускаться к нижней границе, а при повторных тайм-аутах — делить её пополам, но не ниже 68 октетов для IPv4.
Практический вывод для эксплуатации: современные стеки такой механизм имеют, и часть старых «неизлечимых» проблем с размером сегодня рассасывается сама. Но полагаться на это нельзя: сетевое оборудование, встроенные системы и многие туннели по-прежнему живут на классическом механизме.
9. Плейбук: подозрение на проблему размера
- Подтвердить симптом. Мелкое ходит, крупное нет. Проверить, что пинг обычного размера идёт без потерь — это отсекает обычную аварию связности.
- Измерить точку перелома. Перебором с запретом фрагментации найти максимальный проходящий размер. Шаг 8 октетов — смещение фрагмента кратно восьми.
- Определить вид отказа. Пришло сообщение с размером — механизм жив. Молчание — чёрная дыра.
- Найти виновный участок. Повторить измерение до промежуточных узлов трассы: до какого размер полный, после какого падает — там и находится узкое место.
- Посчитать накладные расходы. Сверить измеренное число с расчётным по таблице раздела 2. Расхождение означает лишний слой упаковки, о котором ты не знал.
- Применить лечение. Для TCP — правка объявляемого размера сегмента на своей границе. Для UDP — устранение фильтрации либо настройка приложения.
- Проверить результат тем же измерением и приложить оба вывода — «до» и «после» — к заявке.
10. Мини-лаба: попробуй прямо сейчас
Шаг 1. Узнать MTU своих интерфейсов.
Linux: ip link show
macOS: ifconfig | grep mtu
Windows: netsh interface ipv4 show subinterfaces
Ожидаемый результат: у проводного интерфейса 1500. Если меньше — у тебя PPPoE или туннель, запиши значение.
Шаг 2. Найти точку перелома до внешнего узла.
Linux: for s in 1472 1464 1456 1440 1400 1372; do \
echo -n "$s: "; ping -M do -s $s -c 1 -W 2 1.1.1.1 >/dev/null 2>&1 \
&& echo прошло || echo нет; done
Windows: ping -f -l 1472 -n 1 1.1.1.1
ping -f -l 1400 -n 1 1.1.1.1
Ожидаемый результат: на домашнем канале через Ethernet проходят все размеры до 1472. Через PPPoE перелом будет около 1464. Прибавь 28 к найденному числу — получишь предельный размер пакета на пути.
Шаг 3. Отличить честный отказ от чёрной дыры.
Linux: ping -M do -s 1500 -c 2 1.1.1.1
Windows: ping -f -l 1500 -n 2 1.1.1.1
Ожидаемый результат: в норме приходит явное сообщение о необходимости
фрагментации с указанием размера — в Linux строка вида
Frag needed and DF set (mtu = 1500), в Windows —
«Требуется фрагментация пакета». Полная тишина вместо сообщения означает,
что служебные сообщения на пути отфильтрованы.
Шаг 4. Посмотреть, что запомнила система.
Linux: ip route get 1.1.1.1
ip route show cache # на старых ядрах
Windows: netsh interface ipv4 show destinationcache
Ожидаемый результат: для направлений с уменьшенным размером система хранит найденное значение отдельной записью. Это и есть результат работы механизма, который мы разобрали.
11. Задачи самопроверки
1. Вернись к ситуации в начале урока. Что именно сломалось при поднятии туннеля и почему пинг этого не показал?
Туннель добавил заголовок доставки, и полезный размер внутри него стал меньше 1500. Клиентские устройства об этом не знают и продолжают слать пакеты полного размера с запретом фрагментации. Они не влезают, отбрасываются, а служебное сообщение о превышении либо не порождается, либо не доходит. Пинг по умолчанию шлёт короткий пакет — он проходит без проблем и потому ничего не показывает. Лечение: измерить реальный предельный размер и настроить правку объявляемого размера сегмента на интерфейсе туннеля.
2. Почему «список файлов открывается, а копирование виснет» — это почти диагноз?
Потому что перечисление каталога — короткий обмен небольшими пакетами, а копирование сразу переходит к пакетам полного размера. Разделение симптома строго по размеру пакета, а не по протоколу, времени или адресату, оставляет очень мало объяснений, и ограничение размера с потерянным служебным сообщением — первое из них.
3. Ты измерил: проходит 1400, не проходит 1408. Какой предельный размер пакета на пути и какое значение размера сегмента ставить?
Данные 1400 плюс 8 октетов ICMP плюс 20 октетов IP дают 1428 октетов — это предельный размер пакета на пути. Размер сегмента для IPv4 равен 1428 − 40 = 1388. На практике берут небольшой запас на случай дополнительного слоя упаковки. Полезно также посчитать, что 1500 − 1428 = 72 октета накладных расходов, и сверить это с таблицей: такое число не объясняется одним туннелем, значит слоёв несколько.
4. Почему правка объявляемого размера сегмента не спасёт голосовой трафик через тот же туннель?
Голос идёт поверх UDP, а приём опирается на согласование размера при установке соединения TCP — у UDP такого согласования нет. Впрочем, голосовые пакеты обычно мелкие, и проблема размера их редко задевает. Опасность в другом трафике поверх UDP: туннелях внутри туннеля и современных веб-протоколах, работающих поверх UDP, которым нужен полный размер.
5. Ты видишь, что пакет 1500 не проходит, зато приходит внятное сообщение с указанием размера 1400. Это авария?
Нет, это штатная работа механизма определения предельного размера: сеть честно сообщила отправителю, чего она ждёт, и он подстроится. Авария — это когда такого сообщения нет. Единственное, что здесь стоит сделать, — записать в паспорт линии, что предельный размер на этом направлении 1400, и проверить, нет ли на пути лишнего слоя упаковки, который можно убрать.
6. Оператор говорит: «мы включили большие кадры на магистрали, теперь у вас проблем не будет». Почему это не гарантия?
Потому что предельный размер пути определяется самым узким участком, а не магистралью. Если хотя бы один сегмент на пути — включая последнюю милю клиента, туннель или чужого оператора в середине — остался на меньшем значении, ограничение сохранится. Увеличение размера полезно, но проверяется оно измерением от края до края, а не заявлением одного из участников.
12. Словарик урока
| Термин | English | Что означает |
|---|---|---|
| Предельный размер пакета | MTU, Maximum Transmission Unit | Наибольший пакет IP, который линия несёт целиком |
| Предельный размер на пути | Path MTU | Минимум из MTU всех участков пути |
| Размер сегмента | MSS, Maximum Segment Size | Данные в сегменте TCP: MTU минус фиксированные заголовки |
| Запрет фрагментации | Don't Fragment, DF | Бит 1 поля флагов IPv4: не резать, а отбросить |
| Ещё фрагменты | More Fragments, MF | Бит 2 поля флагов: пакет продолжается |
| Определение размера на пути | PMTUD | Механизм RFC 1191 на служебных сообщениях |
| Определение размера пробами | PLPMTUD | Механизм RFC 4821, служебные сообщения не нужны |
| Чёрная дыра | PMTUD black hole | Крупные пакеты пропадают молча, отправитель не уведомлён |
| Правка размера сегмента | MSS clamping | Уменьшение объявляемого размера при установке соединения |
13. Главное
- Симптом «мелкое ходит, крупное нет» — это почти всегда размер пакета. Проверяется за минуту, стоит проверять раньше всего остального.
- Пинг по умолчанию мелкий и потому этот класс аварий не видит вообще.
- MSS = MTU − 40 для IPv4 — не эмпирика, а требование RFC 6691: вычитаются только фиксированные заголовки.
- Каждый слой упаковки нужно считать в октетах: метка 4, QinQ 8, PPPoE 8, GRE поверх IPv4 — 24. Ошибка в четыре октета ломает сервис при рабочем пинге.
- В IPv6 маршрутизаторы транзит не режут вообще, минимум линии — 1280 октетов.
- Классический механизм держится на одном служебном сообщении. Отфильтровали — получили чёрную дыру и зависающие соединения.
- Правка объявляемого размера сегмента лечит TCP на своей стороне и совсем не помогает UDP.
- Отличай честный отказ от молчания. Сообщение с размером — механизм работает; тишина — механизм сломан.
14. Мост к следующему уроку
Теперь известно всё, что нужно, чтобы честно измерить главное — скорость. Именно в таком порядке требует действовать RFC 6349: сначала определить предельный размер пакета на пути, потом снять базовое время прохождения, и только потом мерить полосу. В следующем уроке разберём iperf3: почему канал 1 Гбит/с с задержкой 30 мс не даёт скорость при стандартных настройках, как посчитать нужное окно по формуле, что означает каждая колонка отчёта — и семь способов провести измерение так, что результату нельзя верить.
15. Источники
- RFC 791 — поле флагов (биты DF и MF), смещение фрагмента в единицах по 8 октетов, правила 576 и 68 октетов
- RFC 1191 — Path MTU Discovery: размер следующего участка в младших 16 битах ранее неиспользуемого поля, старение оценки порядка 10 минут
- RFC 4821 — PLPMTUD: формулировка проблемы зависаний при недоставке служебных сообщений, трактовка потери одиночной пробы, ориентиры 1024, 1400 и 1280 октетов, нижняя граница 68
- RFC 8200 — фрагментация только источником, минимум линии 1280 октетов, рекомендация 1500 для настраиваемых линий
- RFC 4443 — отдельный тип сообщения «пакет слишком велик» с полем MTU
- RFC 6691 — расчёт размера сегмента: вычитаются только фиксированные заголовки IP и TCP
- RFC 2516 — PPPoE: 6 октетов заголовка плюс 2 октета идентификатора протокола, предел 1492
- RFC 2784 — GRE: обязательный заголовок 4 октета, с внешним IPv4 суммарно 24 октета