Může skript háku OpenVPN používat tunel, který právě vytvořil?
OpenVPN spouští háky uvnitř vlastního startu, takže skript, který tunel potřebuje, čeká na tunel, který čeká na něj. Oddělte práci a vybírejte hák podle události.
Zda se skript háku dostane na druhou stranu tunelu, závisí na třech podmínkách: ke které události je připevněn, zda je OpenVPN při běhu skriptu stále uvnitř své startovací sekvence a zda byla práce od této sekvence oddělena. Většina skriptů selhává na třetí. Přidání čekání bere problém životního cyklu jako problém načasování a funguje právě tak často, aby to zmátlo.
Nejprve určete událost, pak mechanismus odložení práce, potom místo, kde odložená práce běží. Tato tři rozhodnutí jsou nezávislá a jejich záměna je důvod, proč se z dvouřádkového háku stane celé odpoledne.
Proč hák čeká na tunel, který čeká na něj
OpenVPN volá své háky synchronně, uvnitř stejného procesu, který přepravuje pakety. up se spustí, jakmile zařízení tun nebo tap existuje, ale dřív než se přidá jakákoli trasa, a route-up po trasách; ani jeden z těch okamžiků neslibuje, že protistrana odpoví. Dokud skript z kteréhokoli háku běží, démon nepředává, takže příkaz, který očekává provoz skrz tunel, čeká na tunel, který čeká na příkaz. Toto kruhové čekání je důvod, proč ruční spuštění projde a hák vyprší.
Zřejmá záplata, tedy čekání několika sekund, někdy funguje proto, že vzdálený konec naběhl sám, ne proto, že by čekání něco opravilo. Pomocník, který zjišťuje připravenost, je jiná odpověď: hák se vrátí, předávání začne a pomocník dostane, co potřebuje, jakmile to skutečně existuje.
Vyberte hák podle události, ne podle pohodlí
Připojte up k práci, která potřebuje jen zařízení, route-up k práci, která potřebuje trasy, a client-connect a client-disconnect si nechte na úkoly pro jednotlivé klienty na straně serveru. Úklid při odpojení musí snést dvojí spuštění, protože opětovná připojení přes trvalé rozhraní nenásledují stejnou sekvenci jako úplný restart. Na serveru se client-connect spustí, když se klient autentizuje, ne když startuje démon, což stojí za ověření, než tam logiku přesunete. Pokud práce patří k životnímu cyklu služby a ne k jednomu spojení, je jednotka systemd lepší domov než jakýkoli hák.
Příkazy háku spouští přímo démon, bez prostředního shellu, takže ifconfig_remote na řádku up dorazí jako doslovný text. Zabalte příkaz do explicitního shellu, nebo držte logiku ve skriptu, který čte prostředí. ipchange je jedna direktiva, která přidává vlastní argumenty: předává příkazu adresu a port, takže skript napsaný pro žádný vidí dva neočekávané.
Tři způsoby, jak práci oddělit
První možnost je poslat pomocníka na pozadí zevnitř háku: spusťte ho přes setsid nebo systemd-run --scope, zavřete zděděné deskriptory a hned skončete s nulou. Druhá je nechat hák zapsat malý soubor stavu a nechat na něm jednat časovač systemd nebo path jednotku, což drží hák triviální a klade politiku opakování tam, kde jsou logy. Třetí je hák úplně zahodit a přesunout práci do jednotky seřazené za službou VPN, což je správná odpověď, když práce vůbec není pro jednotlivá spojení. Všechny tři sdílejí jedno pravidlo: hák se musí vrátit, než bude tunel potřebovat.
Ať vyberete cokoli, udělejte pomocníka idempotentním a pozorovatelným. Dvě překrývající se volání nesmějí provést stejnou nevratnou akci dvakrát a pomocník, který selže, musí zanechat něco, co člověk přečte.
Oddělte selhání sandboxu od selhání životního cyklu
Když skript běží z root promptu a jako služba selže, příčinou je obvykle sandbox, ne síť. Restriktivní ProtectHome, jen pro čtení ProtectSystem, nebo pracovní adresář, který neexistuje mohou nechat skript nebo jeho data nedostupná a na hostiteli SELinux potřebuje soubor také kontext, který povoluje spuštění. Přečtěte jednotku pomocí systemctl cat openvpn-server@server a journal pomocí journalctl -u openvpn-server@server -n 80, pak hledejte chybu oprávnění nebo kontextu, ne timeout spojení. Vypnutí sandboxu má být poslední krok, ne první.
Selhání životního cyklu vypadá jinak: hák startuje, pomocník běží a socket prostě ještě není. Zapište řádek s časovým razítkem ze samotného háku, odpojte a znovu připojte a čtěte události v pořadí. Když pomocník tunel skutečně potřebuje, ať zjišťuje připravenost, místo aby spal pevnou dobu.
Tři pole dělají příští zprávu užitečnou: který hák běžel, který účet použil a kde se zastavil. Bez nich každé další vyšetřování začíná znovu.