Om et hookscript kan nå tunnels anden side, afhænger af tre betingelser: hvilken hændelse det er knyttet til, om OpenVPN stadig er inde i sin opstartssekvens, når scriptet kører, og om arbejdet er løsrevet fra den sekvens. De fleste scripts fejler på den tredje. At tilføje en pause behandler et livscyklusproblem som et timingproblem, og det virker lige netop ofte nok til at vildlede.

Vælg først hændelsen, derefter mekanismen til at udskyde arbejde, derefter det sted, hvor det udskudte arbejde kører. De tre beslutninger er uafhængige, og at blande dem er, hvordan et hook på to linjer bliver til en eftermiddag.

Hvorfor hooket venter på en tunnel, der venter på det

OpenVPN kalder sine hooks synkront, inde i den samme proces, som flytter pakker. up udløses, når tun- eller tap-enheden findes, men før nogen rute tilføjes, og route-up udløses efter ruterne; ingen af øjeblikkene lover, at en peer svarer. Mens et script fra et af hookene stadig kører, videresender daemonen ikke, så en kommando, der forventer, at trafik krydser tunnelen, venter på en tunnel, der venter på kommandoen. Den cirkulære venten er grunden til, at en manuel kørsel lykkes, og hooket timer ud.

Den oplagte lap, at sove nogle få sekunder, virker nogle gange, fordi den fjerne ende kom op af sig selv, ikke fordi pausen løste noget. En hjælper, der undersøger parathed, er et andet svar: hooket vender tilbage, videresendelsen starter, og hjælperen får det, den har brug for, når det faktisk er der.

Vælg hooket efter hændelse, ikke efter bekvemmelighed

Knyt up til arbejde, der kun har brug for enheden, route-up til arbejde, der har brug for ruter, og gem client-connect og client-disconnect til opgaver per klient på serversiden. Oprydning ved afbrydelse skal tåle at køre to gange, fordi genopkoblinger over en vedvarende grænseflade ikke følger samme sekvens som en fuld genstart. På serveren udløses client-connect, når en klient godkender sig, ikke når daemonen starter, hvilket er værd at bekræfte, før logik flyttes derhen. Hvis arbejdet hører til tjenestens livscyklus i stedet for en enkelt forbindelse, er en systemd-unit et bedre hjem end noget hook.

Hookkommandoer udføres direkte af daemonen, uden en shell imellem, så ifconfig_remote i en up-linje ankommer som bogstavelig tekst. Pak kommandoen ind i en eksplicit shell, eller hold logikken i et script, der læser miljøet. ipchange er en direktiv, der tilføjer sine egne argumenter: den giver adressen og porten til kommandoen, så et script skrevet til ingen ser to uventede.

Tre måder at frigøre arbejdet

Den første mulighed er at sætte hjælperen i baggrunden inde fra hooket: start den med setsid eller systemd-run --scope, luk de nedarvede deskriptorer, og afslut med nul med det samme. Den anden er at lade hooket skrive en lille tilstandsfil og lade en systemd-timer eller en path-unit handle på den, hvilket holder hooket trivielt og lægger genforsøgspolitikken et sted med logs. Den tredje er at droppe hooket helt og flytte arbejdet til en unit, der er ordnet efter VPN-tjenesten, hvilket er det rigtige svar, når arbejdet slet ikke er per forbindelse. Alle tre deler én regel: hooket skal vende tilbage, før det har brug for tunnelen.

Uanset hvad du vælger, gør hjælperen idempotent og observerbar. To overlappende kald bør ikke udføre den samme uigenkaldelige handling to gange, og en hjælper, der fejler, skal efterlade noget, et menneske kan læse.

Adskil sandbox-fejl fra livscyklusfejl

Når et script kører fra en root-prompt og fejler som tjeneste, er årsagen normalt en sandbox frem for netværket. En restriktiv ProtectHome, en skrivebeskyttet ProtectSystem eller en arbejdsmappe, der ikke findes kan gøre scriptet eller dets data utilgængelige, og på en SELinux-vært har filen også brug for en kontekst, der tillader udførelse. Læs uniten med systemctl cat openvpn-server@server og journalen med journalctl -u openvpn-server@server -n 80, og se derefter efter en tilladelses- eller kontekstfejl i stedet for en forbindelsestimeout. At deaktivere sandboxen bør være det sidste træk, ikke det første.

En livscyklusfejl ser anderledes ud: hooket starter, hjælperen kører, og soklen er bare ikke der endnu. Skriv en tidsstemplet linje fra selve hooket, afbryd og genopkobl, og læs hændelserne i rækkefølge. Når hjælperen virkelig har brug for tunnelen, lad den undersøge paratheden i stedet for at sove i en fast periode.

Tre felter gør den næste rapport nyttig: hvilket hook kørte, hvilken konto det brugte, og hvor det stoppede. Uden dem starter enhver senere undersøgelse forfra.

Relaterede artikler