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 შეცდომებად ვლინდება და ხელით გადატვირთვისას ქრება.