Ali lahko skript kavlja OpenVPN uporabi tunel, ki ga je pravkar zgradil?
OpenVPN izvaja kavlje znotraj lastnega zagona, zato skript, ki potrebuje tunel, čaka na tunel, ki čaka nanj. Ločite delo in izberite kavelj glede na dogodek.
Ali skript kavlja doseže drugo stran tunela, je odvisno od treh pogojev: na kateri dogodek je pritrjen, ali je OpenVPN med izvajanjem skripta še vedno znotraj svojega zagonskega zaporedja in ali je bilo delo od tega zaporedja ločeno. Večina skriptov spodleti pri tretjem. Dodajanje spanja obravnava problem življenjskega cikla kot problem časovnega usklajevanja in deluje ravno dovolj pogosto, da zavaja.
Najprej določite dogodek, nato mehanizem za odlaganje dela, nato mesto, kjer se odloženo delo izvaja. Te tri odločitve so neodvisne, njihovo mešanje pa je razlog, da iz vrstice ali dveh kavlja nastane celo popoldne.
Zakaj kavelj čaka na tunel, ki čaka nanj
OpenVPN svoje kavlje kliče sinhrono, znotraj istega procesa, ki premika pakete. up se sproži, ko naprava tun ali tap obstaja, a preden je dodana katera koli pot, route-up pa po poteh; noben od teh trenutkov ne obljublja, da bo nasprotna stran odgovorila. Dokler skript katerega koli kavlja še teče, daemon ne posreduje, zato ukaz, ki pričakuje, da bo promet prešel tunel, čaka na tunel, ki čaka na ukaz. To krožno čakanje je razlog, da ročni zagon uspe, kavelj pa poteče.
Očitna zaplata, spanje nekaj sekund, včasih deluje, ker se je oddaljeni konec dvignil sam, ne ker bi spanje kaj popravilo. Pomočnik, ki sprašuje o pripravljenosti, je drug odgovor: kavelj se vrne, posredovanje se začne in pomočnik dobi, kar potrebuje, ko je to res tam.
Izberite kavelj po dogodku, ne po udobju
Povežite up z delom, ki potrebuje samo napravo, route-up z delom, ki potrebuje poti, client-connect in client-disconnect pa prihranite za opravila za posameznega odjemalca na strani strežnika. Čiščenje ob odklopu mora zdržati dvojno izvajanje, ker ponovne povezave prek trajnega vmesnika ne sledijo istemu zaporedju kot popoln ponovni zagon. Na strežniku se client-connect sproži, ko se odjemalec overi, ne ko se daemon zažene, kar velja potrditi, preden se logika preseli tja. Če delo pripada življenjskemu ciklu storitve in ne eni povezavi, je enota systemd boljši dom kot kateri koli kavelj.
Ukaze kavlja izvaja neposredno daemon, brez vmesne lupine, zato ifconfig_remote v vrstici up prispe kot dobesedno besedilo. Ukaz ovijte v izrecno lupino ali logiko hranite v skriptu, ki bere okolje. ipchange je ena direktiva, ki doda lastne argumente: ukazu preda naslov in vrata, zato skript, napisan za nobenega, vidi dva nepričakovana.
Trije načini, kako delo ločiti
Prva možnost je poslati pomočnika v ozadje od znotraj kavlja: zaženite ga z setsid ali systemd-run --scope, zaprite podedovane deskriptorje in takoj končajte z nič. Druga je, da kavelj zapiše majhno datoteko stanja in da časovnik systemd ali potna enota deluje nanjo, kar ohranja kavelj trivialen in politiko ponovitev postavlja tja, kjer so dnevniki. Tretja je, da kavelj povsem opustite in delo preselite v enoto, urejeno za storitvijo VPN, kar je pravi odgovor, kadar delo sploh ni na povezavo. Vse tri delijo eno pravilo: kavelj se mora vrniti, preden potrebuje tunel.
Karkoli izberete, naredite pomočnika idempotentnega in opazljivega. Dva prekrivajoča se klica ne smeta iste nepovratne dejavnosti izvesti dvakrat, pomočnik, ki spodleti, pa mora pustiti nekaj, kar človek lahko prebere.
Ločite okvare peskovnika od okvar življenjskega cikla
Ko skript teče iz root poziva in kot storitev spodleti, je vzrok običajno peskovnik in ne omrežje. Omejevalni ProtectHome, samo za branje ProtectSystem ali delovni imenik, ki ne obstaja lahko naredijo skript ali njegove podatke nedosegljive, na gostitelju SELinux pa datoteka potrebuje tudi kontekst, ki dovoljuje izvajanje. Preberite enoto z systemctl cat openvpn-server@server in dnevnik z journalctl -u openvpn-server@server -n 80, nato iščite napako dovoljenja ali konteksta namesto časovne omejitve povezave. Onemogočanje peskovnika bi moralo biti zadnja poteza, ne prva.
Okvara življenjskega cikla je videti drugače: kavelj se zažene, pomočnik teče in vtičnice preprosto še ni. Zapišite vrstico s časovnim žigom iz samega kavlja, prekinite in znova povežite ter berite dogodke po vrsti. Ko pomočnik tunel res potrebuje, naj sprašuje o pripravljenosti, namesto da spi določeno obdobje.
Tri polja naredijo naslednje poročilo uporabno: kateri kavelj je tekel, kateri račun je uporabil in kje se je ustavil. Brez njih se vsaka poznejša preiskava začne znova.