La mateixa ordre es connecta des d’un shell i mor sota cron, així que la conclusió natural és que el túnel o el certificat tenen la culpa. Mireu què tenen en comú les dues execucions abans de creure-ho: el binari, la configuració i les credencials són idèntics, i només ha canviat l’entorn del procés. Quan el programa ni tan sols es troba, cap quantitat de depuració de TLS ajuda. La solució sol viure en un camí, un directori de treball i un grapat de variables d’entorn, no en la VPN.

command -v openvpn al shell que funciona imprimeix la resposta, i molt sovint és /usr/sbin/openvpn, un directori que cron no posa al seu camí de cerca.

El túnel no va arrencar mai, així que el túnel no és el problema

Les feines iniciades per cron hereten un entorn mínim, convencionalment PATH=/usr/bin:/bin, i cap terminal de control. Tot el que s’instal·la a /usr/sbin o /usr/local/sbin simplement és absent d’aquesta llista, i la línia del registre diu openvpn: not found en lloc d’un error de TLS. El subprocess de Python falla d’una altra manera: hereta l’entorn del procés de l’intèrpret, que pot ser més ric que el de cron però encara no té cap shell per expandir una titlla. Totes dues fallades passen abans que un sol paquet surti de l’amfitrió.

Una manera ràpida de distingir-les és llegir el primer error en lloc de l’últim. Un binari que falta produeix una excepció del shell o de Python, una configuració dolenta produeix un missatge d’ús d’OpenVPN, i una fallada real d’apretada de mans produeix marques de temps i adreces d’igual. Només la tercera és un problema de túnel.

Els camins absoluts i les llistes d’arguments guanyen les cadenes de shell

Passeu el camí resolt explícitament i prescindiu del shell del tot. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) us dona un codi de retorn, stdout i stderr sense demanar a cap shell que interpreti un nom de fitxer. Construïu el camí de la configuració a partir de os.environ["HOME"] o pathlib.Path.home(), perquè una titlla no s’hagi d’expandir mai. Quan realment necessiteu sintaxi de shell, feu servir shlex.split, perquè dividir una cadena amb .split() es trenca amb qualsevol camí que contingui un espai. Llegiu també stderr, ja que OpenVPN hi escriu la majoria de les seves fallades primerenques.

La mateixa regla val per a cron: la línia de la feina no és un shell d’inici de sessió, així que res no carrega el vostre perfil ni res no defineix els vostres àlies.

Què hereta realment un crontab

Una entrada de crontab rep l’entorn que declara el crontab més uns quants valors per defecte heretats, així que escriviu el camí sencer o emboliqueu la crida en un script que ho faci. Una línia com PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin a la part superior del fitxer cobreix les ubicacions d’instal·lació habituals, i redirigir amb >> cron.log 2>&1 és el que fa llegible la propera fallada. Un perfil protegit amb contrasenya no té manera de demanar el seu secret sota cron, ja que no hi ha cap terminal on preguntar. Aquesta connexió pertany a una unitat de systemd que pugui llegir un fitxer de credencials, no a una feina que fingeix ser interactiva.

Els camins relatius són la segona trampa. Una prova sovint es fa des de la carpeta que conté el perfil, i una feina de cron comença en un lloc completament diferent, així que --config office.ovpn es resol en un fitxer que no hi és i el missatge es llegeix com un fitxer que falta més que com un túnel que falta.

Demostreu-ho despullant l’entorn

Reproduïu l’entorn mínim directament: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. Una queixa de camí o de terminal d’aquesta execució vol dir que el problema seu per sobre de la VPN. Si es connecta, els sospitosos restants són el compte amb què s’executa, el directori on arrenca i la credencial que presenta. Qualsevol dels dos resultats és millor que una altra ronda de comprovació de certificats.

A continuació feu que l’embolcall s’autoinformi. Sortiu amb un estat diferent per a cada etapa assolida, registreu tots dos fluxos amb una marca de temps, i la propera fallada us dirà si va morir en la resolució del camí, en l’autenticació o després que el túnel ja fos aixecat.

Una unitat també necessita un ordre correcte: Wants=network-online.target més After=network-online.target impedeixen que el client arrenqui abans que existeixi una adreça o una ruta per defecte, cosa que altrament es manifesta com a errors de certificat o de TLS que desapareixen en un reinici manual.

Articles relacionats