Малые запросы работают, большие загрузки зависают, и кто-то предлагает MSS-клампинг. Это предложение достаточно часто верно, чтобы его стоило попробовать в правильном порядке, и достаточно часто неверно, чтобы потерять полдня при слепом применении. Три проверки ниже отделяют настоящую проблему размера TCP от проблемы UDP, от сломанного обнаружения path-MTU и от клампа, который никогда не видит рукопожатие, которое должен переписать.

Начните с формы отказа

У отказа по размеру есть подпись: соединение устанавливается, аутентификация и небольшие ответы проходят, а затем передача встаёт навсегда, как только нужен сегмент полного размера. Страницы, которые загружают текст, но никогда не завершают картинку, — тот же отказ в меньшем масштабе. Если вообще ничего не подключается, проблема раньше на пути, и клампинг не поможет. Кламп не может починить рукопожатие, которое так и не пришло.

Подпись существует потому, что именно в рукопожатии согласуется размер сегмента. Каждая сторона объявляет максимальный размер сегмента как опцию TCP, а отправители уважают объявление партнёра. Если путь не может нести такой большой сегмент, отказ проявляется позже, когда отправитель наконец пробует один.

Держите транспорт в поле зрения, читая этот симптом. Клампинг — это перезапись опции TCP, поэтому голосовой или видеозвонок, зависающий под тем же туннелем, не является проблемой MSS и от этого не улучшится. Запишите транспорт, прежде чем трогать опцию TCP.

Оцените путь, а затем сравните его с туннелем

Два числа важны, и их часто путают. path-MTU — это самый большой пакет, который путь несёт без фрагментации, а объявленный MSS для IPv4 — это то значение минус 40 байт заголовков IP и TCP, или минус 60 для IPv6. Инкапсуляция туннеля съедает часть бюджета ещё до того, как внутренний пакет вообще начнётся.

ping -M do -s 1400 198.51.100.20
tracepath 198.51.100.20

Ping с битом do-not-fragment сообщает, выживет ли пакет такой полезной нагрузки; меняйте размер, пока он не откажет, и вы эмпирически нашли предел пути. Вывод tracepath сообщает MTU, обнаруженный по маршруту, что быстрее, когда работает, и менее надёжно, когда промежуточный узел фильтрует пробы.

Теперь вычтите накладные расходы туннеля. Внешний заголовок IP, заголовок UDP и заголовок, специфичный для туннеля, берутся из одних и тех же 1500 байт, поэтому пригодный внутренний MTU на типичном Ethernet-основании ниже, чем предполагает физическое звено. Если вычисленный внутренний MTU ниже объявленного партнёрами, вы нашли настоящего кандидата на кламп, а не догадку. Если вычисленное значение уже выше объявления партнёров, остановитесь здесь и ищите в другом месте.

Поставьте кламп там, где проходит рукопожатие

Кламп работает, переписывая опцию MSS в пакетах SYN и SYN-ACK, когда они пересекают шлюз. Если правило стоит на интерфейсе, который не проходит ни одно из направлений, согласование завершается без изменений и симптом сохраняется, поэтому размещение решает исход больше, чем значение.

SymptomWhat it points toNext check
Handshake completes, large transfer stallsSegment size larger than the path can carryPath MTU against the tunnel's effective MTU
Nothing connects, small or largeRouting, firewall or keying failureNot MSS; look at the tunnel state
Only UDP applications stallDatagram size or a dropped ICMP errorPlatform-specific UDP handling, not clamping
Fixed after reconnect, returns laterClamp applied to one direction or one interfaceRule placement and the handshake path

Направление — вторая половина. Клампинг одного направления исправляет половину потоков и оставляет остальные сбоить так, что это выглядит периодическим, поэтому применяйте его к обоим направлениям перенаправляемого трафика. Классическая форма в Linux для туннельного интерфейса — правило mangle, совпадающее с пакетами SYN:

iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Обратите внимание, что на самом деле делает --clamp-mss-to-pmtu: он выводит значение из MTU маршрута, а это не всегда реальный бюджет полезной нагрузки туннеля. На туннеле на основе маршрута, где внутренний маршрут и внешний путь различаются, явное значение, вычисленное в предыдущей проверке, предсказуемее автоматического.

Проверьте новым соединением и поддерживайте обратную связь живой

Установленное соединение сохраняет согласованный MSS, поэтому тестирование в той же сессии ничего не доказывает. Откройте новое соединение после изменения и прочитайте согласованное значение напрямую, а не выводите его из передачи, которая случайно завершается.

ss -tin dst 198.51.100.20
iptables -t mangle -S | grep TCPMSS

Первая команда сообщает MSS сокета вместе с состоянием перегрузки, и это самое быстрое подтверждение того, что кламп сработал. Вторая подтверждает, что правило, которое вы, как вам кажется, добавили, — это правило, которое существует, в той таблице, куда оно было помещено.

Затем защитите механизм, который вы не исправили. Обнаружение path-MTU зависит от того, доходят ли сообщения ICMP fragmentation-needed до отправителя, поэтому межсетевой экран, который их отбрасывает, продолжит ломать большие передачи даже при правильном клампе. Разрешите эти сообщения для пути туннеля или примите, что клампинг компенсирует выбранную вами политику.

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

Запишите измеренный path-MTU, вычтенные накладные расходы туннеля, добавленное правило и MSS, который вы увидели после этого. Четыре числа превращают следующий инцидент в поиск, а не в расследование.

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