Pot un script de ganxo d’OpenVPN utilitzar el túnel que acaba de construir?
OpenVPN executa els ganxos dins del seu propi arrencament, així que un script que necessita el túnel espera un túnel que l’espera a ell. Separeu la feina i trieu el ganxo per esdeveniment.
Que un script de ganxo arribi a l’altre costat del túnel depèn de tres condicions: a quin esdeveniment està lligat, si OpenVPN encara és dins de la seva seqüència d’arrencament quan s’executa l’script, i si la feina s’ha separat d’aquesta seqüència. La majoria d’scripts fallen a la tercera. Afegir una espera tracta un problema de cicle de vida com un problema de temps, i funciona just prou sovint per enganyar.
Decidiu primer l’esdeveniment, després el mecanisme per ajornar la feina, després el lloc on s’executa la feina ajornada. Aquestes tres decisions són independents, i barrejar-les és com un ganxo de dues línies es converteix en una tarda.
Per què el ganxo espera un túnel que l’espera a ell
OpenVPN crida els seus ganxos de manera síncrona, dins del mateix procés que mou els paquets. up s’activa quan el dispositiu tun o tap existeix, però abans que s’afegeixi cap ruta, i route-up s’activa després de les rutes; cap dels dos moments promet que un parell respongui. Mentre un script de qualsevol dels ganxos encara s’executa, el dimoni no reenvia, així que una ordre que espera que el trànsit creui el túnel espera un túnel que espera l’ordre. Aquesta espera circular és la raó per la qual una execució manual passa i el ganxo fa temps d’espera.
El pedaç evident, esperar uns segons, de vegades funciona perquè l’extrem remot s’ha aixecat sol, no perquè l’espera hagi arreglat res. Un assistent que consulta la disponibilitat és una resposta diferent: el ganxo retorna, el reenviament comença, i l’assistent obté el que necessita quan realment hi és.
Trieu el ganxo per esdeveniment, no per comoditat
Lligueu up a la feina que només necessita el dispositiu, route-up a la feina que necessita rutes, i reserveu client-connect i client-disconnect per a tasques per client al costat del servidor. La neteja en desconnectar ha de tolerar executar-se dues vegades, ja que les reconnexions sobre una interfície persistent no segueixen la mateixa seqüència que un reinici complet. Al servidor, client-connect s’activa quan un client s’autentica, no quan arrenca el dimoni, cosa que val la pena confirmar abans de moure-hi la lògica. Si la feina pertany al cicle de vida del servei i no a una sola connexió, una unitat systemd és un lloc millor que qualsevol ganxo.
Les ordres del ganxo les executa directament el dimoni, sense cap shell entremig, així que ifconfig_remote en una línia up arriba com a text literal. Emboliqueu l’ordre en un shell explícit, o manteniu la lògica en un script que llegeixi l’entorn. ipchange és una directiva que afegeix arguments propis: lliura l’adreça i el port a l’ordre, així que un script escrit per a cap en veu dos d’inesperats.
Tres maneres de separar la feina
La primera opció és enviar l’assistent al fons des de dins del ganxo: inicieu-lo amb setsid o systemd-run --scope, tanqueu els descriptors heretats i sortiu amb zero de seguida. La segona és que el ganxo escrigui un petit fitxer d’estat i que un temporitzador systemd o una unitat de camí hi actuï, cosa que manté el ganxo trivial i posa la política de reintents on hi ha registres. La tercera és descartar el ganxo del tot i moure la feina a una unitat ordenada després del servei VPN, que és la resposta correcta quan la feina no és per connexió en absolut. Les tres comparteixen una regla: el ganxo ha de retornar abans que necessiti el túnel.
Tant és quina trieu, feu l’assistent idempotent i observable. Dues invocacions superposades no haurien d’executar la mateixa acció irreversible dues vegades, i un assistent que falla ha de deixar alguna cosa que una persona pugui llegir.
Separeu les fallades de sandbox de les fallades de cicle de vida
Quan un script s’executa des d’un indicador de root i falla com a servei, la causa sol ser una sandbox i no la xarxa. Una ProtectHome restrictiva, una ProtectSystem només de lectura, o un directori de treball que no existeix poden deixar l’script o les seves dades fora de l’abast, i en un amfitrió SELinux el fitxer també necessita un context que permeti l’execució. Llegiu la unitat amb systemctl cat openvpn-server@server i el registre amb journalctl -u openvpn-server@server -n 80, i busqueu un error de permís o de context en lloc d’un temps d’espera de connexió. Desactivar la sandbox hauria de ser l’últim moviment, no el primer.
Una fallada de cicle de vida es veu diferent: el ganxo arrenca, l’assistent corre i el sòcol simplement encara no hi és. Escriviu una línia amb marca de temps des del mateix ganxo, desconnecteu i reconnecteu, i llegiu els esdeveniments per ordre. Quan l’assistent necessiti realment el túnel, deixeu que consulti la disponibilitat en lloc de dormir un període fix.
Tres camps fan útil l’informe següent: quin ganxo s’ha executat, quin compte ha fet servir i on s’ha aturat. Sense ells, cada investigació posterior comença de zero.