OpenVPN shell'da ishlaydi, cron ostida esa ishlamaydi: muammo PATH'da
Shell'dan ulanadigan buyruq tunnel boshlanishidan oldin cron yoki subprocess ostida ishlamay qolishi mumkin. Yo'lni, ish katalogini va terminalni tuzating.
Xuddi shu buyruq shell'dan ulanadi va cron ostida o'ladi, shuning uchun tabiiy xulosa — tunnel yoki sertifikat aybdor. Bunga ishonishdan oldin ikki ishga tushishning umumiy tomonini ko'ring: binar fayl, konfiguratsiya va hisob ma'lumotlari bir xil, faqat jarayon muhiti o'zgargan. Dastur hatto topilmasa, TLS tuzatishning hech qanday miqdori yordam bermaydi. Tuzatish odatda yo'lda, ish katalogida va bir hovuch muhit o'zgaruvchisida bo'ladi, VPN'da emas.
command -v openvpn ishlaydigan shell'da javobni chop etadi va bu ko'pincha /usr/sbin/openvpn, ya'ni cron o'z qidiruv yo'liga qo'ymaydigan katalog.
Tunnel hech qachon boshlanmagan, demak muammo tunnelda emas
cron boshlagan ishlar minimal muhitni meros oladi, odatda PATH=/usr/bin:/bin, va boshqaruvchi terminalga ega bo'lmaydi. /usr/sbin yoki /usr/local/sbin ichida o'rnatilgan hamma narsa o'sha ro'yxatda umuman yo'q va jurnal satri TLS xatosi o'rniga openvpn: not found deb o'qiydi. Python'ning subprocess boshqacha ishlamay qoladi: u interpretator jarayonining muhitini meros oladi, bu cron'dan boyroq bo'lishi mumkin, lekin tildani ochish uchun hali ham shell yo'q. Ikkala muvaffaqiyatsizlik ham bitta paket xostdan chiqmasdan oldin sodir bo'ladi.
Ularni ajratishning tez usuli — oxirgi emas, birinchi xatoni o'qish. Yo'q binar shell yoki Python istisnosini keltiradi, yomon konfiguratsiya OpenVPN foydalanish xabarini keltiradi, haqiqiy handshake muvaffaqiyatsizligi esa vaqt belgilari va hamkor manzillarini keltiradi. Faqat uchinchisi tunnel muammosi.
Absolyut yo'llar va argumentlar ro'yxati shell satrlaridan ustun
Hal qilingan yo'lni aniq bering va shell'ni butunlay chetlab o'ting. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) sizga qaytish kodi, stdout va stderr beradi, shell'dan fayl nomini izohlashni so'ramasdan. Konfiguratsiya yo'lini os.environ["HOME"] yoki pathlib.Path.home() dan quring, shunda tildani hech qachon ochish kerak bo'lmaydi. Haqiqatan shell sintaksisi kerak bo'lsa, shlex.split dan foydalaning, chunki satrni .split() bilan bo'lish bo'sh joy bor har qanday yo'lda buziladi. stderr'ni ham o'qing, chunki OpenVPN erta muvaffaqiyatsizliklarining ko'pini o'sha yerga yozadi.
Xuddi shu qoida cron'ga ham tegishli: ish satri login shell emas, shuning uchun hech narsa profilingizni yuklamaydi va hech narsa taxalluslaringizni belgilamaydi.
crontab aslida nimani meros oladi
crontab yozuvi crontab e'lon qilgan muhitni va bir nechta meros qolgan standart qiymatlarni oladi, shuning uchun yo'lni to'liq yozing yoki chaqiruvni buni qiladigan skriptga o'rang. Faylning yuqorisidagi PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin kabi satr odatiy o'rnatish joylarini qamrab oladi va >> cron.log 2>&1 bilan qayta yo'naltirish keyingi muvaffaqiyatsizlikni o'qish mumkin qiladi. Parol iborasi bilan himoyalangan profil cron ostida o'z sirini so'rashning yo'liga ega emas, chunki so'rash uchun terminal yo'q. Bunday ulanish hisob ma'lumotlari faylini o'qiy oladigan systemd birligiga tegishli, o'zini interaktiv ko'rsatadigan ishga emas.
Nisbiy yo'llar ikkinchi tuzoq. Sinov odatda profil joylashgan papkadan o'tkaziladi, cron ishi esa butunlay boshqa joydan boshlanadi, shuning uchun --config office.ovpn u yerda yo'q faylga hal qilinadi va xabar yo'q tunnel emas, yo'q fayl sifatida o'qiladi.
Muhitni yechib buni isbotlang
Minimal muhitni to'g'ridan-to'g'ri qayta yarating: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. O'sha ishdan yo'l yoki terminal haqida shikoyat kelsa, muammo VPN'dan yuqorida. Agar u ulansa, qolgan gumondorlar — u ishlaydigan hisob, u boshlaydigan katalog va u taqdim etadigan hisob ma'lumoti. Ikki natijadan qaysi biri bo'lsa ham sertifikatlarni tekshirishning yana bir bosqichidan yaxshiroq.
Keyin o'ramni o'zi hisobot beradigan qiling. Yetib borgan har bir bosqich uchun alohida holat bilan chiqing, ikkala oqimni vaqt belgisi bilan jurnalga yozing va keyingi muvaffaqiyatsizlik u yo'lni hal qilishda, autentifikatsiyada yoki tunnel allaqachon ko'tarilganda o'lganini aytadi.
Birlikka to'g'ri tartib ham kerak: Wants=network-online.target bilan After=network-online.target mijozi manzil yoki standart marshrut paydo bo'lishidan oldin boshlashdan saqlaydi, aks holda bu qo'lda qayta ishga tushirishda yo'qoladigan sertifikat yoki TLS xatolari sifatida ko'rinadi.