Тунелът изглежда, че работи само след като сървърът първо изпрати нещо. Стартирайте от клиента и нищо не се случва, изчакайте няколко секунди, опитайте отново и той успява. Обичайната диагноза е счупен NAT, а обичайната диагноза е грешна. Променило се е това, че едната страна е научила къде живее другата.

Познаване на крайната точка, а не достижимост

Страна по WireGuard няма да започне ръкостискане, докато не знае къде да го изпрати. Конфигурацията подава това като крайна точка от адрес и порт, а текущото състояние следи крайната точка, в която в момента вярва.

wg show показва двете страни на тази картина, а страна без крайна точка в изхода не може да започне нищо, колкото и правилни да са публичният ѝ ключ и разрешените префикси. Сравнете гледната точка на клиента с тази на сървъра, преди да промените каквото и да е правило, защото двете често не са съгласни кой какво знае.

Как страната научава крайна точка

WireGuard е умишлено тих. Когато правилно удостоверен пакет пристигне от адрес, който страната не е очаквала, реализацията обновява крайната точка на тази страна към новия източник и точно така работи роумингът на лаптоп, който сменя мрежи. Това поведение обяснява зависимостта от посоката: ако сървърът изпрати пръв и пакетът му достигне клиента, клиентът научава текущия адрес на сървъра и може да отговори. До тогава няма къде да изпраща. Механизмът е удостоверен роуминг, а не съкращение „доверие при първа употреба“, защото пакетът е трябвало да е валиден, преди крайната точка да се премести.

Документацията за инструментите на wg описва това обновяване и си струва да се прочете веднъж, ако ще проектирате около него.

Транслацията със състояние добавя своя посока

Когато UDP минава през транслационен шлюз, шлюзът създава състояние за първия пакет, който види. RFC 4787 описва това поведение и изтичанията, които в крайна сметка премахват съпоставянето. Неактивното съпоставяне изтича и входящ пакет от далечната страна тогава се изхвърля от шлюза, преди да достигне хоста. Тунел, който е работил цяла сутрин, спира да отговаря следобед точно поради тази причина.

Това е втори и независим механизъм, който произвежда същия посочен симптом. И познаването на крайната точка, и транслационното състояние трябва да са правилни, а поправянето на едното не поправя другото.

Конфигурирайте посоката, която наистина искате

За клиент, който трябва да започва връзката, поставете крайната точка на сървъра в секцията за страни на клиента и я оставете там. Разчитането сървърът да изпрати пръв е разчитане на случайност в реда на трафика, която ще се промени в тиха мрежа. Конфигурацията трябва да заявява желаната посока, а не да я открива.

За страна зад транслация, която трябва да остане достижима, включете постоянен keepalive от тази страна. Keepalive на всеки 25 секунди е обичайната начална стойност и целта му е да държи съпоставянето отворено, а не да проверява тунела. Изберете една страна да го носи, защото включването и от двете удвоява трафика и шума в журнала, без да подобрява резултата.

Сравнете състоянието преди и след задействането

Запишете двете гледки в момента на отказа, после отново след като сървърът изпрати. Първата команда показва крайните точки и възрастта на ръкостискането. Втората показва дали има транслационен запис за порта. Записът показва коя посока действително е преминала по кабела, а проверката на маршрута потвърждава, че клиентът не изпраща този трафик съвсем другаде.

wg show
conntrack -L -p udp 2>/dev/null | grep 51820
tcpdump -ni any -c 20 'udp port 51820'
ip route get 198.51.100.7

Запишете колоната с крайната точка и транслационния запис заедно. Страна без крайна точка и шлюз без съпоставяне са две различни повреди. Само една от тях се поправя с keepalive.

Подобни статии