Иногда сеть выглядит «живой»: DNS отвечает, TCP-соединение устанавливается, но дальше начинаются странности — HTTPS зависает на загрузке, SSH сыпется, API таймаутит, а часть сайтов не открывается только у некоторых пользователей/сетей. Частая причина — blackhole PMTUD: Path MTU Discovery (PMTUD) не может подобрать корректный MTU, потому что ICMP-сообщения Fragmentation needed (или их IPv6-аналог Packet Too Big) не доходят обратно до отправителя.
Ниже — практичная схема: как понять, что это именно PMTUD/MTU, как быстро найти «узкое место» с tracepath и ping с DF, и какие фиксы реально помогают в продакшене: пропуск нужных ICMP-типов, MSS clamping на границе и корректный MTU на туннелях.
Что такое PMTUD и что именно ломается в blackhole
PMTUD (Path MTU Discovery) нужен, чтобы отправитель не посылал IP-пакеты крупнее, чем способен пропустить любой сегмент пути. Механика простая:
- в IPv4 отправитель ставит DF (Don’t Fragment), чтобы маршрутизаторы не фрагментировали пакет;
- если где-то по пути MTU меньше, маршрутизатор возвращает ICMP-ошибку «Destination Unreachable / Fragmentation needed» с подсказкой допустимого MTU;
- отправитель уменьшает размер пакетов и повторяет отправку.
Blackhole PMTUD — это ситуация, когда нужный ICMP-ответ не доходит до отправителя (фильтруется firewall’ом, ломается на NAT/conntrack, теряется из-за асимметрии маршрутов). В итоге отправитель продолжает слать «слишком большие» пакеты, а они исчезают на узком участке.
PMTUD ломается не от того, что «ICMP вообще запрещён», а от того, что не проходят конкретные ICMP-ошибки, связанные с доставкой. Пинг может работать, а PMTUD — нет.
Типовые симптомы: когда подозревать blackhole PMTUD
На практике чаще всего это выглядит так:
- HTTPS: TCP установился, но запрос/страница «висит», особенно на больших ответах или при HTTP/2;
- SSH: логин подвисает, интерактив тормозит, SCP/SFTP обрываются на одном и том же объёме;
- VPN/туннели (WireGuard/IPsec/GRE/VXLAN/PPPoE): внутри туннеля часть трафика идёт, часть — нет;
- проблема воспроизводится только для части провайдеров/регионов (другой маршрут и другой MTU);
- если руками уменьшить MTU на клиенте/в туннеле — «вдруг начинает работать».
На сервере это часто проявляется как таймауты чтения/записи на уровне приложения, ретрансляции TCP и отсутствие явных ошибок маршрутизации.
Диагностика в Linux: подтвердить PMTUD и найти «узкий» MTU
1) Быстрая оценка Path MTU через tracepath
tracepath удобен как первый тест: он пытается «нащупать» PMTU и показывает, где оно меняется.
tracepath example.com
Что искать в выводе:
- строки вида
pmtu 1500,pmtu 1492,pmtu 1420— это подсказки Path MTU; - резкая смена
pmtuна меньшую — частый маркер туннеля/PPPoE/overlay на участке; - если
tracepathне показываетpmtu, это не доказательство отсутствия проблемы: нужные ICMP могут быть отфильтрованы.
2) Проверка ping с DF (IPv4): подбор максимального размера
Классика для IPv4 — ping с запретом фрагментации -M do и заданным payload -s.
ping -M do -s 1472 -c 3 example.com
1472 — это 1500 (Ethernet MTU) минус 20 байт IPv4-заголовок и минус 8 байт ICMP. Если по пути MTU меньше, вы увидите «Frag needed» либо просто потери/таймауты (что и намекает на blackhole).
Подбирайте вниз шагами и фиксируйте, на каком размере ответы становятся стабильными:
ping -M do -s 1464 -c 3 example.com
ping -M do -s 1452 -c 3 example.com
ping -M do -s 1412 -c 3 example.com
Дальше переведите найденный payload в приблизительный MTU: прибавьте 28 байт (IPv4+ICMP). Например, если стабильно проходит -s 1412, то ориентировочный MTU по пути около 1440.
3) Понимание MTU vs MSS: почему «лечат» TCP, а не ICMP
В продакшене чаще всего «ломается» TCP (веб/SSH/API), поэтому важно держать в голове:
- MTU — максимальный размер IP-пакета на линке;
- MSS — максимальный размер TCP payload в одном сегменте, зависящий от MTU.
Если MTU по пути меньше, а MSS не подстроился (из-за blackhole PMTUD), крупные TCP-сегменты будут теряться. Отсюда и популярный фикс — MSS clamping на пограничном узле.
4) Сниффинг: увидеть, что ICMP «Fragmentation needed» не возвращается
При воспроизведении проблемы полезно посмотреть трафик на сервере или на проблемном шлюзе. Идея: вы видите исходящие TCP-сегменты и не видите ожидаемых ICMP-ошибок.
tcpdump -ni any 'icmp or (tcp and (port 443 or port 22))'
Учитывайте асимметричную маршрутизацию: ICMP может возвращаться другим путём и «прилетать» не туда, где вы слушаете. Если есть возможность, смотрите на границе сети, где проходит возвратный трафик.

Почему ICMP Fragmentation Needed часто «пропадает»
Самые частые причины из админской практики:
- слишком строгий firewall: разрешили echo-request/echo-reply, но запретили ICMP errors;
- ошибки stateful-фильтрации: ICMP не попадает в
ESTABLISHED,RELATEDиз-за порядка правил или неверного места фильтрации (INPUT/FORWARD); - NAT/conntrack особенности: «входящий» ICMP должен быть классифицирован как RELATED к исходящему потоку, иначе блокируется;
- туннели и overlay: добавились заголовки (WireGuard/ESP/GRE/VXLAN), а MTU внутри не уменьшили;
- PPPoE: типичный MTU 1492, и 1500 уже не проходит до конца пути;
- IPv6: блокировка ICMPv6 часто даёт ещё более странные эффекты, потому что ICMPv6 критичен для работы сети, включая PMTUD.
Практическое правило: «разрешить весь ICMP без ограничений» — обычно перебор. Но ICMP-ошибки, связанные с доставкой (включая fragmentation needed / packet too big), почти всегда должны проходить.
Исправления: что делать, если PMTUD попал в blackhole
Выбор зависит от того, где вы контролируете сеть: сервер, пограничный NAT/маршрутизатор, VPN-шлюз. Начинайте с корректного решения (ICMP), а MSS clamping используйте как надёжный «пластырь», если первопричину быстро не устранить.
1) Самое правильное: разрешить нужные ICMP-типы и RELATED
Для IPv4 важен ICMP type 3 (Destination Unreachable) code 4 (Fragmentation needed). Для IPv6 — ICMPv6 type 2 (Packet Too Big).
Ориентир для iptables (адаптируйте под вашу политику и порядок правил):
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT
Для IPv6 (ip6tables) — пропустите packet-too-big и RELATED:
ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
Пример для nftables (упрощённо, смысл важнее конкретного расположения в вашей таблице):
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input ip protocol icmp icmp type destination-unreachable accept
nft add rule inet filter input ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big accept
Замечание: в IPv4 «fragmentation needed» — частный случай destination-unreachable. Можно разрешать весь destination-unreachable или только нужные коды, если политика строгая.
2) MSS clamping: самый предсказуемый фикс для TCP
MSS clamping уменьшает MSS в TCP SYN, чтобы стороны сразу договорились о меньшем размере сегментов и не упирались в MTU по пути. Особенно полезно на пограничных узлах, NAT и VPN-шлюзах.
Типовой вариант для iptables (clamp к Path MTU):
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Если у вас не роутер, а хост, который сам принимает трафик, иногда MSS «подрезают» в других цепочках, но правильнее делать это именно там, где трафик форвардится между сетями (граница, туннель, NAT).
Полезно посмотреть, что происходит с MSS в SYN:
tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0'
Практика: если у вас веб-проекты и клиенты массово ходят по HTTPS, MSS clamping на границе часто быстрее всего «снимает пожар». Дальше уже можно спокойно разбираться с тем, где именно режется ICMP.
3) Выставить корректный MTU на интерфейсе и в туннелях
Если проблема появилась после включения VPN/overlay, зачастую правильнее настроить MTU там, где добавилась инкапсуляция, чтобы стек сам выбирал корректные размеры.
Проверьте текущие значения:
ip link show
Пример установки MTU на туннельном интерфейсе:
ip link set dev wg0 mtu 1420
Затем повторите tracepath и ping -M do, чтобы подтвердить исчезновение «чёрной дыры».
Если вы поднимаете VPN на сервере и вам важен полный контроль над сетевым стеком и правилами фильтрации, удобный вариант — держать такой узел на VDS.
4) Антипаттерн: «давайте разрешим фрагментацию и выключим DF»
В IPv4 это иногда даёт временный эффект, но обычно ухудшает ситуацию:
- фрагменты теряются чаще и провоцируют ретрансляции;
- растёт нагрузка на обработку;
- диагностика и безопасность усложняются.
Если инфраструктура под контролем — чините прохождение нужных ICMP-ошибок или используйте MSS clamping.
Проверка после фикса: быстрый чек-лист
Повторите
tracepathдо проблемного хоста и посмотрите, определяется лиpmtuожидаемо.Повторите
ping -M do -s ...и найдите максимальный стабильный размер; сопоставьте с вашими туннелями/PPPoE.Проверьте прикладной сценарий, который раньше «висел» (скачивание файла по HTTPS, ответ API, SCP/SFTP на несколько десятков мегабайт).
Если включали MSS clamping — убедитесь по
tcpdump, что MSS в SYN действительно уменьшается.

Практические заметки для продакшена
Не ломайте ICMPv6
При dual-stack блокировка ICMPv6 почти гарантированно приводит к труднообъяснимым проблемам. Минимум — пропускайте packet-too-big и ESTABLISHED,RELATED, а также базовые сообщения для ND/RA в зависимости от роли хоста.
PMTUD и прокси/балансировщики
Если «падает только 443», не спешите обвинять TLS. Часто TLS просто первым начинает регулярно передавать большие записи/ответы, поэтому blackhole MTU проявляется именно там. На цепочках «клиент → прокси/CDN → origin» проблема может быть на любом участке.
Если у вас сложная фильтрация и вы недавно меняли правила, полезно свериться с материалом про firewall в Docker: iptables/nftables и порядок правил: порядок и точки фильтрации легко ломают RELATED-трафик, включая ICMP-ошибки.
Когда MSS clamping — лучший компромисс
Если у вас нет контроля над тем, где режется ICMP (например, проблема между провайдерами), MSS clamping на вашей границе часто оказывается самым предсказуемым способом стабилизировать TCP для пользователей.
Итог
Blackhole PMTUD — классическая «сетевая чертовщина»: соединение установилось, но крупные пакеты исчезают, потому что ICMP fragmentation needed (или Packet Too Big в IPv6) не возвращается. В Linux проблему удобно диагностировать через tracepath и ping -M do, а чинится она обычно одним из трёх путей:
- разрешить нужные ICMP-типы и корректно настроить stateful-фильтрацию;
- включить MSS clamping на пограничном устройстве;
- привести в порядок MTU на туннелях/интерфейсах.
Если подойти системно и закрепить результат тестами, вы убираете целый класс «плавающих» таймаутов — особенно на HTTPS/SSH и в VPN-сценариях. А чтобы исключать «ложные» подозрения на TLS и держать публичные сервисы в порядке, используйте корректные SSL-сертификаты для ваших доменов.


