რატომ ვერ პოულობს OpenVPN-ის კაუჭი თავისი სკრიპტის გვერდით არსებულ ფაილს
კაუჭში ფარდობითი ბილიკები იხსნება პროცესის, და არა სკრიპტის მიმართ. დაამაგრეთ ისინი __file__-ით, შემდეგ ნებართვებამდე შეამოწმეთ სახელთა სივრცე და იდენტობა.
კაუჭები, რომლებიც შეცდომის გარეშე მუშაობენ და მაინც აცხადებენ დაკარგულ ფაილს, ჩვეულებრივ არასწორ ადგილს უყურებენ და არა თავიანთ საქმეში მარცხდებიან. სკრიპტში ფარდობითი ბილიკები იხსნება პროცესის სამუშაო დირექტორიის მიმართ, ხოლო სერვისი იწყება ისეთი სამუშაო დირექტორიით, რომელიც თქვენ არ აგირჩევიათ. სკრიპტის გვერდით არსებული ფაილი და ფაილი, რომელსაც პროცესი ხსნის, ერთი და იგივე მხოლოდ მაშინაა, როცა რაღაც ამაგრებს მათ. ეს სხვაობა ხსნის კაუჭების იმ წარუმატებლობების დიდ ნაწილს, რომლებსაც შეცდომით ნებართვების პრობლემად კითხულობენ.
შეამოწმეთ ბილიკი ნებართვებამდე, რადგან არასწორ ფაილზე ნებართვის შეცდომა მაინც არასწორი ფაილია.
ფარდობითი ბილიკი იხსნება პროცესის მიმართ და არა ფაილის
როცა სკრიპტი იძახებს open("policy.json"), ბირთვი სახელს ხსნის პროცესის მიმდინარე სამუშაო დირექტორიის მიმართ. სკრიპტის საკუთარი მდებარეობიდან არაფერი მონაწილეობს ამ ძიებაში. OpenVPN კაუჭებს იწყებს საკუთარ მიერ არჩეული დირექტორიიდან და cd პარამეტრს შეუძლია მისი შეცვლა, ამიტომ საკუთარი საქაღალდიდან ხელით გამოცდილი სკრიპტი სხვაგვარად იქცევა, როცა დემონი ამუშავებს მას. ხელით ტესტი გადის, სერვისის გაშვება ვარდება და ჟურნალის სტრიქონი მხოლოდ დაკარგულ სახელს ახსენებს.
Python სკრიპტის მდებარეობას ამჟღავნებს როგორც __file__, და სწორედ ეს ხდის დამაგრებას შესაძლებელს. Path(__file__).resolve().parent / "policy.json" ბილიკს აშენებს ფაილიდან და არა პროცესიდან. ეს ერთი სტრიქონი აშორებს სამუშაო დირექტორიაზე დამოკიდებულებას, უფლებებში არაფრის შეცვლის გარეშე.
განზრახ დაამაგრეთ ბილიკი, შემდეგ შეამოწმეთ რას აკეთებს resolve
resolve() მიჰყვება სიმბოლურ ბმულებს, ამიტომ ინსტალაცია, რომელიც კაუჭს თავის ადგილზე ბმავს, მაგრდება ბმულის სამიზნესთან და არა ბმულის შემცველ დირექტორიასთან. ეს ჩვეულებრივ სასურველია ვერსირებული განთავსებისთვის და არასწორია განლაგებისთვის, რომელიც სიმბოლური ბმულის გვერდით მონაცემებს ელოდება. გადაწყვიტეთ, რას გულისხმობს განთავსება, და დაწერეთ კოდი შესაბამისად, ნაცვლად იმისა, რომ სხვაობა წარმოებაში აღმოაჩინოთ. Path(__file__).parent გარეშე resolve() ინარჩუნებს თავად ბმულის დირექტორიას.
თუ მონაცემები ეკუთვნის ინსტანციას და არა პროგრამას, აიღეთ აბსოლუტური ბილიკი კონფიგურაციიდან. მდებარეობის მყარი კოდირება კაუჭს ერთ ჰოსტის განლაგებაზე აბამს.
გაიარეთ ოთხი საზღვარი თანმიმდევრობით
დაიწყეთ სამუშაო დირექტორიით: შეადარეთ ერთეულის WorkingDirectory, OpenVPN-ის cd პარამეტრი და ნებისმიერი გარსი, რომელიც exec-მდე დირექტორიას ცვლის. შემდეგ დაადასტურეთ გახსნილი მდებარეობა, რადგან სხვა განთავსებაში მსგავსი სახელის ფაილმა შეიძლება ძიებას უპასუხოს და შეცდომა დამალოს. შემდეგ მოდის ფაილური სისტემის ხედი: chroot ან სერვისის mount-სახელთა სივრცე შეიძლება ჰოსტის აბსოლუტური ბილიკი უბრალოდ არარსებული გახადოს. ბოლოს არის წვდომის იდენტობა, რაც ხილვადობისგან ცალკე საკითხია.
ProtectHome და PrivateTmp სხვადასხვა მდებარეობას მალავს და არცერთი არ ჩანს ჰოსტიდან აღებულ დირექტორიათა ჩამონათვალში. ბილიკი, რომელიც root-ისთვის ჭურვში არსებობს, შეიძლება უხილავი იყოს ერთეულის სახელთა სივრცეში, და ამიტომ სერვისის გარეთ იმავე ბრძანების გამოცდა ძალიან ცოტას ამტკიცებს.
გაასწორეთ ძიება სერვისის გაფართოების გარეშე
ბილიკის დამაგრება მხოლოდ პირველ საზღვარს ხსნის. ის არ ამჟღავნებს დირექტორიას, რომელსაც სერვისი მალავს, და არ აძლევს უფლებების არმქონე ანგარიშს წვდომას მხოლოდ root-ისთვის განკუთვნილ ფაილზე. script-security ამაღლება ცვლის, რომელი სკრიპტები გაუშვას OpenVPN-მა; მას არანაირი გავლენა არ აქვს იმაზე, სად იხსნება ფარდობითი სახელი. მთელი სერვისის სამუშაო დირექტორიის შეცვლა პრობლემაზე უფრო ფართოა, რადგან ყოველი სხვა ფარდობითი სერთიფიკატის, ჟურნალის ან დამხმარე ბილიკი მასთან ერთად მოძრაობს.
უპირატესობა მიანიჭეთ ვიწრო შესწორებას: განმსაზღვრელი ბილიკი სკრიპტში, კონფიგურაციის მკაფიო მნიშვნელობა ინსტანციის მონაცემებისთვის და ფაილის მფლობელობა, რომელიც შეესაბამება ანგარიშს, რომლის ქვეშაც კაუჭი რეალურად მუშაობს.
ჩაწერეთ მტკიცებულება, რომელიც ასახელებს საზღვარს
სასარგებლო წარუმატებლობის ანგარიში სამ რამეს შეიცავს: ზუსტ ბილიკს, რომელიც კაუჭმა სცადა, გარემოს, რომელმაც ის შექმნა, და რომელმა საზღვარმა თქვა უარი. დაბეჭდეთ გახსნილი ბილიკი და გამონაკლისი ფაილის შიგთავსის დაღვრის გარეშე. ეს სამეული გამოყოფს არასწორ დამაგრებას დამალული mount-ისა და ნებართვის უარისგან, რაც სამი განსხვავებული შესწორებაა.
მტკიცება, რომ root-ს შეუძლია ფაილის წაკითხვა ტერმინალიდან, პასუხობს ამ კითხვებიდან ერთს და არცერთს დანარჩენთაგან. სამაგიეროდ გამოსცადეთ თავად სერვისის კონტექსტიდან.