Bij het opstarten kan een socket-unit die een vast VPN-adres bindt, falen voordat de tunnel het heeft toegewezen, en de dienst erachter start nooit. Twee schakelaars lijken oplossingen en lossen verschillende helften van dat probleem op. FreeBind laat systemd de listener aanmaken terwijl het adres nog ontbreekt. After= ordent alleen taken, dus het verandert wanneer dingen starten zonder het adres eerder te laten komen.

Twee verschillende problemen, twee verschillende schakelaars

Het eerste probleem is een bindingsfout: de kernel weigert te luisteren op een adres dat de host niet bezit, dus de socket-unit faalt onmiddellijk en de dienst wordt nooit geactiveerd. Het tweede probleem is een gereedheidsfout: het adres bestaat uiteindelijk, maar iets probeert het te gebruiken voordat de tunnel verkeer draagt. FreeBind pakt het eerste aan en doet niets voor het tweede. Ordeningsrichtlijnen pakken geen van beide direct aan, omdat ze alleen bepalen wat in welke volgorde start. De fout benoemen die je echt hebt, is de hele beslissing.

Bevestig welke van de twee je hebt uit het journaal, niet uit de dienstbeschrijving. Een bindingsfout noemt een adres en meldt dat het niet kan worden toegewezen. Een gereedheidsfout verschijnt meestal later, als een time-out of een geweigerde verbinding gezien vanaf de andere kant, met een volledig gezonde socket-unit in de logs.

FreeBind: de listener bestaat vóór het adres

FreeBind vertelt de kernel dat een binding aan een niet-lokaal adres is toegestaan, zodat systemd de luisterende socket bij het opstarten kan aanmaken en aan de toepassing kan geven telkens wanneer die start. Dat is het punt van socket-activering, en de reden dat de socket de dienst erachter kan overleven.

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

De lege toewijzing wist de luistervermeldingen die van de leveranciersunit zijn geërfd voordat de nieuwe wordt toegevoegd, wat voorkomt dat een achtergebleven wildcard-listener op elke interface antwoordt. Vervang het adres en de poort door je eigen en controleer de effectieve unit, niet alleen het drop-in-bestand. Gebruik een drop-in onder de naam van de unit in plaats van een pakketbestand ter plekke te bewerken, want de volgende pakketupdate overschrijft de wijziging en laat geen spoor van de bedoeling achter. Pas het daarna toe via de herlaad- en herstartprocedure die de socket-unit verwacht.

De systemd-socketreferentie documenteert het IPv4- en IPv6-gedrag achter deze optie, en het belangrijke detail is dat die op de binding slaat en niet op routing. Niets erin wijst een adres toe of start een VPN. FreeBind is een aan de listener gegeven toestemming, geen vervanging van de interface.

After= en Wants=: volgorde is geen gereedheid

Volgorde en vereiste zijn afzonderlijke assen, en ze verwarren levert units op die in de juiste volgorde starten en toch falen. After=vpn-client.service betekent alleen dat als beide taken worden gestart, deze wacht tot de andere is gestart. Het trekt de VPN er niet bij en het wacht niet tot de VPN klaar is met verbinden.

Vereisterichtlijnen zoals Wants= en Requires= regelen activering, en ze verschillen in wat er gebeurt als de afhankelijkheid faalt: de ene gaat door, de andere stopt. Geen van beide weet wat een verbonden tunnel betekent. Een VPN-proces kan actief zijn zonder toegewezen adres, of met een toegewezen adres en zonder route naar de peer, en beide toestanden voldoen aan de afhankelijkheid. Als de toepassing het adres nodig heeft, modelleer die voorwaarde dan expliciet in plaats van het starten van het proces als bewijs van gereedheid te zien.

Controleer wat de unit werkelijk declareert met systemctl cat en systemctl show -p After -p Wants -p Requires. Drop-ins uit drie verschillende mappen kunnen richtlijnen toevoegen die je nooit hebt geschreven, en systemd leest alleen de effectieve unit.

Wat network-online.target niet doet

Een unit die na network-online.target is geordend, wacht tot de netwerkbeheerder het netwerk bruikbaar verklaart, wat een synchronisatiepunt bij het opstarten is en geen blijvende voorwaarde. Het zegt niets over of een bepaalde tunnel actief is, en het wordt niet opnieuw geactiveerd wanneer een VPN midden op de middag opnieuw verbindt. Het als een herverbindingsmonitor behandelen is de meest voorkomende verkeerde lezing van dat doel.

Het systemd-project documenteert dat onderscheid direct, en het praktische gevolg is dat alles wat een tunneladres nodig heeft, de afhankelijkheid zelf moet bezitten. Een unit die op network-online wacht en daarna een tunneladres bindt, is alleen correct wanneer de tunnel toevallig eerst omhoog komt, en dat is toeval en geen ontwerp.

Test de levenscyclus die je echt hebt gekozen

Test een schone start, een verzoek nadat het adres verschijnt, en het gedrag nadat de VPN wegvalt en terugkomt. Die drie gevallen scheiden een werkende listener van een werkende dienst.

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

De eerste opdracht vangt fouten in het unit-bestand vóór een herstart, de tweede toont de samengevoegde unit, en de derde bewijst of de listener bestaat en op welk adres. Een listener op een wildcard-adres waar je een tunneladres verwachtte, is precies het overschot dat de lege ListenStream moest verwijderen. Herhaal de derde opdracht na een VPN-herverbinding om te zien of het adres is verschoven.

Kies de levenscyclus bewust: ofwel een vrij gebonden listener die wacht tot een stabiel adres terugkomt, ofwel een dienst die met de tunnel stopt en bij herstel opnieuw start. Dat zijn verschillende ontwerpen en ze falen op verschillende manieren. Houd daarna het toegangsbeleid gebonden aan de bronnen en paden die je bedoelde, want het binden van een bestemmingsadres vereist niet dat geaccepteerde pakketten via een vertrouwde interface binnenkwamen.

Gerelateerde artikelen