Настройка MSS для TCP на шлюзе Linux IPsec: что это исправляет
Небольшие запросы работают, а большие ответы зависают. Проверьте, является ли правило MSS на внутреннем пути TCP правильным решением и где оно должно находиться.
Ping работает, SSH работает, небольшая страница загружается, а затем каждый большой ответ зависает до истечения времени ожидания. Классическая картина указывает на размер пакета, а не на доступность: путь несёт рукопожатие и первые несколько килобайт, затем полноразмерный сегмент исчезает. На шлюзе Linux IPsec правило TCP MSS часто бывает решением, но только если вы понимаете, что оно меняет и где на самом деле находится пакет, которого оно касается. Порядок ниже ведёт пакет от симптома к размещению правила, так что вы можете остановиться, как только объяснение перестанет подходить.
Симптом, который указывает на MSS
TCP согласует максимальный размер сегмента при рукопожатии. Если это значение больше того, что путь может нести после инкапсуляции, отправитель продолжает создавать сегменты, которые так и не доходят, и соединение зависает после первого круга. Небольшие ответы помещаются; большие нет.
Обратная связь ICMP может спасти соединение через обнаружение MTU пути, а межсетевой экран, который отбрасывает эти сообщения, превращает зависание в тихую чёрную дыру. Поэтому один и тот же туннель работает для одного приложения и не работает для другого без видимой разницы в конфигурации.
Что правило TCPMSS делает и чего не делает
Правило переписывает параметр MSS в пакетах рукопожатия TCP, когда они проходят. Оно не задаёт MTU туннельного интерфейса, не меняет политику IPsec, а на современных ядрах только понижает объявленное значение, а не повышает уже меньшее. Оно также касается только TCP; полезная нагрузка UDP, поведение DNS и согласованные селекторы трафика находятся вне его досягаемости.
Поскольку изменение происходит во время рукопожатия, существующее соединение, установленное до правила, сохраняет своё старое значение. Проверяйте новым соединением и ожидайте, что именно первая попытка после изменения что-то вам скажет. Ничто в правиле не достигает уже открытого соединения. Поэтому исправление, применённое в середине инцидента, может выглядеть так, будто оно не сделало совершенно ничего.
Разместите правило на внутреннем пути TCP
На шлюзе Linux с политиками пересылаемый пакет всё ещё выглядит как обычный TCP, когда его видит межсетевой экран. Политика IPsec решает, что пакет будет защищён; межсетевой экран не видит заголовка ESP для внутреннего потока, поэтому сопоставление с ESP здесь описывает совсем другой пакет. Именно это несоответствие — причина того, что некоторые правила выглядят правильными и никогда не срабатывают.
В терминах iptables правило принадлежит таблице mangle на пути пересылки и ограничено пакетами рукопожатия: iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1270. Число — это пример, а не универсальная константа; выведите его из накладных расходов инкапсуляции и реального MTU пути. Эквивалент в nftables задаёт максимальный размер сегмента в цепочке forward или postrouting.
Держите внешние правила прослушивания для IKE и ESP отдельно от внутренних правил пересылки. Единственное правило, которое пытается разрешить и поток приложения, и внешний протокол, в итоге надёжно не совпадает ни с одним из них.
Уважайте владельца межсетевого экрана и порядок NAT
Если UFW управляет межсетевым экраном хоста, добавляйте изменения mangle и пересылки через поддерживаемую постоянную конфигурацию, а не вводя команду, которая исчезнет при следующей перезагрузке. Правило, вставленное в неправильную таблицу или после терминального правила, не имеет эффекта, а живая таблица скрывает это от вас.
Трансляция источника — отдельное решение, которое часто взаимодействует с этим. Исключение, размещённое перед общим правилом masquerade, не даёт защищённому трафику потерять источник, который требует его политика; оно не исправляет проблему размера, а правило размера не исправляет проблему трансляции.
Проверяйте узко, затем остановитесь
Откройте новое соединение к сбойному сервису и наблюдайте и за приложением, и за счётчиками правила. Если зависание исчезло, у вас есть доказательства об этом пути TCP с этой инкапсуляцией. У вас нет доказательств, что подходит каждый протокол VPN, что исправлено каждое приложение UDP или что конкретный вышестоящий сервис был первоначальной причиной.
Оставляйте обратную связь ICMP о размере работающей там, где политика это позволяет, и осторожно относитесь к автоматическому ограничению на основе MTU маршрута, когда внешний путь IPsec не представлен внутренним маршрутом. Чем уже вывод, тем легче диагностировать следующий инцидент.