Ping отвечает, DNS разрешает, а каждая страница, которой нужен полноразмерный сегмент, зависает. На канале, добавляющем собственную инкапсуляцию, путь молча теряет несколько десятков байт бюджета, и профиль, написанный для чистого Ethernet, продолжает запрашивать пакеты, которые линия не может провести. Соединение не медленное; оно отбрасывает именно те пакеты, которые важны.

Три варианта могут это исправить, и они работают на разных уровнях. Неверный выбор либо ничего не делает, либо делает туннель хрупким по-новому, поэтому выбор начинается с того, что путь действительно поддерживает.

Три параметра, три разных уровня

link-mtu — это внешний бюджет: зашифрованная полезная нагрузка плюс заголовок OpenVPN, заголовок UDP и внешний заголовок IP. Он описывает то, что покидает машину, и поэтому именно это число ограничивает физический путь.

tun-mtu — это внутренний бюджет: интерфейс, который видит ваш трафик. Он больше того, что путь может провести, ровно на накладные расходы туннеля, и OpenVPN обычно выводит его сам, а не заставляет вас задавать его.

mssfix — совершенно другой механизм. Он переписывает максимальный размер сегмента, объявляемый во время рукопожатий TCP, чтобы узлы TCP выбирали сегменты, помещающиеся после инкапсуляции. Он не меняет MTU интерфейса и никак не влияет на UDP.

Если задать link-mtu явно, OpenVPN вычитает свои накладные расходы, чтобы вывести внутренний MTU. Эти расходы не являются фиксированной константой; они зависят от шифра и аутентификации, поэтому значение, скопированное с форума, может быть неверным на другом профиле. Если задать и link-mtu, и tun-mtu, клиент получит две противоречивые инструкции.

Измерьте путь, прежде чем выбирать число

Измеряйте с физического интерфейса, а не изнутри туннеля, и помните, что ping сообщает полезную нагрузку, а не размер пакета. Добавьте 28 байт для заголовков IPv4 и ICMP, прежде чем сравнивать полезную нагрузку с кадром в 1500 байт, и держите эту поправку в голове, когда партнёр сообщает другое число.

В клиенте Linux ping -M do -s 1472 запрещает фрагментацию и завершается неудачей, если пакет слишком велик. Уменьшайте полезную нагрузку, пока она не пройдёт, затем добавьте 28, чтобы получить MTU пути. PPPoE стоит 8 байт, поэтому 1492 нормально для DSL. DS-Lite и некоторые мобильные пути стоят 40 или больше, и ответ обычно ниже, чем предполагает номинальная скорость линии.

Если каждый размер ping проходит, но большие передачи всё равно зависают, подозревайте чёрную дыру, а не простой предел размера. Сообщение ICMP о необходимой фрагментации где-то на пути фильтруется, поэтому отправитель так и не узнаёт, что нужно уменьшать, и это замечают только потоки, которым нужен большой сегмент.

Сначала ограничьте TCP, затем уменьшите туннель

Рукопожатия TCP — единственное, чего касается mssfix, поэтому обычно это наименее разрушительный элемент управления, который стоит попробовать первым. Задайте его чуть ниже реального бюджета пути, отправьте то же значение с сервера, чтобы обе стороны согласовали его, и повторите тест большой загрузки. Если зависание исчезло, проблема была в размере сегмента TCP, и больше ничего менять не нужно.

Уменьшайте внутренний MTU, когда затронутый трафик не является TCP. Служба UDP, туннель внутри туннеля или приложение, отправляющее датаграммы полного размера, продолжат сбоить после ограничения MSS, потому что ничто не переписывает размер их пакетов. В этом случае уменьшите tun-mtu или задайте link-mtu и позвольте клиенту вывести внутреннее значение, но никогда не оба сразу.

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

Почему малые пробы продолжают работать

Запросы DNS, эхо ICMP и рукопожатия TCP находятся намного ниже размера, на котором происходит сбой. Поэтому туннель выглядит здоровым в любой быстрой проверке, пока рукопожатия TLS и ответы HTTP тихо сбоят. Именно это сочетание, работающий traceroute и браузер, зависающий на первом большом ответе, и есть признак, который нужно искать. Прежде чем браться за новый профиль, возьмитесь за пробу полного размера.

Проверьте на том трафике, который сбоил. Загрузите большую страницу, отправьте датаграмму UDP полного размера, если это и есть затронутая служба, и повторите со второго клиента на другом канале. Запишите измеренный MTU пути и выбранное значение, иначе следующий человек, который тронет профиль, сочтёт это число произвольным.

Никогда не опускайте внутренний MTU ниже 1280, когда IPv6 идёт через туннель, потому что это минимум, который должно провести каждое звено IPv6. Меньший MTU — это факт о пути, а не настройка производительности, которую подкручивают на ощущение.

Похожие статьи