FreeBind versus After=: legarea unui socket systemd de o adresă VPN
FreeBind permite systemd să dețină ascultătorul înainte ca adresa VPN să existe; After= doar ordonează sarcini. Comparați-le, apoi testați ordinea și disponibilitatea.
La pornire, o unitate socket care leagă o adresă VPN fixă poate eșua înainte ca tunelul să o fi atribuit, iar serviciul din spate nu pornește niciodată. Două comutatoare par remedii și rezolvă jumătăți diferite ale acelei probleme. FreeBind îi permite systemd să creeze ascultătorul cât timp adresa lipsește încă. After= doar ordonează sarcini, deci schimbă când pornesc lucrurile fără a face adresa să ajungă mai devreme.
Două probleme diferite, două comutatoare diferite
Prima problemă este o eroare de legare: kernelul refuză ascultarea pe o adresă pe care gazda nu o deține, așa că unitatea socket eșuează imediat și serviciul nu este niciodată activat. A doua problemă este o eroare de disponibilitate: adresa există în final, dar ceva încearcă să o folosească înainte ca tunelul să transporte trafic. FreeBind rezolvă prima și nu face nimic pentru a doua. Directivele de ordine nu rezolvă niciuna direct, pentru că doar decid ce pornește și în ce succesiune. A numi eroarea pe care o ai de fapt este întreaga decizie.
Confirmați care dintre cele două o aveți din jurnal, nu din descrierea serviciului. O eroare de legare numește o adresă și raportează că nu poate fi atribuită. O eroare de disponibilitate apare de obicei mai târziu, ca expirare sau conexiune refuzată văzută din cealaltă parte, cu o unitate socket perfect sănătoasă în jurnale.
FreeBind: ascultătorul există înainte de adresă
FreeBind spune kernelului să permită legarea la o adresă ne-locală, astfel încât systemd poate crea socketul de ascultare la pornire și îl poate preda aplicației ori de câte ori aplicația pornește. Acesta este sensul activării prin socket și motivul pentru care socketul poate supraviețui serviciului din spatele lui.
[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes
Atribuirea goală șterge intrările de ascultare moștenite de la unitatea furnizorului înainte de a o adăuga pe cea nouă, ceea ce împiedică un ascultător wildcard rămas să răspundă pe fiecare interfață. Înlocuiți adresa și portul cu ale dumneavoastră și verificați unitatea efectivă, nu doar fișierul drop-in. Folosiți un drop-in sub numele unității în loc să editați un fișier de pachet la fața locului, pentru că următoarea actualizare a pachetului va suprascrie modificarea și nu va lăsa nicio urmă a intenției. Apoi aplicați-l prin procedura de reîncărcare și repornire pe care unitatea socket o așteaptă.
Referința pentru socketuri systemd documentează comportamentul IPv4 și IPv6 din spatele acestei opțiuni, iar detaliul important este că se aplică legării, nu rutării. Nimic din ea nu atribuie o adresă sau nu pornește un VPN. FreeBind este o permisiune acordată ascultătorului, nu un substitut al interfeței.
After= și Wants=: ordinea nu este disponibilitate
Ordinea și cerința sunt axe separate, iar confundarea lor produce unități care pornesc în ordinea corectă și tot eșuează. After=vpn-client.service înseamnă doar că, dacă ambele sarcini sunt pornite, aceasta așteaptă ca cealaltă să fie pornită. Nu trage VPN-ul și nu așteaptă ca VPN-ul să termine conectarea.
Directivele de cerință precum Wants= și Requires= se ocupă de activare și diferă prin ce se întâmplă când dependența eșuează: una continuă, cealaltă se oprește. Niciuna nu știe ce înseamnă un tunel conectat. Un proces VPN poate fi activ fără o adresă atribuită, sau cu adresă atribuită și fără rută către partener, iar ambele stări satisfac dependența. Dacă aplicația are nevoie ca adresa să existe, modelați acea condiție explicit în loc să tratați pornirea procesului ca dovadă a disponibilității.
Verificați ce declară de fapt unitatea cu systemctl cat și systemctl show -p After -p Wants -p Requires. Drop-in-uri din trei directoare diferite pot adăuga directive pe care nu le-ați scris niciodată, iar systemd citește doar unitatea efectivă.
Ce nu face network-online.target
O unitate ordonată după network-online.target așteaptă ca managerul de rețea să declare rețeaua utilizabilă, ceea ce este un punct de sincronizare la pornire și nu o condiție continuă. Nu spune nimic despre dacă un anumit tunel este activ și nu se va declanșa din nou când un VPN se reconectează la mijlocul după-amiezii. A-l trata ca monitor de reconectare este cea mai frecventă citire greșită a acelei ținte.
Proiectul systemd documentează direct această distincție, iar consecința practică este că tot ce are nevoie de o adresă de tunel trebuie să dețină singur dependența. O unitate care așteaptă network-online și apoi leagă o adresă de tunel este corectă doar când tunelul se ridică primul din întâmplare, iar asta este o coincidență, nu un design.
Testați ciclul de viață pe care l-ați ales de fapt
Testați o pornire curată, o cerere după ce adresa apare și comportamentul după ce VPN-ul cade și revine. Cele trei cazuri separă un ascultător funcțional de un serviciu funcțional.
systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"
Prima comandă prinde erorile fișierului de unitate înainte de o repornire, a doua arată unitatea fuzionată, iar a treia dovedește dacă ascultătorul există și pe ce adresă. Un ascultător pe o adresă wildcard unde ați așteptat o adresă de tunel este exact restul pe care ListenStream gol trebuia să îl elimine. Repetați a treia comandă după o reconectare a VPN-ului pentru a vedea dacă adresa s-a mutat.
Alegeți ciclul de viață deliberat: fie un ascultător legat liber care așteaptă întoarcerea unei adrese stabile, fie un serviciu care se oprește cu tunelul și repornește la recuperare. Sunt designuri diferite și eșuează în moduri diferite. Apoi țineți politica de acces legată de sursele și căile pe care le-ați intenționat, pentru că legarea unei adrese de destinație nu cere ca pachetele acceptate să fi sosit printr-o interfață de încredere.