PPPoE: почему сайты зависают и как это исправить

В профессиональной практике сетевого инженера одна из самых частых и при этом наименее очевидных проблем домашних пользователей MikroTik с PPPoE-подключением — это так называемый «зависающий» интернет. Пользователь вводит адрес сайта, браузер бесконечно крутит индикатор загрузки, а затем выдаёт ошибку. При этом достаточно выделить адресную строку и нажать Enter повторно — и страница открывается мгновенно. Проблема воспроизводится на всех устройствах и во всех браузерах, но полностью исчезает при включении любого VPN.

Именно такая ситуация возникла у меня после подключения к сербскому провайдеру Yettel через PPPoE клиент. После изнурительного дебага конфигурации роутера проблема была устранена. В этой статье я разберу, почему так происходит, и покажу механизм решения проблемы.

 

Природа проблемы: MTU, MSS и «чёрная дыра» PMTUD

PPPoE-доступ добавляет к IP-пакету дополнительные заголовки (PPPoE — 6 байт + PPP — 2 байта), поэтому реальный MTU канала снижается с 1500 до 1492 байт. Без правильной корректировки клиентские устройства продолжают объявлять MSS (Maximum Segment Size) равным 1460 байтам (MTU Ethernet 1500 минус 40 байт заголовков TCP/IP).

Когда сервер в интернете отвечает сегментами, соответствующими объявленному MSS, часть пакетов превышает реальный MTU PPPoE. Если в IP-заголовке установлен флаг DF (Don’t Fragment), пакет отбрасывается. При этом многие провайдеры блокируют ICMP-сообщения «fragmentation needed» (тип 3, код 4), создавая так называемую PMTUD black hole — «чёрную дыру» обнаружения MTU пути.
В результате TCP-сессия зависает на этапе передачи данных, хотя handshake прошёл успешно. Повторная попытка загрузки иногда срабатывает случайно, поскольку браузер может использовать уже частично установленное соединение или меньшие сегменты.

При этом, что добавляло сложность в дебаге проблемы, подключение к любому VPN-клиенту решало проблему. Это происходило потому, что VPN-клиент автоматически выполняет MSS clamping под свой туннель (обычно MTU 1400–1420). Именно поэтому при включении VPN сайты начинают открываться без каких-либо проблем.

 

Параметр change-mss

Изначальные настройки были следующие - PPPoE-клиент с max-mtu/max-mru=1460, профиль без change-mss.

Самый правильный и эффективный способ — включить встроенную корректировку MSS непосредственно в профиле PPPoE.

В терминале MikroTik выполните:

/ppp profile set [find name=<имя профайла, привязанного к pppoe клиенту>] change-mss=yes

После этого перезапустите сессию:

/interface pppoe-client disable pppoe-out1
/interface pppoe-client enable pppoe-out1

Также были установлены корректные значения MTU для pppoe клиента:

/interface pppoe-client set [find name=<имя pppoe клиента>] max-mtu=1492 max-mru=1492

При change-mss=yes роутер автоматически перехватывает все TCP-пакеты с флагом SYN, проходящие через PPPoE-интерфейс, и снижает значение MSS до actual-MTU минус 40 байт (при MTU 1492 это 1452 байта). Корректировка применяется в обоих направлениях и работает на уровне ядра роутера.

В итоге, проблема зависающих сайтов при подключении через PPPoE — это классический пример несоответствия MSS и MTU, усугублённый блокировкой ICMP. Включение всего одного параметра change-mss=yes в профиле PPPoE полностью устраняет причину на корневом уровне.