Обнаружение MTU пути через VPN: размер и разрыв с ICMP
Туннель уменьшает пакет, который путь может перенести, и обнаружение работает только тогда, когда приходит обратная связь. Измеряйте, проверяйте и подтверждайте путь вместо угадывания.
Туннель завершает рукопожатие, небольшие запросы возвращаются, а первая большая передача зависает. Эта картина указывает на MTU пути гораздо раньше, чем на пропускную способность. Каждое звено на маршруте ограничивает размер пакета, а инкапсуляция тратит часть этого лимита на внешние заголовки, поэтому внутренний пакет должен быть меньше, чем предполагала бы сырая дорога. Отказ безмолвен, и именно поэтому его дорого диагностировать.
Что на самом деле измеряет MTU пути
MTU пути — это наименьший MTU звена на маршруте между двумя хостами, а не MTU, напечатанный на локальном интерфейсе. Локальное значение — точка, с которой начинается оценка, а путь решает, где она должна закончиться. Поэтому одинаковый туннель может работать в одной сети доступа и застревать в другой: изменился маршрут, а не конфигурация. Измерить один раз и предполагать везде — ошибка, которая поддерживает эту проблему живой.
Для туннеля важное число — внутренний MTU, то есть лимит внешнего пути минус то, что потребляет инкапсуляция. WireGuard добавляет внешний заголовок IP и заголовок UDP; другие транспорты добавляют свои. Задайте внутренний размер слишком высоким, и каждому пакету полного размера потребуется фрагментация, которая может никогда не произойти.
Почему туннель уменьшает полезный пакет
Если интерфейс туннеля сохраняет MTU физического звена, каждый большой пакет зависит от того, согласится ли кто-то ниже по пути его фрагментировать. IPv4 в принципе это допускает, но маршрутизатор, которому велено не фрагментировать, возвращает ошибку. Маршрутизаторы IPv6 никогда не фрагментируют в транзите, поэтому одна и та же настройка ведёт себя по-разному в зависимости от семейства адресов. В любом случае отправитель ничего не узнаёт, пока что-то не сообщит обратно.
Практическое следствие — размер, который помещается в рукопожатие, но не в полезную нагрузку. TLS ClientHello или запрос DNS достаточно малы, чтобы пройти уменьшенный путь нетронутыми, а массовая передача — нет. Поэтому симптомы группируются вокруг конкретных операций, а не конкретных хостов.
Обнаружение работает только тогда, когда приходит обратная связь
Обнаружение IPv4 опирается на бит don't-fragment: маршрутизатор, который не может продвинуть пакет, возвращает ICMP fragmentation-needed с MTU следующего перехода, и отправитель понижает свою оценку. IPv6 вместо этого использует сообщения Packet Too Big, потому что маршрутизаторы не фрагментируют в транзите. Оба механизма предполагают, что сообщение найдёт дорогу обратно к отправителю, через туннель и мимо любого межсетевого экрана на обратном пути. Когда это предположение рушится, отправитель продолжает повторять размер, который путь не может перенести.
Межсетевой экран, разрешающий echo request и echo reply, не обязательно разрешил эти типы ошибок. ICMP — это семейство, и здесь важны ошибки, а не пара эхо. Проверьте политику управляющего трафика на обоих концах туннеля и на пути между ними, и следуйте поддерживаемым рекомендациям платформы вместо того, чтобы разрешать любой тип ICMP везде.
Та же фильтрация может находиться внутри туннеля. Если внутренний путь отбрасывает ошибку, а внешний её переносит, отправитель может подстроиться под предел, которого инкапсулированный трафик на самом деле никогда не видит.
Проверяйте путь, а не угадывайте число
Держите пункт назначения, сеть доступа и туннель фиксированными, а меняйте только размер пакета. Проверка don't-fragment, которая терпит неудачу с подсказкой MTU, даёт предел следующего перехода; повторяйте, пока какой-то размер не пройдёт, и записывайте и размер, и семейство адресов.
ping -M do -s 1400 10.60.20.10
ping -M do -s 1300 10.60.20.10
ping -6 -M do -s 1300 2001:db8::10
Проходящий ping не доказывает, что проходят сегменты полного размера реального приложения, поэтому повторите тест с передачей, которая действительно не удалась. Сравните самую большую работающую проверку с MTU туннеля, который вы настроили, и держите два числа отдельно в своих заметках. Если они различаются примерно на один заголовок, вы нашли накладные расходы инкапсуляции, а не неисправность.
PLPMTUD, описанный в RFC 4821, проверяет вверх и использует подтверждения транспорта вместо доверия доставленным ошибкам. Это помогает на путях, фильтрующих ICMP, но поддержка зависит от стека и приложения. Поток TCP может восстановиться сам, тогда как UDP-приложение с фиксированным размером датаграммы продолжает терпеть неудачу.
Выберите значение и запишите обоснование
Снижение MTU туннеля — это и диагностика, и законное исправление, когда вы уже знаете путь. Оно не заменяет знания того, какой путь и какой механизм обратной связи были задействованы, потому что значение, настроенное для мобильного звена, будет излишне малым на оптоволоконном соединении. Запишите выбранный размер, проверку, которая его оправдала, и шаг отката.
Механизм IPv4 описан в RFC 1191, а рекомендации по пакетизации IPv6 — в RFC 8201; упоминание обоих избавляет следующего инженера от повторного вывода этого предположения. Если передача всё ещё застревает на выбранном размере, перестаньте снижать число и посмотрите на следующий уровень. Путь, который терпит неудачу при любом размере, — это не проблема MTU.