Истата команда се поврзува од школка и умира под cron, па природниот заклучок е дека тунелот или сертификатот е виновен. Пред да го поверувате тоа, погледнете што им е заедничко на двете извршувања: бинарната датотека, конфигурацијата и акредитивите се исти, а се промени само околината на процесот. Кога програмата воопшто не се наоѓа, никакво отстранување на грешки во TLS не помага. Поправката обично лежи во патека, работен директориум и грст променливи на околината, а не во VPN.

command -v openvpn во школката што работи ја печати одговорот, и тоа е многу често /usr/sbin/openvpn, директориум што cron не го става на својата патека за пребарување.

Тунелот никогаш не почна, значи тунелот не е проблемот

Задачите што ги стартува cron наследуваат минимална околина, вообичаено PATH=/usr/bin:/bin, и без контролен терминал. Сето што е инсталирано во /usr/sbin или /usr/local/sbin едноставно отсуствува од таа листа, и линијата во дневникот гласи openvpn: not found наместо грешка во TLS. 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 го спречуваат клиентот да стартува пред да постои адреса или стандардна рута, што инаку се појавува како грешки со сертификат или TLS што исчезнуваат при рачно рестартирање.

Поврзани статии