IPIP вътре в WireGuard: допълнителните 20 байта, които никой не е предвидил
IPIP струва още 20 байта вътре в WireGuard. Направете бюджета на правилния слой, преди да обвините фрагментацията за застинал трансфер по жив тунел.
Малките ping-ове минават през тунела цял ден, SSH банерът пристига и точно когато започне трансфер на файл, сесията замръзва. Този модел сочи към бюджет от байтове, изчислен на грешния слой, където външният тунел е оразмерен за собствената си шапка, а никой не е извадил вътрешната. Вложеният IPIP пакет е просто още един IP пакет за WireGuard и точно затова изразходва байтове, които никога не сте запазили. Корекцията е аритметика и се побира в три команди и една таблица.
Симптомът, който го издава
Проблемът с фрагментацията се обявява чрез размер, никога чрез адреси. Вашият партньор отговаря на 56-байтов ping в продължение на час и после замлъква при 1400 байта, докато тунелът остава вдигнат и никой маршрут не се е променил. Ръкостискането се побира, първият пълен TCP прозорец не, и трансферът спира секунди след като е изглеждал здрав.
Измерете тавана, преди да редактирате каквото и да е, защото неизмереният таван е този, който ще гоните два пъти. Изпратете една проба под подозирания размер с вдигнат бит do-not-fragment, ping -M do -s 1000 10.9.0.2, после я повторете при размер, за който вече знаете, че е твърде голям. Когато преобръщането следва размера на полезния товар, докато дестинацията остава същата, маршрутизацията си върши работата и в бюджета липсва една шапка.
Бройте всяка шапка веднъж, на правилния слой
Започнете от най-малкия MTU по пътя, а не от интерфейса на тунела, защото стената е над двата края. WireGuard харчи 60 байта за външен IPv4 транспорт: 20 за IP, 8 за UDP и 32 за собствената си шапка, и 80 байта, когато този транспорт е IPv6. wg0 от 1420 байта пази 20 байта резерв под 1440, които път от 1500 байта наистина може да достави, и затова числото, копирано от уики, все още пасва тук. Начертайте целия стек на диаграмата, защото следващият, който смени MTU, иначе ще избере ново кръгло число и ще наследи вашата грешка.
| Layer | Bytes | Remaining |
|---|---|---|
| Path MTU on the wired link | none yet | 1500 |
| WireGuard outer: IP, UDP, WG header | 60 | 1440 |
| Slack kept for safety | 20 | 1420 (wg0) |
| IPIP header inside the tunnel | 20 | 1400 (ipip0) |
| Original IPv4 and TCP headers | 40 | 1360 payload |
Петият ред е мястото, където бюджетите се чупят, защото 1400 байта, които носи вложеният интерфейс, вече включват собствените 40 байта шапки на оригиналния пакет. Само 1360 от тези байтове стигат до процеса, който чете файла. Приемете 1400 за полезен товар на приложението, както ви кани всяка диаграма без тази колона, и вътрешното устройство излиза с 40 байта твърде щедро срещу стена, която не е мръднала.
Задайте двата MTU поотделно
Носителят и вложеното устройство са отделни обекти, така че всяко се нуждае от собствена стойност. Приложете ги в този ред, защото вложеното устройство не наследява нищо от носителя:
ip link set wg0 mtu 1420
ip tunnel add ipip0 mode ipip remote 203.0.113.9 local 198.51.100.4
ip link set ipip0 mtu 1400
Правилото, което си заслужава да се запомни: вътрешен MTU = външен MTU - 20, когато пакетът, който носи IPIP тунелът, е IPv4, и - 40, щом някоя страна на вътрешния пакет е IPv6, защото вложената шапка расте от 20 байта на 40. Нищо друго не влиза в това изваждане. Шапката на WireGuard вече е похарчена, когато сте избрали 1420, и таксуването ѝ два пъти създава тунел, който работи безупречно и остава бавен, докато никой не го измерва. Внедряване, в което и двете устройства носят кръгло 1400, е отпечатъкът на точно тази грешка.
IPv6 от двете страни на вложения пакет обезсмисля всяко число по-горе, затова преизчислете, вместо да копирате число от подобен сайт. Изважданите шапки са по 40 байта, щом IPv6 се появи във външния път или в оригиналната дейтаграма, и числото на полезния товар пада точно с толкова.
Правилото за защитната стена, което вероятно не ви трябва
Между два партньора WireGuard единственото по жицата е UDP, така че входящо правило за протокол 4, номера, който RFC 2003 дава на инкапсулацията IPv4-в-IPv4, нито създава вложения път, нито го поддържа жив. Шапката на IPIP живее вътре в криптирания полезен товар, където никоя гранична защитна стена не я вижда. Отварянето на протокол 4 така или иначе не купува нищо освен още един разрешен път към хоста.
Политика, която споменава източниците и дестинациите на оригиналния пакет, принадлежи след декапсулацията, на интерфейсите на тунела и в таблицата за маршрутизация. Сложете я там и граничното правило може да остане затворено.
Какво всъщност валидира WireGuard
AllowedIPs съди за източника на пакета, който WireGuard носи, а той носи IPIP-инкапсулирания пакет. Разрешен IPIP източник се приема дори когато шапката вътре посочва хост, към който предпочитате да не маршрутизирате. Затова оригиналният източник не е това, което партньорът е проверил вместо вас, и тази вътрешна двойка адреси се нуждае от собствен контрол след декапсулацията.
Обвивката доставя маршрутна структура, а не втори слой криптография. Наричането на IPIP допълнителна защита вътре в WireGuard описва друг дизайн.
Проверявайте със стълба, не с един ping
Проверете размери, които заобикалят изчислената граница, после потвърдете какво ядрото мисли за двете устройства. При 1360 байта полезен товар плюс 40 байта шапки, което прави 1400, първото ехо по-долу минава, а второто стои на един байт отвъд тавана:
ping -M do -s 1372 10.9.0.2
ping -M do -s 1373 10.9.0.2
wg show wg0
ip -d link show ipip0
Чисто преминаване под тавана и провал при първия размер над него означава, че аритметиката се държи от край до край. После пуснете отново трансфера, който първоначално заседна, защото синтетичната проба доказва бюджета и не казва нищо за собствените размери на запис на подателя. Ако вложеният път все още се чупи при размер, който сте доказали, че пасва, прегледайте декапсулацията и маршрутите на далечния край, преди да отрежете още десет байта от MTU.