FreeBind kontra After=: att binda en systemd-socket till en VPN-adress
FreeBind låter systemd äga lyssnaren innan VPN-adressen finns; After= ordnar bara jobb. Jämför dem och testa sedan ordning och beredskap.
Vid uppstart kan en socket-enhet som binder en fast VPN-adress misslyckas innan tunneln har tilldelat den, och tjänsten bakom startar aldrig. Två brytare ser ut som rättelser och löser olika halvor av problemet. FreeBind låter systemd skapa lyssnaren medan adressen ännu saknas. After= ordnar bara jobb, så det ändrar när saker startar utan att få adressen att komma tidigare.
Två olika problem, två olika brytare
Det första problemet är ett bindningsfel: kärnan vägrar lyssna på en adress som värden inte äger, så socket-enheten misslyckas direkt och tjänsten aktiveras aldrig. Det andra problemet är ett beredskapsfel: adressen finns till slut, men något försöker använda den innan tunneln bär trafik. FreeBind åtgärdar det första och gör ingenting för det andra. Ordningsdirektiv åtgärdar inget av dem direkt, eftersom de bara avgör vad som startar i vilken ordning. Att namnge det fel du faktiskt har är hela beslutet.
Bekräfta vilket av de två du har i journalen, inte i tjänstebeskrivningen. Ett bindningsfel namnger en adress och rapporterar att den inte kan tilldelas. Ett beredskapsfel dyker vanligtvis upp senare, som timeout eller en avvisad anslutning sedd från andra sidan, med en helt frisk socket-enhet i loggarna.
FreeBind: lyssnaren finns före adressen
FreeBind säger åt kärnan att tillåta en bindning till en icke-lokal adress, så att systemd kan skapa den lyssnande socketen vid uppstart och ge den till applikationen när applikationen startar. Det är poängen med socket-aktivering, och anledningen till att socketen kan överleva tjänsten bakom sig.
[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes
Den tomma tilldelningen rensar lyssningsposterna som ärvts från leverantörens enhet innan den nya läggs till, vilket hindrar en kvarvarande wildcard-lyssnare från att svara på alla gränssnitt. Ersätt adressen och porten med dina egna och verifiera den effektiva enheten, inte bara drop-in-filen. Använd en drop-in under enhetens namn istället för att redigera en paketfil på plats, eftersom nästa paketuppdatering skriver över ändringen och inte lämnar något spår av avsikten. Tillämpa den sedan genom det omladdnings- och omstartsförfarande som socket-enheten förväntar sig.
systemd-socket-referensen dokumenterar IPv4- och IPv6-beteendet bakom alternativet, och den viktiga detaljen är att det gäller bindningen och inte routningen. Ingenting i den tilldelar en adress eller startar en VPN. FreeBind är ett tillstånd som ges till lyssnaren, inte en ersättning för gränssnittet.
After= och Wants=: ordning är inte beredskap
Ordning och krav är separata axlar, och att blanda dem ger enheter som startar i rätt ordning och ändå misslyckas. After=vpn-client.service betyder bara att om båda jobben startas väntar denna på att det andra startas. Det drar inte in VPN och det väntar inte på att VPN ska bli klar med anslutningen.
Kravdirektiv som Wants= och Requires= hanterar aktivering och skiljer sig i vad som händer när beroendet misslyckas: den ena fortsätter och den andra stoppar. Ingen av dem vet vad en ansluten tunnel betyder. En VPN-process kan vara aktiv utan tilldelad adress, eller med tilldelad adress och utan rutt till motparten, och båda tillstånden uppfyller beroendet. Om applikationen behöver att adressen finns, modellera det villkoret uttryckligen istället för att behandla processstart som bevis på beredskap.
Kontrollera vad enheten faktiskt deklarerar med systemctl cat och systemctl show -p After -p Wants -p Requires. Drop-ins från tre olika kataloger kan lägga till direktiv du aldrig skrev, och den effektiva enheten är det enda systemd läser.
Vad network-online.target inte gör
En enhet som är ordnad efter network-online.target väntar på att nätverkshanteraren förklarar nätverket användbart, vilket är en synkroniseringspunkt vid uppstart och inte ett varaktigt villkor. Den säger ingenting om huruvida en viss tunnel är uppe, och den utlöses inte igen när en VPN återansluter mitt på eftermiddagen. Att behandla den som en återanslutningsmonitor är den vanligaste felläsningen av det målet.
systemd-projektet dokumenterar den skillnaden direkt, och den praktiska konsekvensen är att allt som behöver en tunneladress själv måste äga beroendet. En enhet som väntar på network-online och sedan binder en tunneladress är bara korrekt när tunneln råkar komma upp först, och det är en slump och inte en design.
Testa den livscykel du faktiskt valde
Testa en ren uppstart, en förfrågan efter att adressen dykt upp och beteendet efter att VPN faller och kommer tillbaka. De tre fallen skiljer en fungerande lyssnare från en fungerande tjänst.
systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"
Det första kommandot fångar fel i enhetsfilen före en omstart, det andra visar den sammanslagna enheten och det tredje bevisar om lyssnaren finns och på vilken adress. En lyssnare på en wildcard-adress där du förväntade dig en tunneladress är precis den rest som den tomma ListenStream skulle ta bort. Upprepa det tredje kommandot efter en VPN-återanslutning för att se om adressen flyttade sig.
Välj livscykeln medvetet: antingen en fritt bunden lyssnare som väntar på att en stabil adress ska återvända, eller en tjänst som stoppar med tunneln och startar igen vid återhämtning. Det är olika designer och de misslyckas på olika sätt. Håll sedan åtkomstpolicyn knuten till de källor och sökvägar du avsåg, eftersom bindning av en destinationsadress inte kräver att accepterade paket kom in genom ett betrott gränssnitt.