OpenVPN berjalan dalam shell tetapi gagal di bawah cron: masalahnya PATH
Perintah yang bersambung dari shell boleh gagal di bawah cron atau subprocess sebelum terowong bermula. Betulkan laluan, direktori kerja dan terminal.
Perintah yang sama bersambung dari shell dan mati di bawah cron, jadi kesimpulan semula jadinya ialah terowong atau sijil yang bersalah. Lihat apa persamaan kedua-dua larian sebelum mempercayainya: binari, konfigurasi dan kelayakan adalah sama, dan hanya persekitaran proses berubah. Apabila program itu sendiri tidak ditemui, tiada jumlah penyahpepijatan TLS yang membantu. Pembetulan biasanya terletak pada laluan, direktori kerja dan segelintir pemboleh ubah persekitaran, bukan pada VPN.
command -v openvpn dalam shell yang berfungsi mencetak jawapannya, dan selalunya /usr/sbin/openvpn, iaitu direktori yang tidak diletakkan cron pada laluan cariannya.
Terowong tidak pernah bermula, jadi terowong bukan masalahnya
Tugas yang dimulakan cron mewarisi persekitaran minimum, lazimnya PATH=/usr/bin:/bin, dan tiada terminal pengawal. Apa-apa yang dipasang dalam /usr/sbin atau /usr/local/sbin sememangnya tiada dalam senarai itu, dan baris log membaca openvpn: not found dan bukannya ralat TLS. subprocess Python gagal secara berbeza: ia mewarisi persekitaran proses penterjemah, yang mungkin lebih kaya daripada cron tetapi masih tiada shell untuk mengembangkan tilde. Kedua-dua kegagalan berlaku sebelum satu paket pun meninggalkan hos.
Cara cepat untuk membezakannya ialah membaca ralat pertama dan bukan yang terakhir. Binari yang hilang menghasilkan pengecualian shell atau Python, konfigurasi buruk menghasilkan mesej penggunaan OpenVPN, dan kegagalan jabat tangan sebenar menghasilkan cap masa dan alamat rakan. Hanya yang ketiga ialah masalah terowong.
Laluan mutlak dan senarai argumen mengalahkan rentetan shell
Berikan laluan yang telah diselesaikan secara jelas dan langkaui shell sepenuhnya. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) memberi anda kod pulangan, stdout dan stderr tanpa meminta shell mentafsir nama fail. Bina laluan konfigurasi daripada os.environ["HOME"] atau pathlib.Path.home(), supaya tilde tidak perlu dikembangkan. Apabila benar-benar memerlukan sintaks shell, gunakan shlex.split, kerana memecahkan rentetan dengan .split() rosak pada mana-mana laluan yang mengandungi ruang. Baca juga stderr, kerana OpenVPN menulis kebanyakan kegagalan awalnya di situ.
Peraturan yang sama terpakai kepada cron: baris tugas bukan shell log masuk, jadi tiada apa memuatkan profil anda dan tiada apa mentakrifkan alias anda.
Apa yang sebenarnya diwarisi crontab
Entri crontab mendapat persekitaran yang diisytiharkan crontab serta beberapa nilai lalai yang diwarisi, jadi tulis laluan itu sepenuhnya atau balut panggilan dalam skrip yang melakukannya. Baris seperti PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin di bahagian atas fail meliputi lokasi pemasangan biasa, dan pengalihan dengan >> cron.log 2>&1 itulah yang menjadikan kegagalan seterusnya boleh dibaca. Profil yang dilindungi frasa laluan tiada cara meminta rahsianya di bawah cron, kerana tiada terminal untuk bertanya. Sambungan sedemikian patut berada dalam unit systemd yang boleh membaca fail kelayakan, bukan dalam tugas yang berpura-pura interaktif.
Laluan relatif ialah perangkap kedua. Larian ujian sering berlaku dari folder yang menyimpan profil, dan tugas cron bermula di tempat lain sama sekali, jadi --config office.ovpn menyelesaikan kepada fail yang tiada di situ dan mesejnya dibaca sebagai fail hilang dan bukan terowong hilang.
Buktikan dengan melucutkan persekitaran
Hasilkan semula persekitaran minimum secara langsung: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. Aduan laluan atau terminal daripada larian itu bermakna masalahnya terletak di atas VPN. Jika ia bersambung, yang disyaki selebihnya ialah akaun yang menjalankannya, direktori ia bermula, dan kelayakan yang dikemukakannya. Mana-mana daripada dua keputusan itu lebih baik daripada satu lagi pusingan pemeriksaan sijil.
Kemudian jadikan pembalut itu melaporkan dirinya sendiri. Keluar dengan status berbeza bagi setiap peringkat yang dicapai, log kedua-dua aliran dengan cap masa, dan kegagalan seterusnya akan memberitahu anda sama ada ia mati semasa penyelesaian laluan, semasa pengesahan, atau selepas terowong sudah naik.
Unit juga memerlukan susunan yang betul: Wants=network-online.target bersama After=network-online.target menghalang klien daripada bermula sebelum alamat atau laluan lalai wujud, yang jika tidak muncul sebagai ralat sijil atau TLS yang hilang apabila dimulakan semula secara manual.