OpenVPN beží v shelli, ale pod cronom zlyháva: problém je v PATH
Príkaz, ktorý sa pripojí zo shellu, môže pod cronom alebo subprocessom zlyhať ešte pred spustením tunela. Opravte cestu, pracovný adresár a terminál.
Ten istý príkaz sa zo shellu pripojí a pod cronom umrie, takže prirodzený záver je, že na vine je tunel alebo certifikát. Než tomu uveríte, pozrite sa, čo majú oba behy spoločné: binárka, konfigurácia a prihlasovacie údaje sú rovnaké a zmenilo sa len prostredie procesu. Keď sa program vôbec nenájde, žiadne ladenie TLS nepomôže. Oprava zvyčajne leží v ceste, pracovnom adresári a hŕstke premenných prostredia, nie vo VPN.
command -v openvpn v shelli, ktorý funguje, vypíše odpoveď, a to je veľmi často /usr/sbin/openvpn, teda adresár, ktorý cron do svojej vyhľadávacej cesty nedáva.
Tunel sa nikdy nespustil, takže problém nie je v tuneli
Úlohy spustené cronom dedia minimálne prostredie, zvyčajne PATH=/usr/bin:/bin, a žiadny riadiaci terminál. Čokoľvek nainštalované v /usr/sbin alebo /usr/local/sbin v tom zozname jednoducho chýba a riadok v logu znie openvpn: not found namiesto chyby TLS. Pythonový subprocess zlyháva inak: dedí prostredie procesu interpreta, ktoré môže byť bohatšie ako cronové, ale stále nemá shell, ktorý by rozbalil tildou. Obe zlyhania nastanú skôr, než jediný paket opustí hostiteľa.
Rýchly spôsob, ako ich rozlíšiť, je čítať prvú chybu namiesto poslednej. Chýbajúca binárka vytvorí výnimku shellu alebo Pythonu, zlá konfigurácia vytvorí správu o použití OpenVPN a skutočné zlyhanie handshake vytvorí časové značky a adresy protistrán. Len to tretie je problém tunela.
Absolútne cesty a zoznamy argumentov porážajú shellové reťazce
Odovzdajte vyriešenú cestu explicitne a shell úplne obíďte. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) vám dá návratový kód, stdout a stderr bez toho, aby ste žiadali shell o interpretáciu názvu súboru. Cestu ku konfigurácii stavajte z os.environ["HOME"] alebo pathlib.Path.home(), aby sa tilda nikdy nemusela rozbaľovať. Keď naozaj potrebujete shellovú syntax, použite shlex.split, pretože delenie reťazca pomocou .split() sa pokazí na každej ceste s medzerou. Čítajte aj stderr, pretože OpenVPN tam píše väčšinu svojich skorých zlyhaní.
To isté pravidlo platí pre cron: riadok úlohy nie je prihlasovací shell, takže nič nenačíta váš profil a nič nedefinuje vaše aliasy.
Čo crontab skutočne dedí
Položka v crontabe dostane prostredie, ktoré crontab deklaruje, plus niekoľko zdedených predvolených hodnôt, takže cestu vypíšte celú alebo volanie zabaľte do skriptu, ktorý to robí. Riadok ako PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin na začiatku súboru pokrýva obvyklé miesta inštalácie a presmerovanie pomocou >> cron.log 2>&1 je to, čo urobí ďalšie zlyhanie čitateľným. Profil chránený heslovou frázou nemá pod cronom ako požiadať o svoje tajomstvo, keďže neexistuje terminál, na ktorom by sa opýtal. Také spojenie patrí do jednotky systemd, ktorá vie čítať súbor s prihlasovacími údajmi, nie do úlohy, ktorá predstiera, že je interaktívna.
Relatívne cesty sú druhá pasca. Testovací beh sa často odohráva zo priečinka s profilom a úloha cronu začína úplne inde, takže --config office.ovpn sa vyrieši na súbor, ktorý tam nie je, a správa sa číta ako chýbajúci súbor, nie chýbajúci tunel.
Dokážte to vyzlečením prostredia
Reprodukujte minimálne prostredie priamo: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. Sťažnosť na cestu alebo terminál z toho behu znamená, že problém sedí nad VPN. Ak sa pripojí, zostávajúcimi podozrivými sú účet, pod ktorým beží, adresár, v ktorom začína, a údaj, ktorý predkladá. Ktorýkoľvek z oboch výsledkov je lepší ako ďalšie kolo kontroly certifikátov.
Potom urobte obal samovyhodnocujúcim. Ukončite sa so samostatným stavom pre každú dosiahnutú fázu, zaznamenajte oba toky s časovou značkou a ďalšie zlyhanie vám povie, či zomrel pri riešení cesty, pri autentifikácii alebo po tom, čo tunel už stál.
Jednotka potrebuje aj správne poradie: Wants=network-online.target plus After=network-online.target bránia klientovi spustiť sa skôr, než existuje adresa alebo predvolená trasa, čo sa inak prejaví ako chyby certifikátu alebo TLS, ktoré pri ručnom reštarte zmiznú.