MTU или MSS? Что на самом деле исправляет изменение VPN
MTU ограничивает то, что несёт канал; MSS ограничивает полезную нагрузку TCP внутри него. Ограничьте правильную величину и знайте, какие протоколы не покрывает ни одна из них.
Пинги проходят, большие передачи зависают, а туннель сообщает, что он здоров. Кто-то понижает MTU интерфейса, другой ограничивает MSS, и иногда проблема исчезает по причинам, которые никто не записывает. Эти два числа описывают разные объекты, поэтому изменение неверного даёт исправление, похожее на удачу. Вот процедура: определите уровень, примените соответствующую настройку и затем проверьте на новом соединении.
Два числа, два объекта
MTU относится к каналу или интерфейсу: это самый большой пакет, который можно передать без разделения. MSS относится к TCP: это наибольший объём полезной нагрузки TCP, который может нести сегмент, и он исключает заголовки и TCP, и IP. На обычном канале Ethernet с IPv4 MTU 1500 байт даёт известный MSS 1460 байт. Эти числа описывают разные уровни и передаются разными механизмами. Перепутать их легко, потому что оба измеряются в байтах и оба близки к 1500.
Одно приходит как настройка интерфейса. Другое приходит как опция внутри сегмента SYN, согласованная между конечными точками, которые никогда не видят ваш интерфейс.
Куда уходит внешний дополнительный объём
VPN помещает внутренний пакет внутрь другого, и внешний пакет должен поместиться в физический путь. Заголовки инкапсуляции, внешний заголовок IP, транспортный заголовок и любой тег аутентификации расходуют байты, которые внутренний пакет использовать не может. Оставьте интерфейс туннеля на 1500, и внешний пакет регулярно превышает то, что путь может нести. Когда установлен бит 'не фрагментировать', маршрутизатор отбрасывает его и должен вернуть ошибку ICMP; если эта ошибка фильтруется, отправитель об этом никогда не узнает.
Именно поэтому сбой выглядит избирательным. Малые запросы завершаются, а всё, что заполняет сегмент, застревает, потому что отбрасываются только большие пакеты. Туннель, пропускающий ping, не является туннелем, который несёт данные.
Ограничение MSS и где оно действует
Ограничение MSS переписывает значение в сегменте SYN, когда он пересекает выбранную точку, из-за чего оба конца выбирают меньшую нагрузку, не зная почему. В Linux это цель таблицы mangle, применяемая явным правилом, и она должна попадать в пакеты SYN в нужном вам направлении. Ограничьте её интерфейсом туннеля и диапазоном адресов, потому что широкое правило меняет поведение трафика, который никогда не попадает в туннель.
Эффект только для TCP. Приложение UDP, сеанс QUIC и любой протокол, который строит собственные датаграммы, остаются нетронутыми.
Диагностика на фиксированном пути
Держите одну переменную за раз. Проверяйте пакетом, размер которого выбираете вы сами, и установите флаг 'не фрагментировать', чтобы ядро сообщало результат, а не скрывало его.
Запишите, где начинается сбой: внутри туннеля, на интерфейсе туннеля или на физическом пути после инкапсуляции. Затем измените одно число и повторите тот же тест, а не другой. Существующие соединения сохраняют согласованный MSS, поэтому изменение политики видно только на новом соединении, и именно поэтому кэшированная страница ничего не доказывает ни в одну сторону. Если одна большая загрузка начинает работать, вы узнали об этом пути, а не о каждом протоколе на нём.
Что не исправляет каждое изменение
Понижение MTU интерфейса не меняет MSS уже установленного сеанса. Ограничение MSS не помогает потоку UDP и не восстанавливает путь, на котором ошибки ICMP фильтруются только в одну сторону. Каждое изменение исправляет один класс проблем, а остальные оставляет ровно такими, какими они были.
Запишите, какую настройку вы применили, где и какой тест показал разницу, иначе следующий инженер применит обе и потеряет способность сказать, какая имела значение. Если ограничение реально и постоянно, предпочтите MTU туннеля, отражающий его, а не ограничение, которое его скрывает. Если ограничивать всё же нужно, оставьте правило узким и с комментарием, поскольку необъяснённое правило mangle по умолчанию становится постоянным.