MSS-клампінг на VPN-шлюзі: що він виправляє, а що ні
Клампінг переписує MSS у TCP-рукостисканнях, щоб сегменти вміщалися в тунель. Він ніколи не виправляє UDP чи зламану перевірку path-MTU. Три перевірки, по порядку.
Малі запити працюють, великі завантаження зависають, і хтось пропонує 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, коли вони перетинають шлюз. Якщо правило стоїть на інтерфейсі, який не проходить жоден із напрямків, узгодження завершується без змін і симптом залишається, тому розміщення вирішує результат більше, ніж значення.
| Symptom | What it points to | Next check |
|---|---|---|
| Handshake completes, large transfer stalls | Segment size larger than the path can carry | Path MTU against the tunnel's effective MTU |
| Nothing connects, small or large | Routing, firewall or keying failure | Not MSS; look at the tunnel state |
| Only UDP applications stall | Datagram size or a dropped ICMP error | Platform-specific UDP handling, not clamping |
| Fixed after reconnect, returns later | Clamp applied to one direction or one interface | Rule 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, який ви побачили після цього. Чотири числа роблять наступний інцидент пошуком, а не розслідуванням.