OpenVPN shell-де жұмыс істейді, бірақ cron астында істен шығады: себебі PATH
Shell-ден қосылатын пәрмен туннель басталмай тұрып cron немесе subprocess астында сәтсіз аяқталуы мүмкін. Жолды, жұмыс каталогын және терминалды түзетіңіз.
Сол пәрмен shell-ден қосылады да, cron астында өледі, сондықтан табиғи қорытынды — туннель немесе сертификат кінәлі. Бұған сенбес бұрын екі жүгірістің ортақ не екенін қараңыз: бинарлық файл, конфигурация және тіркелгі деректері бірдей, тек процестің ортасы өзгерген. Бағдарлама тіпті табылмаса, TLS жөндеуінің қандай да бір мөлшері көмектеспейді. Түзету әдетте жолда, жұмыс каталогында және бір уыс орта айнымалысында болады, VPN-де емес.
command -v openvpn жұмыс істеп тұрған shell-де жауапты шығарады, және бұл өте жиі /usr/sbin/openvpn, яғни cron өзінің іздеу жолына қоспайтын каталог.
Туннель ешқашан басталған жоқ, сондықтан туннель мәселе емес
cron бастаған тапсырмалар ең аз ортаны мұраға алады, әдетте PATH=/usr/bin:/bin, және басқарушы терминалы болмайды. /usr/sbin немесе /usr/local/sbin ішінде орнатылғанның бәрі сол тізімде жай ғана жоқ, және журнал жолы TLS қатесінің орнына openvpn: not found деп оқылады. Python-ның subprocess басқаша істен шығады: ол интерпретатор процесінің ортасын мұраға алады, ол cron-нан байырақ болуы мүмкін, бірақ тильда таңбасын ашуға әлі де shell жоқ. Екі сәтсіздік те бір пакет те хосттан шықпай тұрып болады.
Оларды ажыратудың жылдам жолы — соңғы емес, бірінші қатені оқу. Жоқ бинарлық файл shell немесе Python ерекшелігін тудырады, нашар конфигурация OpenVPN пайдалану хабарламасын тудырады, ал нағыз handshake сәтсіздігі уақыт белгілері мен әріптес мекенжайларын тудырады. Тек үшіншісі ғана туннель мәселесі.
Абсолютті жолдар мен аргумент тізімдері shell жолдарынан басым
Шешілген жолды анық беріңіз және shell-ді мүлдем айналып өтіңіз. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) қайтару кодын, stdout пен stderr-ді береді, shell-ден файл атауын түсіндіруді сұрамай-ақ. Конфигурация жолын os.environ["HOME"] немесе pathlib.Path.home()-ден құрастырыңыз, сонда тильданы ешқашан ашуға тура келмейді. Шынымен shell синтаксисі қажет болса, shlex.split пайдаланыңыз, өйткені жолды .split() арқылы бөлу бос орын бар кез келген жолда бұзылады. stderr-ді де оқыңыз, өйткені OpenVPN өзінің ерте сәтсіздіктерінің көбін сонда жазады.
Сол ереже cron-ға да қатысты: тапсырма жолы кіру shell-і емес, сондықтан ештеңе профиліңізді жүктемейді және ештеңе бүркеншік аттарыңызды анықтамайды.
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 қателері ретінде көрінеді.