Path MTU Discovery и прочее связанное с этим

2020-01-30

Переписать, дополнить

Maximum Transmission Unit (MTU)

MTU — эта аббревиатура составлена из слов Maximum Transmission Unit, что можно перевести как Максимальный Передающийся Блок. Блок состоит из заголовка и полезной нагрузки. Под MTU понимается максимально возможный размер передаваемой полезной нагрузки.

Содержимое сетевого пакета

Ethernet-кадр (Ethernet frame)

Размер ethernet-кадра в ethernet-сети варьируется в пределах 1514-1538? байт, что слагается из:

  • заголовок (header) кадра, размером 14–38 байт, содержащий, из важного для наблюдателя, следующие поля:
    • MAC-адрес получателя в актуальном физическом сегменте сети
    • MAC-адрес отправителя в этом же сегменте сети
    • поле EtherType (IPv4: 0x0800, или ARP: 0x0806, или ...)
  • полезная нагрузка (payload), размер которой может достигать 1500 байт, и в которой, для нашего примера, транспортируется IP-датаграмма с инкапсулированным в неё TCP-сегментом.

Так как MTU размером всего 1500 байт на сегодняшний день является атавизмом, то уже разработан и внедряется ... джамбо-пакеты размером до ~9000 байт ... бла-бла-бла.

Запоминаем, что размер Ethernet MTU может достигать 1500 байт, причём длина заголовка ethernet-кадра, в отличии от инкапсулированных в него пакетов, не имеет значения, так как ethernet-кадр существует только в пределах текущего сегмента сети, границы которого не пересекает.

Заголовок ethernet-кадра обрабатывается на втором, канальном уровне, OSI, Ethernet payload на этом уровне, естественно, остаётся без изменений.

Вернее будет сказать, что при необходимости прохождения очередного сегмента сети, сетевая карта загружает полезный груз в только что подготовленный ethernet frame и отправляет его до шлюза-маршрутизатора в следующий сегмент сети, где payload перегружается в новый ethernet-кадр, который, в свою очередь, довезёт груз до следующего роутера, и т.д.

Впрочем, некоторая информация, присутствующая в заголовке предыдущего ethernet фрейма, например VLAN или QoS, может копироваться в соответствующие поля заголовка следующего фрейма и, таким образом, путешествовать вместе с грузом через все или несколько сетевых сегментов до пункта назначения.

IP-датаграмма (IP datagram)

Итак, в поле payload ethernet-кадра мы можем наблюдать IP-датаграмму, состоящую из:

  • заголовок (header) датаграммы, длиной 20–60? байт, где, в числе прочего, видим:
    • длина заголовка (например, 20 байт)
    • общая длина датаграммы, header + payload (например 1500 байт)
    • идентификация — уникальное случайное число, используемое, вместе с полями "протокол", "ip-адрес отправителя" "ip-адрес получателя", для идентификации конкретной датаграммы
    • поле для флагов (установлен флаг DF)
    • протокол
    • ip-адрес отправителя
    • ip-адрес получателя
  • полезная нагрузка (payload).

Из вышенаписанного выясняется, что IP datagram MTU может достигать 1480 байт.

Заголовок IP-датаграммы обрабатывается на третьем сетевом уровне модели OSI и данные в нём могут измениться, например, при трансляции IP-адреса в случае пересечения шлюза NAT. Полезная нагрузка IP-датаграммы, что естественно, на сетевом уровне изменениям не подвергается.

TCP-сегмент (TCP segment)

бла-бла-бла
Подвести к TCP MSS

UDP-сегмент (UDP segment)

бла-бла-бла
Затронуть OpenVPN

Способ определения MTU (Path MTU Discovery)

В RFC1191 (November 1990) предложен способ обнаружения MTU.

На сегодняшний день алгоритм, если я всё правильно понимаю, выглядит так:

  1. Хост-источник подготавливает ip-датаграмму с некоторым содержимым.
  2. В заголовке отправляемой ip-датаграммы устанавливаем флаг "не фрагментировать".
  3. Датаграмма начинает движение к требуемому ip-адресу, пересекая ряд роутеров.
  4. В случае, если очередной роутер не может отправить датаграмму в следующий сетевой сегмент без фрагментации, то этот роутер:
    • отправляет обратную ip-датаграмму с icmp-информацией о необходимости уменьшить MTU для этого маршрута до определённого значения
    • уничтожает исходную датаграмму
  5. Хост-источник, после получения icmp-сообщения, повторяет отправку данных, но перепакованную в пакеты меньшего размера.
  6. Если на маршруте попадётся ещё один роутер с меньшим значением MTU, то алгоритм повторится с учётом нового меньшего значения MTU.

Содержимое обратной ip-датаграммы информативно:

  • заголовок стандартный:
    • ...
    • протокол ICMP
    • ip-адрес отправителя [роутер]
    • ip-адрес получателя [хост-источник]
  • а в payload мы обнаруживаем:
    • Type [3]
    • Code [4]
    • MTU для следующего скачка: [значение до которого надо уменьшить MTU]
    • и копия первых ~500? байт исходной датаграммы, где наблюдаются важные поля: идентификация, протокол, ip-адрес отправителя, ip-адрес получателя

Path MTU Discovery Black Hole

Пресловутая чёрная дыра возникает в том случае, если на каком-то из роутеров, находящихся на обратном маршруте [роутер --> хост-источник], прохождение icmp-пакетов запрещено. Нельзя забывать и о самих отправителе и получателе icmp-пакета.

Причина возникновения "Чёрной дыры"

Разберём обычную схему с "зависшим сайтом":

  1. Домашний пользователь, с помощью браузера, отправляет web-серверу запрос на показ страницы. Обычно такая датаграмма имеет небольшой размер и гарантированно доберётся до web-сервера.
  2. После преодоления цепочки роутеров, на web-сервер приходит ip-датаграмма с запросом показа страницы.
  3. Так как запрашиваемая страница довольно тяжёлая, а сетевой интерфейс web-сервера имеет значение MTU равным 1500 байт, то web-сервер делит содержимое страницы на несколько частей так, чтобы размер первого куска страницы, вместе с заголовками ip-датаграммы и tcp-сегмента, не превышал 1500 байт.
  4. Тяжёлая ip-датаграмма начинает путешествие к пользователю.
  5. На одном из роутеров возникает проблема. Сетевой интерфейс, через который датаграмма должна была продолжить путь к пользователю, имеет MTU 1492. Роутер отправляет icmp 3/4 обратно web-серверу, а датаграмму уничтожает. Пользователь продолжает наблюдать в браузере песочные часы на белом фоне пустой страницы.
  6. Датаграмма с указанием "MTU уменьшить до 1492 при отправке пакетов через такой-то роутер" может быть уничтожена:
    • на роутере-отправителе;
    • на одном из роутеров между роутером-отправителем и web-сервером;
    • на сетевом интерфейсе web-сервера; что маловероятно, потому что одно из первых правил в файрволе web-сервера:
      • iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT,
      • то есть icmp-пакет, после разбора своего содержимого, где будут найдены изначальные идентификация, протокол, ip-адрес отправителя, ip-адрес получателя, попадёт под определение RELATED.
  7. В случае не прохождения обратного icmp-пакета произойдёт следующее:
    • web-сервер не получит icmp-пакет и продолжит ждать tcp-пакет с подтверждением получения первого куска страницы;
    • через некоторое время web-сервер повторит безнадёжную отправку первого куска запрошенной html-страницы;
    • пользователь продолжает наблюдать в браузере песочные часы на белом фоне пустой страницы.

Определение MTU с помощью ping

Работает в случае разрешённых icmp echo/request.

Уменьшаем размер пакета пинга до устойчивых обратных понгов.

$ ping -M do 1.1.1.1 -s 1465
PING 1.1.1.1 (1.1.1.1) 1465(1493) bytes of data.
From 192.168.10.1 icmp_seq=1 Frag needed and DF set (mtu = 1484)
ping: local error: message too long, mtu=1484

$ ping -M do 1.1.1.1 -s 1456
PING 1.1.1.1 (1.1.1.1) 1456(1484) bytes of data.
1464 bytes from 1.1.1.1: icmp_seq=1 ttl=60 time=4.67 ms
1464 bytes from 1.1.1.1: icmp_seq=2 ttl=60 time=6.86 ms
1464 bytes from 1.1.1.1: icmp_seq=3 ttl=60 time=4.84 ms

Разобрать.

Способы решения проблемы с "Чёрной дырой"

  1. Очевидное и самое правильное решение — обеспечить прохождение icmp 3/4 на всём маршруте. К счастью
  2. Искуственно уменьшить MTU внешнего интерфейса на своём хосте, либо на одном из-под контрольных роутеров. Минус этого решения в деградации производительности сети из-за уменьшения размера payload.
  3. Задействовать TCP MSS. Будет работать только с TCP. С UDP- протоколом, например OpenVPN, проблемы останутся.

----

Разобрать:
TCP MSS
tcp сквозь openvpn over udp
Параграф: Определение MTU с помощью ping

Дописать при желании:
Может быть разжевать по какой причине фрагментирование нежелательно.