OpenVPN ради у љусци, али под cron-ом пада: проблем је PATH
Наредба која се повезује из љуске може пасти под cron-ом или subprocess-ом пре него што тунел крене. Поправите путању, радни директоријум и терминал.
Иста наредба се повезује из љуске и умире под cron-ом, па је природан закључак да су тунел или сертификат криви. Погледајте шта је двема покретањима заједничко пре него што у то поверујете: бинарна датотека, конфигурација и акредитиви су идентични, а променило се само окружење процеса. Када се програм ни не пронађе, никакво ТЛС отклањање грешака не помаже. Поправка обично лежи у путањи, радном директоријуму и шаци променљивих окружења, а не у VPN-у.
command -v openvpn у љусци која ради испише одговор, а то је врло често /usr/sbin/openvpn, директоријум који cron не ставља на своју путању претраживања.
Тунел никада није кренуо, па тунел није проблем
Послови које покреће cron наслеђују минимално окружење, уобичајено PATH=/usr/bin:/bin, и без контролног терминала. Све што је инсталирано у /usr/sbin или /usr/local/sbin једноставно недостаје на том списку, а ред у дневнику гласи openvpn: not found уместо ТЛС грешке. Python-ов subprocess пада другачије: наслеђује окружење процеса преводиоца, које може бити богатије од cron-овог, али још увек нема љуску која би раширила тилду. Оба пада се дешавају пре него иједан пакет напусти хоста.
Брз начин да их разликујете јесте да читате прву грешку уместо последње. Недостајућа бинарна датотека даје изузетак у љусци или Python-у, лоша конфигурација даје OpenVPN поруку о употреби, а стварни неуспех руковања даје временске ознаке и адресе партнера. Само је трећи проблем тунела.
Апсолутне путање и листе аргумената побеђују љускине низове
Проследите разрешену путању изричито и потпуно прескочите љуску. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) даје вам повратни код, stdout и stderr без тражења да љуска тумачи назив датотеке. Градите путању конфигурације из os.environ["HOME"] или pathlib.Path.home(), тако да тилду никада не треба ширити. Када вам истински треба љускина синтакса, користите shlex.split, јер дељење низа са .split() пуца на свакој путањи која садржи размак. Читајте и stderr, јер OpenVPN тамо записује већину својих раних неуспеха.
Исто правило важи и за cron: линија посла није пријавна љуска, па ништа не учитава ваш профил и ништа не дефинише ваше алијасе.
Шта crontab заправо наслеђује
Унос у crontab-у добија окружење које crontab декларише плус неколико наслеђених подразумеваних вредности, па испишите путању или умотајте позив у скрипту која то чини. Ред као PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin на врху датотеке покрива уобичајене локације инсталације, а преусмеравање са >> cron.log 2>&1 је оно што следећи неуспех чини читљивим. Профил заштићен приступном фразом нема начина да под cron-ом затражи своју тајну, јер нема терминала на коме би питао. Таква веза припада systemd јединици која може да чита датотеку акредитива, а не послу који се претвара да је интерактиван.
Релативне путање су друга замка. Тестно покретање се често дешава из фасцикле која држи профил, а cron посао почиње сасвим другде, па се --config office.ovpn разрешава у датотеку које нема и порука се чита као датотека која недостаје, а не тунел који недостаје.
Докажите то скидањем окружења
Репродукујте минимално окружење директно: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. Притужба на путању или терминал из тог покретања значи да проблем седи изнад VPN-а. Ако се повеже, преостали осумњичени су рачун под којим ради, директоријум у коме почиње и акредитив који представља. Било који од два исхода бољи је од још једне рунде провере сертификата.
Затим учините омотач самопријављујућим. Изађите са различитим статусом за сваку достигнуту фазу, забележите оба тока са временском ознаком, а следећи неуспех ће вам рећи је ли умро при разрешавању путање, при аутентификацији или након што је тунел већ био подигнут.
Јединици треба и исправан редослед: Wants=network-online.target плус After=network-online.target спречавају клијента да крене пре него што постоји адреса или подразумевана рута, што се иначе појављује као грешке сертификата или ТЛС-а које нестану при ручном поновном покретању.