linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Сеть: L2 / L3/mtu-and-pmtud

kb/network-l2-l3 ── Сеть: L2 / L3 ── intermediate

MTU и Path MTU Discovery (PMTUD)

MTU - максимум байт IP-пакета на интерфейсе. PMTUD ищет минимум на пути через ICMP "Fragmentation Needed". Если ICMP режут - blackhole больших пакетов. MSS clamping в iptables/nftables - стандартный фикс на туннелях VXLAN/IPsec.

view as markdownaka: mtu, pmtud, path-mtu-discovery, mss-clamping

Зачем знать про MTU

Maximum Transmission Unit (MTU) - максимальный размер IP-пакета, который интерфейс готов отправить одним куском. На обычном Ethernet это 1500 байт (полезная нагрузка [[ethernet-frame|кадра]]).

Когда пакет больше MTU - либо он фрагментируется на IP-уровне, либо отправитель должен прислать пакет меньше. В IPv6 фрагментацию ядер отправителей нет (она запрещена в спеке) - только PMTUD.

Сломанный PMTUD - частая причина странных production-проблем: SSH работает, apt update зависает, git clone обрывается. Симптом один: маленькие пакеты проходят, большие - нет.

Откуда берутся типичные значения

СредаMTUЗаметки
Ethernet (стандарт)1500минус 18 байт L2-заголовка из 1518 frame'а
Jumbo frame9000дата-центр, требует поддержки всеми коммутаторами
PPPoE (DSL)1492-8 байт PPPoE-заголовка
OpenVPN UDP~1400overhead на TLS+UDP
WireGuard1420-80 байт overhead
IPsec ESP~1400зависит от mode (tunnel/transport, AES-GCM)
VXLAN1450-50 байт (Ethernet+IP+UDP+VXLAN headers)
GRE1476-24 байта (GRE+IP)
Loopback65536в ядре, без сети

Посмотреть текущий MTU:

ip link show eth0 | grep mtu

Как пакет сравнивается с MTU

При отправке пакета ядро смотрит на исходящий интерфейс. Если IP-payload

  • IP-header > MTU и DF=0 (Don't Fragment не выставлен) - ядро режет пакет на фрагменты. Каждый фрагмент - самостоятельный IP-пакет с одинаковым ID; первый несёт L4-header, остальные - только данные. Собирает их получатель.

Минусы фрагментации:

  • Если хоть один фрагмент потерян - дропается весь пакет (получатель не может его собрать)
  • Многие firewall'ы дропают фрагменты по дефолту (нельзя проверить L4-заголовки на не-первых фрагментах)
  • CPU overhead - и на отправителе и на получателе
  • Conntrack видит фрагменты странно (нужен nf_defrag_ipv4 модуль)

Поэтому в IPv6 фрагментацию запретили: только source-fragmentation если очень надо, и обязательный PMTUD.

TCP MSS - решение проблемы со стороны TCP

TCP не хочет фрагментироваться на IP. При [[tcp-handshake|SYN]] стороны обмениваются опцией MSS (Maximum Segment Size):

MSS = MTU - 20 (IP header) - 20 (TCP header) = 1460 для MTU 1500

Каждая сторона выбирает свой MSS на основе своего интерфейса. Эффективный MSS соединения = min(MSS_клиент, MSS_сервер). После handshake TCP режет данные на сегменты ≤ MSS, никогда не фрагментирует IP.

PMTUD - найти минимум на пути

Между клиентом и сервером может быть link с MTU < 1500 (туннель, PPPoE). MSS-договорённость не помогает - клиент знает только свой MTU. Тут включается Path MTU Discovery:

  1. TCP всегда ставит DF=1 (Don't Fragment) на свои пакеты
  2. Если на пути роутер видит пакет > MTU исходящего интерфейса - он дропает пакет и отправляет ICMP "Fragmentation Needed and DF Set" ([[icmp|ICMP type 3 code 4]])
  3. В ICMP-сообщении - предлагаемый MTU
  4. Отправитель уменьшает свой Path MTU для этого destination'а (хранится в route cache)
  5. Retransmit пакета меньшего размера

MTU blackhole - сломанный PMTUD

PMTUD требует, чтобы ICMP проходил обратно к отправителю. На многих файрволах/middlebox'ах ICMP режут "по соображениям безопасности". Тогда:

  1. Клиент шлёт пакет 1500 байт через VPN с MTU 1400
  2. Роутер дропает пакет, шлёт ICMP "Frag needed, MTU 1400"
  3. ICMP режут - не доходит до клиента
  4. Клиент ретрансмитит этот же 1500-байтный пакет
  5. Роутер снова дропает... infinite loop

Симптом классический: curl --max-time 5 -v https://big-page.com - TLS handshake проходит (мелкие пакеты), > GET / уходит, но крупный HTTP-ответ зависает. SSH в "интерактивном" режиме работает (мелкие пакеты), cat largefile через SSH висит.

Для IPv6 PMTUD blackhole особенно болезнен: фрагментацию делать нельзя, TCP буквально не может работать с большими пакетами.

MSS clamping - workaround

Когда не уверен в PMTUD (типичная VPN/туннель), переписывают MSS в SYN-пакетах на роутере, через который идёт туннель. TCP-клиент думает, что MSS меньше - и сам не превышает.

В nftables:

add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu

В iptables:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
         -j TCPMSS --clamp-mss-to-pmtu

--clamp-mss-to-pmtu берёт MTU исходящего интерфейса и переписывает MSS в SYN. Это первое, что включают на VPN-сервере, OpenVZ ноде, любом GRE/IPsec endpoint'е.

Альтернатива - явный размер: --set-mss 1360 если знаешь точно.

Jumbo frames - 9000 MTU

В дата-центре между серверами и SAN-стораджем часто включают jumbo frames (MTU 9000):

  • Меньше per-packet overhead (один TCP-пакет вместо 6) → больше throughput
  • Меньше CPU на сетевой стек
  • Полезно для NFS, iSCSI, репликация БД

Подвох: все устройства в L2-сегменте (свитчи, NIC, бридж в ядре) должны поддерживать jumbo. Один свитч с 1500 - blackhole.

Включается:

ip link set eth0 mtu 9000

Для постоянной настройки - в NetworkManager / netplan / /etc/network/interfaces.

MTU в туннелях и overlay сетях

Любой туннель добавляет заголовки → effective MTU внутри туннеля меньше underlay MTU.

Расчёт для VXLAN на underlay MTU 1500:

1500
- 14 outer Ethernet
- 20 outer IP
- 8  UDP
- 8  VXLAN header
- 14 inner Ethernet
= 1436 → округляют до 1450 (исторически)

Если pod в Kubernetes шлёт 1500-байтные TCP-пакеты по [[vxlan-overlay|flannel]], они внутри VXLAN превратятся в 1550-байтный underlay-пакет → дроп где-то. Решения:

  • Уменьшить pod MTU до 1450 (CNI делает это автоматически)
  • Включить jumbo frames на underlay (тогда pod MTU 9000)
  • MSS clamping на CNI-уровне

Аналогично для [[gre-tunnel|GRE]], [[ipsec-ike|IPsec]] - вычитай overhead.

Когда что-то пошло не так

  • Маленькие пакеты идут, большие - нет - классический blackhole. ping -M do -s 1472 host (DF=1, payload 1472=1500-28). Уменьшай -s пока не пройдёт - найдёшь PMTU.
  • tracepath host покажет PMTU по пути (как traceroute, но для MTU)
  • apt update зависает на конкретном пакете - 99% MTU. Включи tcp_mtu_probing или зафиксируй MTU интерфейса
  • VPN tunnel работает плохо после миграции - кто-то сменил underlay MTU. Пересчитай overhead, включи MSS clamping
  • TCP retransmits high, throughput low - проверь не из-за фрагментации (netstat -s | grep -i frag)
  • iptables block ICMP type 3 code 4 - выпили это правило, иначе PMTUD не работает совсем

sysctl-ручки

  • net.ipv4.tcp_mtu_probing=1 - если PMTUD сломан, ядро пробует уменьшить MSS, кэширует результат
  • net.ipv4.ip_no_pmtu_disc=0 - 1 отключает PMTUD (не делать!)
  • net.ipv4.route.min_pmtu=552 - минимальный PMTU, ниже не опускаемся
  • net.ipv6.conf.all.mtu=1280 - минимум для IPv6 (RFC)

§ команды

bash
ip link show eth0 | grep mtu

Текущий MTU интерфейса

bash
ip link set eth0 mtu 9000

Сменить MTU на 9000 (jumbo frames). Действует до перезагрузки

bash
ping -M do -s 1472 -c 1 8.8.8.8

Пинг с DF=1, payload 1472 байт. Если не проходит - PMTU < 1500

bash
tracepath -n example.com

PMTU по hops до destination'а - покажет где режется

bash
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Стандартный MSS clamping для VPN/туннеля. Переписывает MSS в SYN

bash
nft add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu

То же на nftables - clamping MSS до route MTU

bash
sysctl -w net.ipv4.tcp_mtu_probing=1

Включить probing - ядро адаптирует MSS если PMTUD blackhole

bash
ss -ti | grep -i mss

Текущий MSS активных TCP-соединений - сверить с ожидаемым

§ см. также

  • ethernet-frameEthernet frameEthernet-frame - единица передачи на L2: dst-MAC, src-MAC, ethertype, payload (обычно IP-пакет), FCS-checksum. Стандартный MTU = 1500 байт.
  • vxlan-overlayVXLAN - L2 overlay поверх L3-сетиVXLAN - L2-overlay через UDP/4789. 24-битный VNI = 16M сегментов (vs 4K у VLAN). VTEP делает encap/decap. BUM-трафик идёт через multicast или head-end replication. EVPN-VXLAN - control plane через BGP. Underlay MTU 1550 минимум.
  • gre-tunnelGRE-туннели и IPIP - point-to-point поверх IPGRE - инкапсуляция любого L3 в IP (proto 47), 24 байта header. IPIP - тоньше, только IP-в-IP. mGRE - один интерфейс к multiple endpoint'ам. Без шифрования - обёртывают в IPsec. Используется в site-to-site VPN, BGP-полу-мешах.
  • tcp-handshakeTCP three-way handshakeTCP-соединение открывается тремя пакетами: SYN от клиента, SYN-ACK от сервера, ACK от клиента. После - соединение Established, можно слать данные.
  • icmpICMPICMP - служебный протокол поверх IP для control-сообщений: echo (ping), destination-unreachable, time-exceeded (используется traceroute), MTU discovery. Не для данных.
  • ipsec-ikeIPsec и IKEv2 - стандарт корпоративных VPNIPsec - L3-VPN-стандарт. ESP инкапсулирует и шифрует, IKEv2 обменивается ключами. Tunnel-mode даёт новый IP-заголовок для site-to-site; transport-mode - host-to-host. На Linux это strongSwan.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки