Da li hook skripta može doći do druge strane tunela zavisi od tri uslova: na koji događaj je prikačena, da li je OpenVPN još unutar svog niza pokretanja kada se skripta izvršava i da li je posao odvojen od tog niza. Većina skripti pada na trećem. Dodavanje pauze tretira problem životnog ciklusa kao problem tajminga, i radi tačno toliko često da obmane.

Prvo odlučite događaj, zatim mehanizam za odgađanje posla, zatim mjesto na kojem se odgođeni posao izvršava. Te tri odluke su nezavisne, a njihovo miješanje pretvara hook od dva reda u cijelo poslijepodne.

Zašto hook čeka tunel koji čeka njega

OpenVPN poziva svoje hookove sinhrono, unutar istog procesa koji prenosi pakete. up se aktivira kada tun ili tap uređaj postoji, ali prije nego što se doda bilo koja ruta, a route-up nakon ruta; nijedan od tih trenutaka ne obećava da će druga strana odgovoriti. Dok se skripta iz bilo kojeg hooka još izvršava, demon ne prosljeđuje, pa naredba koja očekuje da saobraćaj pređe tunel čeka tunel koji čeka naredbu. To kružno čekanje je razlog zašto ručno pokretanje prolazi, a hook istekne.

Očigledna zakrpa, pauza od nekoliko sekundi, ponekad radi jer se udaljena strana sama podigla, a ne zato što je pauza nešto popravila. Pomoćnik koji provjerava spremnost je drugačiji odgovor: hook se vraća, prosljeđivanje počinje, a pomoćnik dobija ono što mu treba kada to zaista postoji.

Odaberite hook prema događaju, ne prema udobnosti

Prikačite up na posao kojem treba samo uređaj, route-up na posao kojem trebaju rute, a client-connect i client-disconnect sačuvajte za zadatke po klijentu na strani servera. Čišćenje pri prekidu veze mora podnijeti dvostruko izvršavanje, jer ponovna spajanja preko trajnog interfejsa ne slijede isti niz kao potpuni restart. Na serveru se client-connect aktivira kada se klijent autentificira, a ne kada demon starta, što vrijedi potvrditi prije nego se logika premjesti tamo. Ako posao pripada životnom ciklusu servisa, a ne jednoj vezi, systemd jedinica je bolji dom od bilo kojeg hooka.

Hook naredbe izvršava direktno demon, bez ljuske između, pa ifconfig_remote u liniji up stiže kao doslovan tekst. Umotajte naredbu u eksplicitnu ljusku ili držite logiku u skripti koja čita okruženje. ipchange je jedna direktiva koja dodaje vlastite argumente: predaje adresu i port naredbi, pa skripta napisana bez njih vidi dva neočekivana.

Tri načina da odvojite posao

Prva opcija je poslati pomoćnika u pozadinu iz samog hooka: pokrenite ga s setsid ili systemd-run --scope, zatvorite naslijeđene deskriptore i odmah izađite s nulom. Druga je da hook zapiše mali fajl stanja, a systemd tajmer ili path jedinica djeluje na njega, što hook drži trivijalnim i stavlja politiku ponavljanja tamo gdje postoje logovi. Treća je potpuno odbaciti hook i premjestiti posao u jedinicu poredanu nakon VPN servisa, što je ispravan odgovor kada posao uopće nije po vezi. Sve tri dijele jedno pravilo: hook se mora vratiti prije nego mu zatreba tunel.

Šta god izabrali, učinite pomoćnika idempotentnim i vidljivim. Dva preklapajuća poziva ne smiju izvršiti istu nepovratnu radnju dvaput, a pomoćnik koji padne mora ostaviti nešto što čovjek može pročitati.

Odvojite kvarove sandboxa od kvarova životnog ciklusa

Kada skripta radi s root prompta i padne kao servis, uzrok je obično sandbox, a ne mreža. Restriktivni ProtectHome, samo za čitanje ProtectSystem ili radni direktorij koji ne postoji mogu ostaviti skriptu ili njene podatke nedostupnima, a na SELinux hostu fajlu treba i kontekst koji dopušta izvršavanje. Pročitajte jedinicu s systemctl cat openvpn-server@server i dnevnik s journalctl -u openvpn-server@server -n 80, pa tražite grešku dozvole ili konteksta, a ne tajmaut veze. Isključivanje sandboxa treba biti posljednji potez, ne prvi.

Kvar životnog ciklusa izgleda drugačije: hook starta, pomoćnik radi, a socket jednostavno još nije tu. Zapišite liniju s vremenskom oznakom iz samog hooka, prekinite i ponovo se spojite, pa čitajte događaje po redu. Kada pomoćniku zaista treba tunel, neka provjerava spremnost umjesto da spava fiksni period.

Tri polja čine sljedeći izvještaj korisnim: koji hook je radio, koji račun je koristio i gdje se zaustavio. Bez njih svaka kasnija istraga počinje ispočetka.

Povezani članci