TCP-соединение может успешно устанавливаться, хотя передача данных по нему работает нестабильно. Характерные симптомы — зависание SSH, HTTP-запросов и загрузок после начала передачи более крупных TCP-сегментов.
Одна из возможных причин — проблема с определением MTU на всём пути передачи. Сначала проверим MTU физических и виртуальных интерфейсов:
ip -br link
ip link show eth0
ip link show wg0
ip link show tun0
ip link show docker0
MTU интерфейса и MTU всего маршрута — разные параметры. Интерфейс может иметь MTU 1500, тогда как VPN, VXLAN, GRE, IPsec, PPPoE или другой участок маршрута ограничивает максимальный размер проходящего IP-пакета.
Для IPv4 проверим прохождение пакета размером 1500 байт с запретом фрагментации:
ping -4 -M do -s 1472 server_ip
1472 — данные ICMP. Плюс 20 байт заголовка IPv4 и 8 байт ICMP — получаем IP-пакет размером 1500 байт.Если ядру уже известен меньший MTU маршрута, можно получить локальную ошибку:
ping: local error: message too long, mtu=1400
MTU маршрута также может быть уменьшен после получения ICMP
Fragmentation Needed от маршрутизатора.Если такие ICMP-сообщения фильтруются, отправитель может не узнать, что размер пакета необходимо уменьшить. Крупные пакеты будут отбрасываться, а небольшие продолжат проходить.
При необходимости можно выполнить проверку без учёта сохранённого ядром MTU маршрута:
ping -4 -M probe -s 1472 server_ip
Найти приблизительную границу можно последовательной проверкой:
for size in 1472 1452 1440 1420 1400 1380 1372; do
ping -4 -M do -c 3 -s "$size" server_ip
done
Например, если максимальный рабочий размер данных ICMP равен 1372 байтам:
1372 + 20 IPv4 + 8 ICMP = 1400
Предполагаемый MTU маршрута — 1400 байт. При этом он может различаться в прямом и обратном направлениях, поэтому при возможности проверяйте соединение с обеих сторон.
Дополнительно проверим маршрут:
tracepath server_ip
Для TCP важен MSS — максимальный размер данных TCP, который сторона сообщает другой стороне. MSS объявляется независимо в SYN и SYN-ACK, поэтому значения могут отличаться. Посмотреть MSS при установлении соединения:
tcpdump -i any -nn -vv 'tcp[tcpflags] & tcp-syn != 0'
При IPv4 MTU 1500 типичный MSS:
1500 - 20 IPv4 - 20 TCP = 1460
Если реальный MTU маршрута меньше, а его определение работает некорректно — например, ICMP
Fragmentation Needed блокируется — крупные пакеты могут теряться, вызывая повторные передачи и зависание соединения.Состояние TCP-соединения проверим через:
ss -ti dst server_ip
Смотрим RTT,
mss, advmss, окно перегрузки и повторные передачи. Одновременно можно анализировать TCP и ICMP:tcpdump -i any -nn -vv 'tcp or icmp'
Ищем повторные передачи TCP-сегментов и ICMP
Fragmentation Needed. Успешный обычный ping здесь ничего не доказывает: небольшие ICMP-пакеты могут проходить даже при меньшем MTU маршрута. По той же причине TCP-соединение может успешно устанавливаться — SYN, SYN-ACK и ACK имеют небольшой размер.При подтверждённой проблеме не стоит произвольно уменьшать MTU на конечном сервере. Проверьте MTU туннелей, фильтрацию ICMP и конфигурацию наложенной сети. Ограничение TCP MSS также может применяться на маршрутизаторах и VPN-шлюзах, но только как осознанное решение конкретной проблемы.
🔥 Главный вывод будет такой: успешное установление TCP-соединения не гарантирует нормальную передачу данных. Если небольшие пакеты проходят, а крупные теряются — проверяйте MTU маршрута, MSS, ICMP и повторные передачи TCP.
🚪 Linux Ready | #практика