क्यों एक 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 या सेवा का माउंट नेमस्पेस होस्ट के निरपेक्ष पथ को सीधे अनुपस्थित कर सकता है। अंत में पहुँच पहचान है, जो दृश्यता से अलग प्रश्न है।
ProtectHome और PrivateTmp अलग-अलग स्थान छिपाते हैं, और इनमें से कोई भी होस्ट से ली गई निर्देशिका सूची में नहीं दिखता। शेल में root के लिए मौजूद पथ यूनिट के नेमस्पेस के भीतर अदृश्य हो सकता है, और इसलिए सेवा के बाहर वही कमांड जाँचना बहुत कम साबित करता है।
सेवा को विस्तारित किए बिना खोज ठीक करें
पथ एंकर करना केवल पहली सीमा हल करता है। यह वह निर्देशिका उजागर नहीं करता जिसे सेवा छिपाती है, और यह बिना विशेषाधिकार वाले खाते को केवल root के लिए वाली फ़ाइल तक पहुँच नहीं देता। script-security बढ़ाना यह बदलता है कि OpenVPN कौन सी स्क्रिप्ट चलाएगा; सापेक्ष नाम कहाँ हल होता है इस पर इसका कोई प्रभाव नहीं है। पूरी सेवा के लिए कार्यशील निर्देशिका बदलना समस्या से अधिक व्यापक है, क्योंकि हर दूसरा सापेक्ष प्रमाणपत्र, लॉग या सहायक पथ उसके साथ चला जाता है।
संकीर्ण सुधार पसंद करें: स्क्रिप्ट में नियतात्मक पथ, इंस्टेंस डेटा के लिए स्पष्ट कॉन्फ़िगरेशन मान, और फ़ाइल स्वामित्व जो उस खाते से मेल खाए जिसके अंतर्गत हुक वास्तव में चलता है।
ऐसे साक्ष्य दर्ज करें जो सीमा का नाम लें
उपयोगी विफलता रिपोर्ट में तीन चीज़ें होती हैं: वह सटीक पथ जिसे हुक ने आज़माया, वह वातावरण जिसने उसे बनाया, और किस सीमा ने मना किया। फ़ाइल की सामग्री उँडाले बिना हल किया गया पथ और अपवाद छापें। यह त्रयी ग़लत एंकर को छिपे हुए माउंट से और अनुमति के इनकार से अलग करती है, और ये तीन अलग सुधार हैं।
यह दावा कि root टर्मिनल से फ़ाइल पढ़ सकता है, उन प्रश्नों में से एक का उत्तर देता है और बाकी किसी का नहीं। इसके बजाय सेवा के अपने संदर्भ से जाँचें।