Ĉu hoka skripto de OpenVPN povas uzi la tunelon, kiun ĝi ĵus konstruis?
OpenVPN ruligas hokojn ene de sia propra starto, do skripto, kiu bezonas la tunelon, atendas tunelon, kiu atendas ĝin. Apartigu la laboron kaj elektu la hokon laŭ evento.
Ĉu hoka skripto povas atingi la alian flankon de la tunelo dependas de tri kondiĉoj: al kiu evento ĝi estas ligita, ĉu OpenVPN ankoraŭ estas ene de sia starta sinsekvo kiam la skripto ruliĝas, kaj ĉu la laboro estis apartigita de tiu sinsekvo. Plej multaj skriptoj malsukcesas ĉe la tria. Aldoni dormantadon traktas vivciklan problemon kiel tempigan problemon, kaj ĝi funkcias ĝuste ofte sufiĉe por misgvidi.
Unue decidu la eventon, poste la mekanismon por prokrasti laboron, poste la lokon, kie la prokrastita laboro ruliĝas. Tiuj tri decidoj estas sendependaj, kaj ilin miksi estas kiel hoko de du linioj fariĝas posttagmezo.
Kial la hoko atendas tunelon, kiu atendas ĝin
OpenVPN vokas siajn hokojn sinkrone, ene de la sama procezo, kiu movas pakaĵojn. up ekagas post kiam la aparato tun aŭ tap ekzistas, sed antaŭ ol aldoni iun ajn itineron, kaj route-up ekagas post la itinerado; neniu el tiuj momentoj promesas, ke la kontraŭa flanko respondos. Dum skripto el iu ajn hoko ankoraŭ ruliĝas, la demono ne plusendas, do komando, kiu atendas, ke trafiko transiru la tunelon, atendas tunelon, kiu atendas la komandon. Tiu cirkla atendo estas kial permana rulo sukcesas kaj la hoko tempolimas.
La evidenta flikaĵo, dormi kelkajn sekundojn, foje funkcias ĉar la fora flanko leviĝis mem, ne ĉar la dormo riparis ion. Helpaĵo, kiu esploras pretecon, estas alia respondo: la hoko revenas, plusendo komenciĝas, kaj la helpaĵo ricevas tion, kion ĝi bezonas, tuj kiam ĝi vere ekzistas.
Elektu la hokon laŭ evento, ne laŭ oportuno
Ligu up al laboro, kiu bezonas nur la aparaton, route-up al laboro, kiu bezonas itinerojn, kaj konservu client-connect kaj client-disconnect por taskoj por ĉiu kliento sur la servila flanko. Purigado ĉe malkonekto devas toleri ruliĝi dufoje, ĉar rekonektoj tra persista interfaco ne sekvas la saman sinsekvon kiel plena restarto. Sur la servilo, client-connect ekagas kiam kliento aŭtentikiĝas, ne kiam la demono startas, kio indas konfirmi antaŭ ol movi logikon tien. Se la laboro apartenas al la vivciklo de la servo anstataŭ al unu konekto, systemd-unuo estas pli bona hejmo ol iu ajn hoko.
Hokajn komandojn plenumas rekte la demono, sen ŝelo intere, do ifconfig_remote en linio up alvenas kiel laŭvorta teksto. Volvu la komandon en eksplicitan ŝelon, aŭ tenu la logikon en skripto, kiu legas la medion. ipchange estas unu direktivo, kiu aldonas proprajn argumentojn: ĝi transdonas la adreson kaj la havenon al la komando, do skripto skribita por neniuj vidas du neesperitajn.
Tri manieroj apartigi la laboron
La unua opcio estas sendi la helpaĵon en la fonon el interne de la hoko: startu ĝin per setsid aŭ systemd-run --scope, fermu la hereditajn priskribilojn, kaj eliru tuj kun nulo. La dua estas lasi la hokon skribi malgrandan statan dosieron kaj lasi systemd-temporizilon aŭ padan unuon agi sur ĝi, kio tenas la hokon triviala kaj metas la retpostan politikon tie, kie estas protokoloj. La tria estas tute forlasi la hokon kaj movi la laboron al unuo ordigita post la VPN-servo, kio estas la ĝusta respondo kiam la laboro tute ne estas por konekto. Ĉiuj tri dividas unu regulon: la hoko devas reveni antaŭ ol ĝi bezonas la tunelon.
Kion ajn vi elektos, faru la helpaĵon idempotenta kaj observebla. Du interkovrantaj vokoj ne rajtas plenumi la saman nereigeblan agon dufoje, kaj helpaĵo, kiu malsukcesas, devas lasi ion, kion homo povas legi.
Apartigu sablujajn fiaskojn de vivciklaj fiaskoj
Kiam skripto ruliĝas el radika prompto kaj fiaskas kiel servo, la kaŭzo kutime estas sablujo, ne la reto. Restrikta ProtectHome, nurlega ProtectSystem, aŭ labora dosierujo, kiu ne ekzistas povas lasi la skripton aŭ ĝiajn datumojn neatingeblaj, kaj sur SELinux-gastiganto la dosiero ankaŭ bezonas kuntekston, kiu permesas plenumadon. Legu la unuon per systemctl cat openvpn-server@server kaj la protokolon per journalctl -u openvpn-server@server -n 80, poste serĉu permesan aŭ kuntekstan eraron anstataŭ konektan tempolimon. Malŝalti la sablujon devus esti la lasta movo, ne la unua.
Vivcikla fiasko aspektas alie: la hoko startas, la helpaĵo ruliĝas, kaj la konektilo simple ankoraŭ ne estas tie. Skribu tempostampitan linion el la hoko mem, malkonektu kaj rekonektu, kaj legu la eventojn laŭ ordo. Kiam la helpaĵo vere bezonas la tunelon, lasu ĝin esplori pretecon anstataŭ dormi fiksan periodon.
Tri kampoj igas la sekvan raporton utila: kiu hoko ruliĝis, kiun konton ĝi uzis, kaj kie ĝi haltis. Sen ili, ĉiu posta esploro rekomenciĝas de nulo.