OpenVPN běží v shellu, ale pod cronem selhává: problém je v PATH
Příkaz, který se ze shellu připojí, může pod cronem nebo subprocessem selhat ještě před spuštěním tunelu. Opravte cestu, pracovní adresář a terminál.
Stejný příkaz se ze shellu připojí a pod cronem umře, takže přirozený závěr je, že na vině je tunel nebo certifikát. Než tomu uvěříte, podívejte se, co mají oba běhy společné: binárka, konfigurace a přihlašovací údaje jsou stejné a změnilo se jen prostředí procesu. Když se program vůbec nenajde, žádné ladění TLS nepomůže. Oprava obvykle leží v cestě, pracovním adresáři a hrstce proměnných prostředí, ne ve VPN.
command -v openvpn v shellu, který funguje, vypíše odpověď, a to je velmi často /usr/sbin/openvpn, tedy adresář, který cron do své vyhledávací cesty nedává.
Tunel vůbec nezačal, takže problém není v tunelu
Úlohy spuštěné cronem dědí minimální prostředí, obvykle PATH=/usr/bin:/bin, a žádný řídicí terminál. Cokoli nainstalované v /usr/sbin nebo /usr/local/sbin v tom seznamu prostě chybí a řádek v logu zní openvpn: not found místo chyby TLS. Pythoní subprocess selhává jinak: dědí prostředí procesu interpretu, které může být bohatší než croní, ale pořád nemá shell, který by rozbalil tildou. Obě selhání nastanou dřív, než jediný paket opustí hostitele.
Rychlý způsob, jak je rozeznat, je číst první chybu místo poslední. Chybějící binárka vytvoří výjimku shellu nebo Pythonu, špatná konfigurace vytvoří zprávu o použití OpenVPN a skutečné selhání handshake vytvoří časová razítka a adresy protějšků. Jen to třetí je problém tunelu.
Absolutní cesty a seznamy argumentů porážejí shellové řetězce
Předejte vyřešenou cestu explicitně a shell úplně obejdě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, aniž byste žádali shell, aby interpretoval název souboru. Cestu ke konfiguraci stavějte z os.environ["HOME"] nebo pathlib.Path.home(), aby se tilda nikdy nemusela rozbalovat. Když skutečně potřebujete shellovou syntaxi, použijte shlex.split, protože dělení řetězce pomocí .split() se rozbije na každé cestě obsahující mezeru. Čtěte i stderr, protože OpenVPN tam píše většinu svých raných selhání.
Stejné pravidlo platí pro cron: řádek úlohy není přihlašovací shell, takže nic nenačte váš profil a nic nedefinuje vaše aliasy.
Co crontab skutečně dědí
Položka v crontabu dostane prostředí, které crontab deklaruje, plus několik zděděných výchozích hodnot, takže cestu vypište nebo volání zabalte do skriptu, který to udělá. Řádek jako PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin na začátku souboru pokrývá obvyklá místa instalace a přesměrování pomocí >> cron.log 2>&1 je to, co udělá další selhání čitelným. Profil chráněný heslem nemá pod cronem jak požádat o své tajemství, protože neexistuje terminál, na kterém by se zeptal. Takové spojení patří do jednotky systemd, která umí číst soubor s přihlašovacími údaji, ne do úlohy, která předstírá, že je interaktivní.
Relativní cesty jsou druhá past. Testovací běh se často odehrává ze složky, která drží profil, a croní úloha začíná úplně jinde, takže se --config office.ovpn vyřeší na soubor, který tam není, a zpráva se čte jako chybějící soubor, nikoli chybějící tunel.
Dokažte to svlečením prostředí
Reprodukujte minimální prostředí přímo: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. Stížnost na cestu nebo terminál z toho běhu znamená, že problém sedí nad VPN. Pokud se připojí, zbývajícími podezřelými jsou účet, pod kterým běží, adresář, ve kterém začíná, a údaj, který předkládá. Kterýkoli z obou výsledků je lepší než další kolo kontroly certifikátů.
Pak udělejte obal sebereportující. Ukončete se zvláštním stavem pro každou dosaženou fázi, zaznamenejte oba toky s časovým razítkem a příští selhání vám řekne, zda zemřel při řešení cesty, při autentizaci, nebo poté, co tunel už byl nahoře.
Jednotka také potřebuje správné řazení: Wants=network-online.target plus After=network-online.target brání klientovi spustit se dřív, než existuje adresa nebo výchozí trasa, což se jinak projeví jako chyby certifikátu nebo TLS, které při ručním restartu zmizí.