При зареждане сокет единица, която обвързва фиксиран VPN адрес, може да се провали, преди тунелът да ѝ го е присвоил, и услугата зад нея така и не стартира. Два превключвателя изглеждат като решение и решават различни половини от този проблем. FreeBind позволява на systemd да създаде слушателя, докато адресът все още липсва. After= само подрежда задачите, така че променя кога нещата стартират, без да направи така, че адресът да пристигне по-рано.

Два различни проблема, два различни превключвателя

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

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

FreeBind: слушателят съществува преди адреса

FreeBind казва на ядрото да разреши обвързване към нелокален адрес, така че systemd да може да създаде слушащия сокет при зареждане и да го предаде на приложението, когато то стартира. Това е смисълът на активирането чрез сокет и причината сокетът да може да надживее услугата зад него.

[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes

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

Справочникът за systemd сокети документира поведението при IPv4 и IPv6 зад тази опция и важната подробност е, че тя се отнася до обвързването, а не до маршрутизацията. Нищо в нея не присвоява адрес и не стартира VPN. FreeBind е разрешение, дадено на слушателя, а не заместител на интерфейса.

After= и Wants=: подредбата не е готовност

Подредбата и изискването са отделни оси и тяхното объркване създава единици, които стартират в правилния ред и все пак се провалят. After=vpn-client.service означава само, че ако и двете задачи бъдат стартирани, тази чака другата да бъде стартирана. Той не издърпва VPN и не чака VPN да завърши свързването.

Директивите за изискване като Wants= и Requires= се грижат за активирането и се различават по това какво се случва при отказ на зависимостта: едната продължава, другата спира. Нито една от тях не знае какво означава свързан тунел. VPN процес може да е активен без присвоен адрес или с присвоен адрес и без маршрут до партньора, и двете състояния удовлетворяват зависимостта. Ако приложението има нужда адресът да съществува, моделирайте това условие явно, вместо да приемате стартирането на процеса за доказателство за готовност.

Проверете какво действително декларира единицата с systemctl cat и systemctl show -p After -p Wants -p Requires. Drop-in файлове от три различни директории могат да добавят директиви, които никога не сте писали, а systemd чете само ефективната единица.

Какво network-online.target не прави

Единица, подредена след network-online.target, чака мениджърът на мрежата да обяви мрежата за използваема, което е точка за синхронизация при зареждане, а не непрекъснато условие. Тя не казва нищо за това дали конкретен тунел е активен и няма да се задейства отново, когато VPN се свърже наново посред следобеда. Да я третирате като монитор за повторно свързване е най-честото погрешно четене на тази цел.

Проектът systemd документира тази разлика пряко и практическата последица е, че всичко, което се нуждае от адрес на тунел, трябва само да притежава зависимостта. Единица, която чака network-online и след това обвързва адрес на тунел, е правилна само когато тунелът случайно се вдигне пръв, а това е съвпадение, а не дизайн.

Тествайте жизнения цикъл, който действително избрахте

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

systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"

Първата команда хваща грешки в unit файла преди рестарт, втората показва обединената единица, а третата доказва дали слушателят съществува и на кой адрес. Слушател на wildcard адрес там, където сте очаквали адрес на тунел, е точно остатъкът, който празният ListenStream е трябвало да премахне. Повторете третата команда след повторно свързване на VPN, за да видите дали адресът се е преместил.

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

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