OpenVPN पर chroot विफल: AppArmor नियम या क्षमता?
AppArmor प्रोफ़ाइल में पथ जोड़ने से कभी CAP_SYS_CHROOT नहीं मिलता, और अस्वीकृत chroot तीन अलग परतों से आ सकता है। तय करें कि किसे बदलना है।
डेमन chroot की विफलता दर्ज करता है और प्रोफ़ाइल पहले से उदार दिखती है, इसलिए लुभावना उपाय पथ-नियम को चौड़ा करके पुनः आरंभ करना है। इससे सामान्यतः कुछ नहीं बदलता, क्योंकि chroot उस विशेषाधिकार से नियंत्रित होता है जिसे प्रोफ़ाइल कभी सौंप ही नहीं सकती थी। किस परत को छूना है यह तय करने के लिए तीन सस्ती जाँच चाहिए: प्रक्रिया को क्या रखने की अनुमति है, नीति क्या अनुमति देती है, और लॉन्चर ने उन दोनों के मायने बनने से पहले क्या हटा दिया।
दो अलग द्वार, और केवल एक AppArmor का
chroot को उस उपयोगकर्ता नामस्थान में CAP_SYS_CHROOT चाहिए जिसमें प्रक्रिया चल रही है। यह सामान्य Linux विशेषाधिकार है, जिसे कर्नेल कॉल के पथों के साथ कुछ करने से पहले जाँचता है। अलग से, प्रवर्तन करने वाली AppArmor प्रोफ़ाइल क्षमता को अस्वीकार कर सकती है भले ही प्रक्रिया के पास वह हो, क्योंकि अनिवार्य नीति क्रेडेंशियल के बजाय उनके साथ परामर्शी जाती है। यह अंतर व्यवहार में मायने रखता है: दोनों परतें अलग फ़ाइलों में रहती हैं और सामान्यतः अलग लोग उन्हें बनाए रखते हैं।
वे दोनों द्वार एक ही errno के साथ विफल होते हैं। दोनों EPERM पैदा करते हैं, और दोनों डेमन लॉग में सामान्य अनुमति-शिकायत के रूप में दिखते हैं, इसीलिए प्रोफ़ाइल की विषयवस्तु का अनुमान लगाने में इतना समय बर्बाद होता है। जो पथ-नियम आप जोड़ने वाले थे वह chroot सफल होने के बाद फ़ाइल पहुँच नियंत्रित करता है; इससे कोई सरोकार नहीं कि क्रिया की अनुमति है या नहीं।
तीसरा द्वार दोनों के ऊपर है। यदि सेवा प्रबंधक या कोई रैपर प्रक्रिया को उसके बाउंडिंग सेट में क्षमता के बिना शुरू कर चुका है, तो कोई AppArmor परिवर्तन उसे वापस नहीं ला सकता, और प्रोफ़ाइल में क्षमताएँ जोड़ना केवल ऐसा इरादा दर्ज करता है जिसे कर्नेल नहीं मानेगा।
नीति संपादित करने से पहले विशेषाधिकार स्थिति पढ़ें
चालू प्रक्रिया से शुरू करें, न कि उस कॉन्फ़िगरेशन से जिसे आप सक्रिय मानते हैं। स्थिति फ़ाइल पाँच क्षमता मास्क और no-new-privileges फ़्लैग दिखाती है, और वे अलग प्रश्नों का उत्तर देते हैं:
grep -E '^(CapInh|CapPrm|CapEff|CapBnd|CapAmb|NoNewPrivs):' /proc/$(pidof openvpn)/status
sudo aa-status | grep -i openvpnCapEff वह समुच्चय है जो कॉल के लिए मायने रखता है: CapBnd में मौजूद पर CapEff में अनुपस्थित क्षमता छत द्वारा अनुमत है और इस समय धारित नहीं है। CapAmb तब मायने रखती है जब बाइनरी सामान्य setuid अर्थ में विशेषाधिकृत न हो, क्योंकि परिवेशी क्षमताएँ वह तरीका हैं जिससे सेवा फ़ाइल क्षमताओं के बिना exec के पार विशेषाधिकार रखती है। CapInh में ऐसे बिट हैं जो exec के पार विरासत में मिल सकते हैं, पर केवल तब जब निष्पादित फ़ाइल का विरासती समुच्चय अनुमति दे, इसलिए वहाँ का एक बिट अकेले कुछ नहीं देता।
फिर पुष्टि करें कि वास्तव में कौन-सी प्रोफ़ाइल जुड़ी है। किसी प्रक्रिया को ऐसे प्रोफ़ाइल नाम से सीमित किया जा सकता है जिसकी आपने अपेक्षा नहीं की, विशेषकर जब कोई वितरण अपनी यूनिट फ़ाइल और प्रोफ़ाइल साथ भेजता है, और /proc/PID/attr/current पढ़ना यह एक पंक्ति में तय कर देता है। अपनी संपादित फ़ाइल की तुलना कर्नेल द्वारा बताई गई प्रोफ़ाइल से करना कारण ठीक करने और ऐसी फ़ाइल संपादित करने के बीच का अंतर है जिसे कोई लोड नहीं करता।
क्षमता नियम केवल तब जोड़ें जब ऑडिट ट्रेल ऐसा कहे
कर्नेल और ऑडिट रिकॉर्ड अस्वीकार करने वाली परत का नाम लेते हैं। ऐसा इनकार खोजें जिसमें क्रिया capable और नाम sys_chroot हो, साथ में वह प्रोफ़ाइल जिसने उसे पैदा किया। यदि वह रिकॉर्ड मौजूद है, तो प्रक्रिया के पास क्षमता पहले से थी और AppArmor ने इनकार किया, और लक्षित परिवर्तन वास्तविक प्रोफ़ाइल के भीतर एक क्षमता नियम है:
capability sys_chroot,इसे उसी प्रोफ़ाइल में टुकड़े के रूप में रखें जो वास्तव में जुड़ी है, और कीवर्ड को apparmor.d प्रोफ़ाइल संदर्भ से मिलाएँ, किसी असंबंधित ट्यूटोरियल से नियम नकल करने के बजाय। इसे साझा include में डालने से वह हर उस सीमित प्रोग्राम को मिल जाता है जो उस फ़ाइल को खींचता है, और प्रोफ़ाइल को complain मोड में बदलने से अगला इनकार छिप जाता है, इसका समाधान होने के बजाय। प्रोफ़ाइल नियम नीति-इनकार हटाता है; वह विशेषाधिकार नहीं गढ़ता, इसलिए जिस प्रक्रिया के प्रभावी समुच्चय में कभी CAP_SYS_CHROOT नहीं था वह नियम होने पर भी विफल होगी।
यदि ऑडिट रिकॉर्ड में AppArmor का कोई इनकार न दिखे, तो प्रोफ़ाइल संपादित करना बंद करें। आप क्रेडेंशियल की समस्या देख रहे हैं, और बचा हुआ काम यूनिट फ़ाइल या मूल प्रक्रिया में है, नीति भाषा में नहीं।
सेवा प्रबंधक अपनी छत रखता है
systemd हर सेवा के लिए एक क्षमता बाउंडिंग सेट तय करता है, और डिफ़ॉल्ट रूप से वह समुच्चय संकीर्ण होता है। वहाँ जो भी बाहर रखा गया है वह प्रक्रिया के लिए अनुपलब्ध है, चाहे प्रोफ़ाइल कुछ भी कहे, इसीलिए कठोर यूनिट ऐसी क्रिया में विफल हो सकती हैं जो डेमन को हाथ से शुरू करने पर काम करती थी। संबंधित निर्देश यूनिट में पढ़ने में आसान हैं और जब एप्लिकेशन विफलता बताता है तब नज़र से ओझल होने में भी आसान हैं। वितरण पैकेज द्वारा भेजे गए drop-in ऐसी छत का सामान्य स्रोत हैं जिसे किसी को याद नहीं कि उसने कॉन्फ़िगर किया था।
छत उठाना और क्षमता देना दो परिवर्तन हैं, एक नहीं। बाउंडिंग सेट की प्रविष्टि कहती है कि प्रक्रिया क्षमता रख सकती है; वह उसे प्रभावी समुच्चय में नहीं जोड़ती, और NoNewPrivs बाद के उन्नयन को सफल होने से रोक सकता है, बाकी सब ठीक होने पर भी। केवल वही जोड़ें जो क्रिया को चाहिए, बाकी कठोरता बनाए रखें, और एक कॉल निकालने के लिए हर क्षमता देने के शॉर्टकट को ठुकराएँ।
यहाँ क्रम भी मायने रखता है। पहले यूनिट की छत बदलें, पुष्टि करें कि CapEff में अब वह बिट है, और तभी तय करें कि AppArmor अभी भी इनकार करता है या नहीं। दोनों परिवर्तन एक साथ करने पर विफलता बनी रहने पर आप फिर अनुमान लगाते रह जाते हैं।
इनकार हटने के बाद, जेल को ही जाँचें
सफल chroot मूल को हटा देता है, इसलिए डेमन जो भी पथ इसके बाद छूता है वह नए वृक्ष के भीतर हल होता है। गुम कॉन्फ़िगरेशन, अनुपस्थित डिवाइस नोड या प्रमाणपत्र निर्देशिका जो प्रतिलिपि नहीं हुई, अब फ़ाइल त्रुटि के रूप में दिखेंगे, और वह त्रुटि क्षमता की नहीं बल्कि व्यवस्था की समस्या है। अगली घटना पढ़ें, एक और व्यापक अनुमति जोड़ने के बजाय। यह स्थानांतरण सापेक्ष पथ का अर्थ भी बदल देता है, इसीलिए कठोरता मार्गदर्शिकाएँ डेमन कॉन्फ़िगरेशन में निरपेक्ष पथ पर ज़ोर देती हैं।
यह याद रखना भी मदद करता है कि chroot क्या नहीं करता। यह पथ की सीमा है, सैंडबॉक्स नहीं: जो प्रक्रिया विशेषाधिकार रखती है वह उससे भाग सकती है, इसीलिए क्षमता सामान्यतः कॉल के बाद गिरा दी जाती है और इसीलिए परिरोध डेमन के चारों ओर बना रहना चाहिए। AppArmor प्रोफ़ाइल, क्षमता बाउंडिंग सेट और फ़ाइलसिस्टम प्रतिबंधों को साथ रखना इस अभ्यास का उद्देश्य है, सेवा शुरू होने पर हटाने योग्य बचा हुआ कचरा नहीं।
निर्णय नियम छोटा है। यदि ऑडिट रिकॉर्ड AppArmor का नाम ले, तो जुड़ी प्रोफ़ाइल में एक क्षमता नियम जोड़ें। यदि प्रभावी समुच्चय खाली है, तो यूनिट की छत और विशेषाधिकार गिराने का क्रम ठीक करें। यदि प्रोफ़ाइल वह नहीं है जिसे आपने संपादित किया, तो संपादन बंद करें और असली को खोजें।