Change MSS: что такое TCP MSS, почему не работает HTTPS

Что такое TCP MSS и MSS Clamping. Почему HTTPS виснет через PPPoE и VPN. Настройка change-mss на MikroTik и Keenetic с командами и диагностикой
За что бьёмся
TCP MSS (Maximum Segment Size) — максимальный размер полезной нагрузки одного TCP-сегмента. Формула: MSS = MTU — 40 байт. При PPPoE, VPN-туннелях и любой инкапсуляции MTU уменьшается. Если MSS не подстроен, а ICMP заблокирован провайдером, HTTPS-сессии зависают на TLS-рукопожатии. Решение: MSS Clamping — одно правило в mangle на MikroTik или один параметр в настройках Keenetic.

Диагноз: HTTPS виснет, HTTP летит, вы уже всё перепробовали

HTTP работает. HTTPS крутит колесо и выдаёт тайм-аут. VPN поднят, пинги идут, а корпоративный портал на TLS не открывается. PPPoE подключили — лёгкие сайты летят, тяжёлые страницы зависают.

Это не браузер, не сертификат и не DNS. В девяти случаях из десяти — неправильный MSS. Разберём, что это такое, почему ломает именно HTTPS, и закроем проблему командами для MikroTik и Keenetic.

Что получишь после прочтения:

  • Понимание механизма MSS и его связи с MTU
  • Готовые команды MikroTik (RouterOS 6.x и 7.x) и Keenetic
  • Инструменты диагностики — найдёшь проблему до того как что-то менять
  • Troubleshooting типичных ошибок при настройке MSS Clamping
  • IPv6 — отдельный блок, потому что про него всегда забывают
  • FAQ под реальные вопросы из поиска

Время на настройку: 5-10 минут. Время на диагностику: 15-20 минут если проблема нестандартная.

Что такое MSS (Maximum Segment Size) и как он связан с MTU

MSS — это максимальный размер полезной нагрузки одного TCP-сегмента без учёта заголовков IP и TCP. Проще говоря: сколько байт данных влезает в один пакет на уровне TCP.

MSS неразрывно связан с MTU (Maximum Transmission Unit) — максимальным размером кадра на уровне канала передачи данных. Связь прямая:


# Формула расчёта MSS:
MSS = MTU - 20 (IP header) - 20 (TCP header)
MSS = MTU - 40

# Пример для стандартного Ethernet:
MSS = 1500 - 40 = 1460

# Пример для PPPoE:
# PPPoE добавляет 8 байт заголовка, поэтому MTU = 1492
MSS = 1492 - 40 = 1452

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

Значения MSS для популярных типов соединений

Тип соединения MTU Overhead MSS Примечание
Ethernet (стандарт) 1500 40 1460 Базовое значение
PPPoE (DSL/GPON) 1492 40 1452 PPPoE = 8 байт overhead
L2TP без шифрования 1460 40 1420 L2TP header ~40 байт
L2TP + IPsec 1418 40 1378 IPsec ESP добавляет ~50 байт
IPsec (ESP, AES-256) 1418 40 1378 Зависит от cipher suite
GRE-туннель 1476 40 1436 GRE header = 24 байта
WireGuard VPN 1420 40 1380 WireGuard overhead ~80 байт
OpenVPN (UDP) ~1400 40 ~1360 Зависит от cipher и компрессии
GRE поверх PPPoE 1468 40 1428 Складываем overhead оба уровня

Архитектура: как MSS анонсируется в TCP-рукопожатии

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#f8fafc',
    'primaryTextColor': '#1e293b',
    'primaryBorderColor': '#94a3b8',
    'noteBkgColor': '#fefce8',
    'noteTextColor': '#713f12',
    'noteBorderColor': '#fbbf24',
    'actorBkg': '#f8fafc',
    'actorBorder': '#94a3b8',
    'actorTextColor': '#1e293b',
    'fontSize': '15px',
    'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
  },
  'sequence': {
    'mirrorActors': false,
    'messageAlign': 'center',
    'actorMargin': 100,
    'width': 160,
    'noteMargin': 12
  }
}}%%
sequenceDiagram
    participant C as Клиент (MSS 1460)
    participant R as Роутер PPPoE
    participant S as Сервер (MSS 1460)
    C->>R: SYN, MSS=1460
    Note over R: MSS Clamping: 1460 -> 1452
    R->>S: SYN, MSS=1452
    S->>R: SYN-ACK, MSS=1452
    R->>C: SYN-ACK, MSS=1452
    C->>S: ACK (сессия открыта, MSS=1452)
    Note over C,S: Оба передают сегменты <= 1452 байт

Без MSS Clamping клиент анонсирует MSS=1460, сервер соглашается. Но пакеты по пути через PPPoE-интерфейс не влезают в MTU=1492 при размере сегмента 1460+40=1500 байт. Точнее, влезают ровно впритык для IPv4 - но TLS ClientHello с расширениями легко выходит за эти рамки.

Почему именно HTTPS зависает, а HTTP работает

Здесь важно понять механизм Path MTU Discovery (PMTUD). Когда пакет не влезает в MTU промежуточного узла, маршрутизатор должен либо фрагментировать его, либо - если установлен флаг DF (Don't Fragment) - отправить назад ICMP Type 3 Code 4 "Fragmentation Needed". Получив это сообщение, отправитель снижает размер сегмента.

Проблема: многие провайдеры и файрволы блокируют ICMP. Полностью. Из-за паранойи, из-за кривой политики безопасности, из-за того что "так было настроено в 2009 году и никто не трогал". В результате отправитель никогда не узнаёт, что пакет не прошёл. Пакеты молча отбрасываются, соединение зависает.

Почему HTTP страдает меньше

HTTP-запрос типично мал: GET /, Host, User-Agent - влезает в один пакет хорошо. Ответ сервера разбивается на мелкие сегменты. Если один потерялся - TCP ретрансмиссия, и всё равно доходит.

TLS-рукопожатие устроено иначе. Пакет ClientHello в TLS 1.3 содержит:

  • список поддерживаемых cipher suites (десятки вариантов)
  • список расширений: SNI, ALPN, session tickets, key_share
  • публичный ключ Diffie-Hellman (32-64 байта)
  • supported_groups, signature_algorithms

Итого ClientHello легко достигает 400-600 байт. Это нормально. Но пакет передаётся с флагом DF=1. Если на пути есть PPPoE или туннель с уменьшенным MTU - и ICMP заблокирован - этот пакет молча дропается. Браузер ждёт ответа, таймаут, retry, снова таймаут.

Поток данных при заблокированном PMTUD

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#ffffff',
    'primaryTextColor': '#1e293b',
    'primaryBorderColor': '#94a3b8',
    'lineColor': '#64748b',
    'fontSize': '15px',
    'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
  },
  'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart TD
    A["Клиент отправляет TLS ClientHello (DF=1, размер > MTU туннеля)"] --> B["Промежуточный роутер PPPoE/VPN"]
    B --> C{"Пакет влезает в MTU?"}
    C -->|"Да"| D["Пакет проходит дальше"]
    C -->|"Нет"| E{"ICMP разрешён?"}
    E -->|"Да (PMTUD работает)"| F["ICMP Fragmentation Needed -> клиент снижает MSS"]
    E -->|"Нет (ICMP заблокирован)"| G["Пакет дропается МОЛЧА"]
    G --> H["Клиент ждёт ответа - тайм-аут"]
    H --> I["Retry - снова тайм-аут"]
    I --> J["HTTPS не работает"]
    F --> K["HTTPS работает после адаптации"]
    D --> K
    style G fill:#f8fafc,stroke:#ef4444,stroke-width:2px,color:#b91c1c
    style J fill:#f8fafc,stroke:#ef4444,stroke-width:2px,color:#b91c1c
    style K fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
    style F fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d

Что такое MSS Clamping и как он решает проблему

MSS Clamping - механизм, при котором маршрутизатор на лету изменяет значение MSS в TCP SYN-пакетах, приводя его к безопасному значению для данного канала.

Ключевые особенности:

  • Работает только с SYN и SYN-ACK пакетами - только при открытии нового TCP-соединения. Установившиеся сессии не затрагиваются.
  • Не ломает соединение - уменьшает анонсируемый MSS до допустимого предела.
  • Решает проблему заблокированного PMTUD - стороны изначально договариваются на правильный размер сегмента, до первого большого пакета.
  • Прозрачно для конечных узлов - клиент и сервер не знают, что кто-то подправил их SYN.

Схема работы MSS Clamping

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#ffffff',
    'primaryTextColor': '#1e293b',
    'primaryBorderColor': '#94a3b8',
    'lineColor': '#64748b',
    'fontSize': '15px',
    'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
  },
  'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart LR
    A["Клиент SYN MSS=1460"] --> B["MikroTik Mangle"]
    B --> C["change-mss clamp-to-pmtu"]
    C --> D["SYN MSS=1452 (PPPoE)"]
    D --> E["Сервер принимает"]
    style B fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
    style C fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af

Настройка MSS Clamping на MikroTik

Системные требования

Компонент Минимальная версия Рекомендуется Примечание
RouterOS 6.40 7.x (LTS) clamp-to-pmtu доступен с 6.x
Тип устройства Любой MikroTik hEX, RB4011, CCR Mangle есть на всех
Права доступа full или write full Нужен доступ к Firewall

На момент публикации актуальна RouterOS 7.18. Перед применением проверь свежие релизы на mikrotik.com/download.

Шаг 1 - Проверяем MTU интерфейса

Прежде чем что-то настраивать, смотрим что есть. Открой Terminal в Winbox или подключись по SSH.


# Смотрим все интерфейсы и их MTU:
/interface print detail

# Конкретно для PPPoE-подключения:
/interface pppoe-client print detail

# Проверяем MTU через ping с флагом DF:
/tool ping address=8.8.8.8 size=1472 do-not-fragment=yes count=4
# Если ответ есть - MTU 1500, MSS 1460
# Если тайм-аут - уменьшай size до получения ответа

# Бинарный поиск MTU:
/tool ping address=8.8.8.8 size=1452 do-not-fragment=yes count=2
/tool ping address=8.8.8.8 size=1464 do-not-fragment=yes count=2
/tool ping address=8.8.8.8 size=1453 do-not-fragment=yes count=2

Результат: знаешь реальный MTU канала. Теперь считаем MSS: MTU - 40.

Шаг 2 - MSS Clamping с автоматической подстройкой (рекомендуется)

Вариант с clamp-to-pmtu - динамически определяет допустимый MSS по MTU исходящего интерфейса. Не нужно вручную считать и обновлять значение при смене MTU.


# Основное правило - для транзитного трафика через роутер:
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping IPv4 clamp-to-pmtu"

# Проверяем что правило создалось:
/ip firewall mangle print

Шаг 3 - MSS Clamping с фиксированным значением

Нужен если clamp-to-pmtu не даёт нужного результата или ты точно знаешь значение MTU. Для PPPoE с MTU 1492 MSS = 1452.


# Фиксированное значение для PPPoE:
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=1452 \
  comment="MSS Clamping PPPoE fixed 1452"

# Для L2TP/IPsec (MTU ~1418):
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=1378 \
  comment="MSS Clamping L2TP-IPsec fixed 1378"

# Для WireGuard (MTU 1420):
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=1380 \
  comment="MSS Clamping WireGuard fixed 1380"

Шаг 4 - Правило с привязкой к конкретному интерфейсу

Если у тебя несколько WAN-интерфейсов с разным MTU - применяй правило только к нужному.


# Только для PPPoE-интерфейса на входе:
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  in-interface=pppoe-out1 \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping inbound pppoe-out1"

# Только для PPPoE-интерфейса на выходе:
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  out-interface=pppoe-out1 \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping outbound pppoe-out1"

Шаг 5 - MSS Clamping для IPv6

Про IPv6 всегда забывают. Если у тебя есть IPv6 - нужны отдельные правила.


# MSS Clamping для IPv6:
/ipv6 firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping IPv6 clamp-to-pmtu"

# Проверяем:
/ipv6 firewall mangle print

В IPv6 фрагментация на промежуточных узлах запрещена протоколом - только отправитель может фрагментировать. Поэтому PMTUD в IPv6 критичен, а MSS Clamping здесь ещё важнее чем в IPv4.

Шаг 6 - Правило для исходящих соединений самого роутера


# Если сам роутер инициирует TCP-соединения (fetch, обновления):
/ip firewall mangle add \
  chain=output \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping router outbound"

Проверка правил через Winbox

IP - Firewall - Mangle. Правило должно быть с зелёной галочкой (enabled). Поле "Bytes" должно расти - значит правило применяется к трафику. Если Bytes = 0 после нескольких HTTPS-запросов с клиентского ПК - что-то не так с цепочкой или фильтрами.

Настройка MSS Clamping на Keenetic

Системные требования

Компонент Версия Примечание
KeeneticOS 3.x и выше CLI adjust-mss поддерживается с 3.x
Модели Все с KeeneticOS Keenetic Extra, Giga, Ultra и др.
Доступ Администратор Нужен для изменения параметров WAN

На момент публикации актуальна KeeneticOS 4.x. Проверь актуальную версию на keenetic.ru.

Способ 1 - Через веб-интерфейс Keenetic

Заходишь в веб-интерфейс роутера (обычно 192.168.1.1 или my.keenetic.net).

Путь: Интернет - выбираешь нужное подключение (PPPoE, L2TP, etc.) - кнопка "Изменить" - раздел "Дополнительно".

Ищешь поле "Ограничение MSS TCP" или "TCP MSS". Вводишь значение:

  • PPPoE: 1452
  • L2TP: считай по таблице выше
  • Если не знаешь - ставь 1452, это безопасное значение для большинства случаев

Сохраняешь. Роутер применяет автоматически.

Способ 2 - Через CLI Keenetic

Подключись по SSH или через веб-консоль (Управление - Командная строка).


# Переходим к настройке PPPoE-интерфейса:
interface PPPoE0

# Устанавливаем MSS:
  ip tcp adjust-mss 1452

# Для автоматической подстройки (если поддерживается):
  ip tcp adjust-mss pmtu

# Выходим из режима интерфейса:
exit

# Сохраняем конфигурацию:
system configuration save
Важно для Keenetic
Синтаксис CLI Keenetic зависит от версии KeeneticOS. Перед применением проверь актуальный синтаксис командой help ip tcp в консоли роутера. В некоторых версиях команда называется ip tcp mss вместо ip tcp adjust-mss.

Проверка на Keenetic


# Смотрим интерфейсы и их состояние:
show interface

# Или через веб: Системный монитор - Интерфейсы
# Смотрим MTU активного WAN-интерфейса

Диагностика: как определить проблему с MSS до настройки

Не трогай ничего, пока не убедился что проблема именно в MSS. Вот полный инструментарий.

Метод 1 - Ping с флагом Don't Fragment (быстрая проверка)

На Windows:


# Проверяем MTU 1500:
ping 8.8.8.8 -f -l 1472
# -f = Don't Fragment
# -l 1472 = payload (1472 + 28 байт заголовков = 1500 байт итого)

# Если тайм-аут - уменьшаем:
ping 8.8.8.8 -f -l 1464
ping 8.8.8.8 -f -l 1452
ping 8.8.8.8 -f -l 1444

# Нашли максимальное значение которое проходит - это наш MTU payload
# MTU = найденное_значение + 28
# MSS = MTU - 40

На Linux/macOS:


# Linux:
ping -M do -s 1472 8.8.8.8

# macOS:
ping -D -s 1472 8.8.8.8

# Если ответ: "Frag needed and DF set" или "Message too long" - MTU меньше 1500
# Уменьшаем -s до получения ответа

Метод 2 - tcpdump для захвата MSS в SYN-пакетах


# Захватываем SYN-пакеты и смотрим поле MSS:
sudo tcpdump -i eth0 "tcp[tcpflags] & tcp-syn != 0" -v 2>/dev/null | grep -E "MSS|mss"

# Более подробный захват:
sudo tcpdump -i eth0 -n 'tcp[tcpflags] == tcp-syn' -v | head -40

# Ищем строку вида:
# options [mss 1460,...]
# Если видим MSS 1460 при PPPoE - проблема подтверждена

Метод 3 - Wireshark (визуально)

Фильтр: tcp.flags.syn == 1

В деталях пакета: TCP - Options - Maximum segment size. Смотришь что анонсирует клиент и что отвечает сервер. Если оба показывают 1460 при PPPoE-подключении - MSS Clamping не работает.

Метод 4 - MTR для поиска узкого места по пути


# Linux - MTR с увеличенным размером пакета:
mtr --report --psize 1400 8.8.8.8

# Если видишь 100% потери на каком-то хопе при большом размере - вот узкое место

Метод 5 - Torch на MikroTik


# Мониторинг трафика на интерфейсе в реальном времени:
/tool torch interface=pppoe-out1 ip-protocol=tcp

# Смотрим размеры пакетов. Если видишь что пакеты > 1452 байт идут через PPPoE - проблема

Быстрый тест HTTPS через curl


# Тестируем TLS-рукопожатие с выводом времени:
curl -v --connect-timeout 10 https://example.com 2>&1 | head -30

# Если зависает на "SSL handshake" или "Trying X.X.X.X:443..." -
# это симптом проблемы с MSS при TLS ClientHello

# Сравниваем HTTP и HTTPS:
curl -v --connect-timeout 5 http://example.com > /dev/null 2>&1 && echo "HTTP OK"
curl -v --connect-timeout 5 https://example.com > /dev/null 2>&1 && echo "HTTPS OK"

Проверка результата после настройки MSS Clamping

Проверка на MikroTik


# Проверяем что правило активно и обрабатывает пакеты:
/ip firewall mangle print stats

# Должны видеть рост счётчика Bytes и Packets в правиле MSS Clamping
# Если счётчики не растут после нескольких минут работы - правило не применяется

# Проверяем счётчик конкретного правила (например rule #0):
/ip firewall mangle print stats where comment~"MSS"

# Смотрим логи (если включено логирование):
/log print where topics~"firewall"

Функциональная проверка


# С клиентского ПК за роутером:
# 1. Откройте несколько HTTPS-сайтов - должны открываться без зависания
# 2. Проверьте специфически тяжёлые сайты (много расширений TLS): github.com, google.com
# 3. Проверьте корпоративные порталы на TLS если именно они не работали

# Проверка через curl с подробным выводом TLS:
curl -v --tlsv1.3 https://github.com 2>&1 | grep -E "Connected|SSL|TLS|certificate"

# Должны увидеть:
# * Connected to github.com
# * SSL connection using TLSv1.3
# * Server certificate: ...
# Без зависания

Проверка что MSS действительно изменился (tcpdump)


# На Linux-машине за роутером, или на самом роутере если есть доступ:
sudo tcpdump -i any 'tcp[tcpflags] & tcp-syn != 0' -v 2>/dev/null | grep mss

# До настройки: options [mss 1460, ...]
# После настройки: options [mss 1452, ...]
# Если MSS изменился - MSS Clamping работает

Troubleshooting: ошибки при настройке MSS Clamping

Ошибка 1 - MSS Clamping настроен, но HTTPS всё равно виснет

Симптом
Правило в mangle создано, счётчики растут, но HTTPS продолжает зависать.

Причины и решения:

  • Правило применяется к неправильному chain. Если трафик проходит через роутер - нужен chain=forward. Если роутер сам инициирует соединения - chain=output. Проверь chain.
  • Неправильный интерфейс в фильтре. Если указал in-interface=ether1, а трафик идёт через pppoe-out1 - правило не применяется. Убери фильтр по интерфейсу или укажи правильный.
  • Слишком большое значение MSS. clamp-to-pmtu берёт MTU исходящего интерфейса. Если MTU определяется неправильно - поставь фиксированное значение. Для PPPoE попробуй 1452, если не помогает - 1440.
  • Проблема не в MSS. Проверь DNS (nslookup github.com), маршрутизацию, наличие proxy.

# Проверяем MTU исходящего интерфейса (что видит clamp-to-pmtu):
/interface print detail where type=pppoe-out
# Смотрим поле actual-mtu

# Если actual-mtu показывает 1500 при PPPoE - MTU определяется неправильно
# Используй фиксированное значение:
/ip firewall mangle set [find comment~"MSS"] new-mss=1452

Ошибка 2 - Счётчики правила не растут

Симптом
Правило создано, но Bytes и Packets остаются на нуле даже после активного использования HTTPS.

# Проверяем порядок правил - важен:
/ip firewall mangle print

# Если выше есть правило с action=passthrough или с accept
# которое захватывает тот же трафик - оно выполняется первым.
# MSS Clamping должен быть перед такими правилами или они не должны его блокировать.

# Проверяем, точно ли трафик идёт через chain=forward:
# Добавляем тестовое правило с логированием:
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=log \
  log-prefix="SYN_TEST " \
  passthrough=yes \
  comment="DEBUG SYN traffic"

# Смотрим логи:
/log print where message~"SYN_TEST"
# Если видим записи - трафик идёт через chain=forward, проблема в другом
# После теста удаляем debug-правило:
/ip firewall mangle remove [find comment="DEBUG SYN traffic"]

Ошибка 3 - HTTPS работает но медленно после настройки MSS

Симптом
HTTPS заработал, но скорость упала по сравнению с HTTP или предыдущей настройкой.

Причина: MSS выставлен слишком маленьким. Например, 576 байт "на всякий случай". Overhead на заголовки вырастает в разы, производительность падает.


# Проверяем текущее значение MSS в правиле:
/ip firewall mangle print detail where comment~"MSS"

# Если new-mss слишком мало - исправляем:
# Для PPPoE:
/ip firewall mangle set [find comment~"MSS Clamping PPPoE"] new-mss=1452

# Или переключаемся на clamp-to-pmtu:
/ip firewall mangle set [find comment~"MSS"] new-mss=clamp-to-pmtu

Ошибка 4 - IPv6 HTTPS зависает, IPv4 работает

Симптом
После настройки MSS Clamping для IPv4 всё заработало. Но сайты с IPv6 продолжают зависать.

# Забыли про IPv6 mangle. Добавляем:
/ipv6 firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping IPv6"

# Проверяем:
/ipv6 firewall mangle print stats

# Для IPv6 также нужно правило для output:
/ipv6 firewall mangle add \
  chain=output \
  protocol=tcp \
  tcp-flags=syn \
  action=change-mss \
  new-mss=clamp-to-pmtu \
  comment="MSS Clamping IPv6 output"

Ошибка 5 - Дублирующиеся правила MSS Clamping

Если несколько правил с одинаковым действием - они не сломают сеть, но создают лишнюю нагрузку и путаницу. Чистим.


# Смотрим все правила mangle:
/ip firewall mangle print

# Удаляем дубли (по номеру правила):
/ip firewall mangle remove numbers=3,4

# Или по комментарию - осторожно, удалит все совпадения:
/ip firewall mangle remove [find comment~"MSS Clamping"]
# После этого добавь правило заново - убедись что осталось одно нужное

Ошибка 6 - MSS Clamping ломает IPsec туннель

Симптом
После добавления MSS Clamping перестал работать site-to-site IPsec туннель или данные по туннелю передаются некорректно.

# IPsec-трафик нужно исключить из MSS Clamping или применять аккуратно.
# Проверяем политики IPsec:
/ip ipsec policy print

# Для site-to-site IPsec используй отдельное правило с фильтрацией по интерфейсу:
/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  out-interface=!lo \
  ipsec-policy=out,ipsec \
  action=change-mss \
  new-mss=1378 \
  comment="MSS Clamping IPsec outbound"

/ip firewall mangle add \
  chain=forward \
  protocol=tcp \
  tcp-flags=syn \
  in-interface=!lo \
  ipsec-policy=in,ipsec \
  action=change-mss \
  new-mss=1378 \
  comment="MSS Clamping IPsec inbound"

Таблица портов и протоколов

Протокол Порт Направление Зачем нужен для MSS
HTTPS TCP 443 Исходящий Основной затронутый протокол
HTTP TCP 80 Исходящий Менее чувствителен к MSS
ICMP Type 3 Code 4 - Входящий Fragmentation Needed - нужен для PMTUD
PPPoE Discovery ETH 0x8863/0x8864 Оба Добавляет 8 байт overhead к MTU
GRE IP proto 47 Оба 24 байта overhead
IPsec ESP UDP 4500 / IP proto 50 Оба ~50-80 байт overhead
WireGuard UDP 51820 Оба ~80 байт overhead

Когда MSS Clamping нужен, а когда нет

Настраивай обязательно:

  • PPPoE-подключение к провайдеру (MTU 1492)
  • L2TP, PPTP, GRE туннели
  • IPsec (ESP) - site-to-site и road warrior
  • WireGuard, OpenVPN
  • LTE/4G/5G-подключения с нестандартным MTU
  • Туннель внутри туннеля (каждый уровень добавляет overhead)
  • Site-to-site VPN для объединения офисов

Не трогай:

  • Обычное Ethernet-подключение без туннелей (MTU 1500, MSS 1460 - всё штатно)
  • PMTUD работает корректно и ICMP не блокируется
  • Медленная загрузка из-за DNS или proxy - диагностируй правильно
  • MSS уже настроен провайдером на своём оборудовании

Безопасность при настройке MSS Clamping

MSS Clamping сам по себе безопасен - он работает только с SYN-пакетами при открытии соединения, не расшифровывает и не модифицирует данные.

Но пока открыт Firewall Mangle - проверь общее состояние безопасности:


# Проверяем что базовые правила firewall на месте:
/ip firewall filter print

# Должны быть правила:
# - accept established,related
# - drop invalid
# - accept input from LAN
# - drop input from WAN (кроме нужных портов)

# Проверяем что нет посторонних открытых правил:
/ip firewall filter print where action=accept chain=input

# Убеждаемся что Winbox доступен только из LAN, не из WAN:
/ip firewall filter print where dst-port=8291
Не делай это в продакшне без бэкапа
Перед изменениями в firewall mangle всегда делай бэкап конфигурации. Одна опечатка в правиле может заблокировать весь транзитный трафик.

Резервное копирование конфигурации MikroTik


# Бэкап перед изменениями (бинарный - всё включая пароли):
/system backup save name=before-mss-clamping

# Экспорт конфигурации в текст (читаемый, без паролей):
/export file=before-mss-clamping-export

# Скачай файлы через Winbox: Files - скачай .backup и .rsc
# Или через SCP:
# scp admin@192.168.88.1:before-mss-clamping.backup ./

# Восстановление из бэкапа если что-то сломалось:
/system backup load name=before-mss-clamping

Профилактика: как не сломать снова

  • Документируй MTU каждого интерфейса - добавляй комментарий к правилу mangle с реальным MTU. Через год сам скажешь себе спасибо.
  • Используй clamp-to-pmtu как дефолт - динамически подстраивается, не нужно пересчитывать при смене провайдера.
  • Не блокируй ICMP Type 3 полностью - можешь блокировать echo-request (ping), но Destination Unreachable нужен для PMTUD. Правило в firewall filter: accept icmp where icmp-options=3:4.
  • Проверяй MSS после смены провайдера - новый провайдер может иметь другой MTU.
  • При добавлении нового туннеля - сразу пересчитывай MSS. Не "потом".
  • Мониторь ICMP unreachable - рост таких сообщений сигнализирует о проблемах с PMTUD.

Обновление RouterOS с MSS Clamping


# Перед обновлением RouterOS:
# 1. Бэкап:
/system backup save name=pre-update-backup

# 2. Проверь changelog на изменения в firewall/mangle:
# https://mikrotik.com/download/changelogs

# 3. Обновляй в тестовой среде сначала если есть возможность

# После обновления:
# 4. Проверь что правила mangle на месте:
/ip firewall mangle print

# 5. Проверь счётчики:
/ip firewall mangle print stats

# 6. Функциональный тест HTTPS с клиентского ПК

Альтернативные решения

Вариант 1 - Уменьшить MTU интерфейса на MikroTik

Вместо MSS Clamping можно уменьшить MTU самого интерфейса. Тогда сетевой стек сам будет генерировать пакеты правильного размера.


# Уменьшаем MTU Ethernet-интерфейса:
/interface ethernet set ether1 mtu=1492

# Минус: влияет на весь трафик через интерфейс, не только TCP.
# MSS Clamping точечнее - работает только с SYN-пакетами.

Вариант 2 - Разрешить ICMP Type 3 Code 4 в firewall

Если PMTUD работает корректно - MSS Clamping не нужен. Убедись что ICMP Fragmentation Needed не блокируется.


# На MikroTik - разрешаем ICMP Fragmentation Needed:
/ip firewall filter add \
  chain=input \
  protocol=icmp \
  icmp-options=3:4 \
  action=accept \
  comment="Allow ICMP Fragmentation Needed for PMTUD" \
  place-before=0

# Это позволит PMTUD работать без MSS Clamping

Вариант 3 - ip tcp adjust-mss на Linux/iptables


# На Linux-роутере (iptables):
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
  -j TCPMSS --clamp-mss-to-pmtu

# nftables (современный вариант):
nft add rule ip mangle FORWARD tcp flags syn / syn,rst \
  tcp option maxseg size set rt mtu

# Сохраняем:
iptables-save > /etc/iptables/rules.v4

FAQ

Почему HTTPS не работает после подключения VPN, а HTTP работает нормально?

VPN-туннель добавляет свои заголовки к каждому пакету - это уменьшает реальный MTU канала. TLS ClientHello при HTTPS-рукопожатии передаётся с флагом Don't Fragment и имеет значительный размер. Если MTU канала уменьшился из-за VPN, а MSS не подстроен - ClientHello не проходит, и браузер зависает на соединении. Решение: настроить MSS Clamping на роутере или VPN-сервере.

Как проверить текущий MSS который анонсирует мой компьютер?


# Windows - через Wireshark или PowerShell:
# В Wireshark: tcp.flags.syn == 1 - смотри TCP Options -> Maximum segment size

# Linux - через ss или tcpdump:
ss -tin dst 8.8.8.8

# MikroTik - через torch или packet sniffer:
/tool sniffer start
/tool sniffer packet print
/tool sniffer stop

Что лучше - clamp-to-pmtu или фиксированное значение MSS?

Для большинства случаев clamp-to-pmtu предпочтительнее - он динамически определяет максимально допустимый MSS по MTU исходящего интерфейса, не требует ручного пересчёта и автоматически адаптируется при смене канала. Фиксированное значение оправдано когда clamp-to-pmtu определяет MTU неправильно (бывает на некоторых туннельных интерфейсах), или когда нужно гарантированно ограничить MSS конкретным значением независимо от интерфейса.

Нужно ли настраивать MSS Clamping если провайдер уже это делает?

Если провайдер настраивает MSS Clamping на своём оборудовании для PPPoE - твой роутер может не нуждаться в дополнительной настройке для самого PPPoE. Но если у тебя поверх PPPoE ещё VPN-туннель - добавляешь свой слой overhead, и правило нужно уже твоему роутеру. Диагностируй по факту: работает HTTPS нормально - не трогай.

Почему MSS Clamping не работает для уже установленных соединений?

MSS Clamping работает только с SYN-пакетами - теми, которые открывают новое TCP-соединение. Установившиеся сессии не затрагиваются: MSS согласован при рукопожатии и изменить его без разрыва соединения нельзя. Поэтому после добавления правила mangle уже активные соединения продолжат работу со старым MSS. Новые соединения получат правильный MSS сразу.

Какой MSS выставить для WireGuard?

WireGuard добавляет примерно 60-80 байт overhead в зависимости от конфигурации. Если внешний MTU 1500, то MTU WireGuard-интерфейса обычно 1420, MSS = 1380. Рекомендуется использовать clamp-to-pmtu - RouterOS сам определит MTU wg-интерфейса. Или явно задай MTU в настройках WireGuard-пира: /interface wireguard set wg0 mtu=1420.

Прогноз и итоги

Сделали следующее: разобрали механизм MSS от формулы до поведения TLS ClientHello, настроили MSS Clamping на MikroTik через mangle с clamp-to-pmtu, добавили IPv6, настроили Keenetic через веб и CLI, прошли через полный набор инструментов диагностики.

Теперь HTTPS-сессии будут открываться корректно через PPPoE, VPN и любые другие туннели. MSS Clamping - это не хак и не workaround, это стандартная практика для любой сети с инкапсуляцией. Если у тебя сеть с туннелями без MSS Clamping - это не "работает само", это "ещё не сломалось при определённых условиях".

Не заработало - разберёмся
Если после настройки HTTPS всё ещё виснет — пиши в комментарии. Опиши тип подключения, что показывает ping с флагом DF и счётчики mangle. Разберём конкретный случай.
Андрей Анатольевич
Author: Андрей Анатольевич

Руководитель ИТ / Кризис-менеджер 25 лет в IT: от инженера в МегаФоне до руководителя отдела. Знаю, как выглядит бардак: нестабильные сети, устаревшая инфраструктура, конфликты в команде, раздутые сроки. Помогаю бизнесу выходить из кризиса: навожу порядок в легаси, стабилизирую то, что разваливается, выстраиваю прогнозируемые процессы. Не раз возвращал к жизни ИТ-структуры — знаю цену хаосу. 📍 Ищу проект для полной реорганизации / стабилизации. 📬 Telegram: @over_dude ✉️ mail@it-apteka.com

Оставайтесь на связи

Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.

Подписаться на IT-Аптеку →

Мы ВКонтакте

IT-Аптека — советы, новости и помощь рядом.

Вступить в группу ВКонтакте →
Поделитесь:

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх