SELinux नीति लिखना

एंड्रॉइड ओपन सोर्स प्रोजेक्ट (एओएसपी) उन एप्लिकेशन और सेवाओं के लिए एक ठोस आधार नीति प्रदान करता है जो सभी एंड्रॉइड डिवाइसों में आम हैं। AOSP में योगदानकर्ता नियमित रूप से इस नीति को परिष्कृत करते हैं। उम्मीद है कि मुख्य नीति अंतिम ऑन-डिवाइस नीति का लगभग 90-95% हिस्सा बनाएगी और डिवाइस-विशिष्ट अनुकूलन शेष 5-10% बनाएगी। यह आलेख इन डिवाइस-विशिष्ट अनुकूलन, डिवाइस-विशिष्ट नीति कैसे लिखें, और रास्ते में बचने के लिए कुछ नुकसानों पर केंद्रित है।

डिवाइस लाना

डिवाइस-विशिष्ट नीति लिखते समय, इन चरणों का पालन करें।

अनुमेय मोड में चलाएँ

जब कोई डिवाइस अनुमेय मोड में होता है, तो इनकार लॉग किया जाता है लेकिन लागू नहीं किया जाता है। अनुमेय मोड दो कारणों से महत्वपूर्ण है:

  • अनुमेय मोड यह सुनिश्चित करता है कि नीति लाने से अन्य प्रारंभिक डिवाइस लाने के कार्यों में देरी न हो।
  • एक ज़बरदस्ती किया गया इनकार अन्य इनकारों को छिपा सकता है। उदाहरण के लिए, फ़ाइल एक्सेस में आम तौर पर निर्देशिका खोज, फ़ाइल खोलना, फिर फ़ाइल पढ़ना शामिल होता है। प्रवर्तन मोड में, केवल निर्देशिका खोज अस्वीकृति होगी। अनुमेय मोड यह सुनिश्चित करता है कि सभी इनकार देखे जाएं।

किसी डिवाइस को अनुमेय मोड में डालने का सबसे सरल तरीका कर्नेल कमांड लाइन का उपयोग करना है। इसे डिवाइस की BoardConfig.mk फ़ाइल में जोड़ा जा सकता है: platform/device/<vendor>/<target>/BoardConfig.mk । कमांड लाइन को संशोधित करने के बाद, make clean , फिर make bootimage और नई बूट इमेज फ्लैश करें।

उसके बाद, अनुमेय मोड की पुष्टि करें:

adb shell getenforce

वैश्विक अनुमेय मोड में रहने के लिए दो सप्ताह का उचित समय है। अधिकांश अस्वीकरणों को संबोधित करने के बाद, प्रवर्तन मोड में वापस जाएँ और बग आने पर उन्हें संबोधित करें। जो डोमेन अभी भी अस्वीकरण उत्पन्न कर रहे हैं या सेवाएँ अभी भी भारी विकास के अधीन हैं, उन्हें अस्थायी रूप से अनुमेय मोड में रखा जा सकता है, लेकिन जितनी जल्दी हो सके उन्हें लागू करने वाले मोड में वापस ले जाएँ।

शीघ्र लागू करें

प्रवर्तन मोड में, इनकारों को लॉग किया जाता है और लागू किया जाता है। जितनी जल्दी हो सके अपने डिवाइस को एनफोर्सिंग मोड में लाना सबसे अच्छा अभ्यास है। डिवाइस-विशिष्ट नीति बनाने और लागू करने की प्रतीक्षा करने से अक्सर ख़राब उत्पाद और ख़राब उपयोगकर्ता अनुभव प्राप्त होता है। डॉगफ़ूडिंग में भाग लेने और वास्तविक दुनिया के उपयोग में कार्यक्षमता का पूर्ण परीक्षण कवरेज सुनिश्चित करने के लिए पर्याप्त जल्दी शुरुआत करें। जल्दी शुरू करने से यह सुनिश्चित होता है कि सुरक्षा संबंधी चिंताएँ डिज़ाइन निर्णयों को सूचित करती हैं। इसके विपरीत, केवल मनाही के आधार पर अनुमति देना एक असुरक्षित दृष्टिकोण है। इस समय का उपयोग डिवाइस का सुरक्षा ऑडिट करने और ऐसे व्यवहार के विरुद्ध बग दर्ज करने के लिए करें जिनकी अनुमति नहीं दी जानी चाहिए।

मौजूदा नीति हटाएं या मिटाएं

किसी नए डिवाइस पर शुरुआत से डिवाइस-विशिष्ट नीति बनाने के कई अच्छे कारण हैं, जिनमें शामिल हैं:

मुख्य सेवाओं से इनकार का पता लगाएं

मुख्य सेवाओं द्वारा उत्पन्न इनकारों को आम तौर पर फ़ाइल लेबलिंग द्वारा संबोधित किया जाता है। उदाहरण के लिए:

avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
scontext=u:r:mediaserver:s0
tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

/dev/kgsl-3d0 उचित रूप से लेबल करके पूरी तरह से संबोधित किया गया है। इस उदाहरण में, tcontext device है। यह एक डिफ़ॉल्ट संदर्भ का प्रतिनिधित्व करता है जहां /dev में सबकुछ " डिवाइस " लेबल प्राप्त करता है जब तक कि अधिक विशिष्ट लेबल असाइन नहीं किया जाता है। यहां केवल ऑडिट2अल्लो से आउटपुट स्वीकार करने से गलत और अत्यधिक अनुमेय नियम बन जाएगा।

इस प्रकार की समस्या को हल करने के लिए, फ़ाइल को एक अधिक विशिष्ट लेबल दें, जो इस मामले में gpu_device है। किसी और अनुमति की आवश्यकता नहीं है क्योंकि मीडियासर्वर के पास gpu_device तक पहुंचने के लिए मूल नीति में पहले से ही आवश्यक अनुमतियां हैं

अन्य डिवाइस-विशिष्ट फ़ाइलें जिन्हें मूल नीति में पूर्वनिर्धारित प्रकारों के साथ लेबल किया जाना चाहिए:

सामान्य तौर पर, डिफ़ॉल्ट लेबल को अनुमति देना गलत है। इनमें से कई अनुमतियाँ नेवरअलाउ नियमों द्वारा अस्वीकृत हैं, लेकिन जब स्पष्ट रूप से अस्वीकृत नहीं होती हैं, तब भी एक विशिष्ट लेबल प्रदान करना सबसे अच्छा अभ्यास है।

नई सेवाओं और पता अस्वीकरण को लेबल करें

Init-लॉन्च की गई सेवाओं को अपने स्वयं के SELinux डोमेन में चलाना आवश्यक है। निम्नलिखित उदाहरण सेवा "फू" को अपने स्वयं के SELinux डोमेन में डालता है और इसे अनुमतियाँ प्रदान करता है।

सेवा हमारे डिवाइस के init. device .rc फ़ाइल इस प्रकार है:

service foo /system/bin/foo
    class core
  1. एक नया डोमेन "फू" बनाएं

    निम्नलिखित सामग्री के साथ device/ manufacturer / device-name /sepolicy/foo.te फ़ाइल बनाएं:

    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;
    
    init_daemon_domain(foo)
    

    यह foo SELinux डोमेन के लिए प्रारंभिक टेम्पलेट है, जिसमें आप उस निष्पादन योग्य द्वारा निष्पादित विशिष्ट संचालन के आधार पर नियम जोड़ सकते हैं।

  2. लेबल /system/bin/foo

    निम्नलिखित को device/ manufacturer / device-name /sepolicy/file_contexts में जोड़ें:

    /system/bin/foo   u:object_r:foo_exec:s0
    

    यह सुनिश्चित करता है कि निष्पादन योग्य ठीक से लेबल किया गया है ताकि SELinux सेवा को उचित डोमेन में चला सके।

  3. बूट और सिस्टम छवियाँ बनाएँ और फ़्लैश करें।
  4. डोमेन के लिए SELinux नियमों को परिष्कृत करें।

    आवश्यक अनुमतियाँ निर्धारित करने के लिए अस्वीकरण का उपयोग करें। ऑडिट2अल्लो टूल अच्छे दिशानिर्देश प्रदान करता है, लेकिन इसका उपयोग केवल नीति लेखन को सूचित करने के लिए करें। केवल आउटपुट कॉपी न करें.

प्रवर्तन मोड पर वापस जाएँ

अनुमेय मोड में समस्या निवारण करना ठीक है, लेकिन जितनी जल्दी हो सके प्रवर्तन मोड पर वापस जाएँ और वहीं बने रहने का प्रयास करें।

सामान्य गलतियां

डिवाइस-विशिष्ट नीतियां लिखते समय होने वाली सामान्य गलतियों के लिए यहां कुछ समाधान दिए गए हैं।

निषेध का अति प्रयोग

निम्नलिखित उदाहरण नियम सामने के दरवाज़े को बंद करने लेकिन खिड़कियाँ खुली छोड़ने जैसा है:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

इरादा स्पष्ट है: तृतीय-पक्ष ऐप्स को छोड़कर सभी के पास डिबग डिवाइस तक पहुंच हो सकती है।

नियम कुछ मायनों में त्रुटिपूर्ण है। untrusted_app का बहिष्करण इस पर काम करना आसान है क्योंकि सभी ऐप्स वैकल्पिक रूप से isolated_app डोमेन में सेवाएँ चला सकते हैं। इसी तरह, यदि तृतीय-पक्ष ऐप्स के लिए नए डोमेन AOSP में जोड़े जाते हैं, तो उन्हें scary_debug_device तक भी पहुंच प्राप्त होगी। नियम अत्यधिक अनुमतिपूर्ण है. अधिकांश डोमेन को इस डिबगिंग टूल तक पहुंच से कोई लाभ नहीं होगा। नियम को केवल उन्हीं डोमेन को अनुमति देने के लिए लिखा जाना चाहिए था जिनके लिए पहुंच की आवश्यकता है।

उत्पादन में डिबगिंग सुविधाएँ

डिबग सुविधाएँ उत्पादन बिल्ड पर मौजूद नहीं होनी चाहिए और न ही उनकी नीति पर।

सबसे सरल विकल्प यह है कि डिबग सुविधा को केवल तभी अनुमति दी जाए जब SELinux eng/userdebug बिल्ड, जैसे adb root और adb shell setenforce 0 पर अक्षम हो।

एक अन्य सुरक्षित विकल्प डिबग अनुमतियों को userdebug_or_eng स्टेटमेंट में संलग्न करना है।

नीति आकार विस्फोट

SEAndroid नीतियों को जंगली रूप में चित्रित करना डिवाइस नीति अनुकूलन के विकास में एक चिंताजनक प्रवृत्ति का वर्णन करता है। डिवाइस-विशिष्ट नीति को किसी डिवाइस पर चलने वाली समग्र नीति का 5-10% हिस्सा होना चाहिए। 20%+ रेंज में अनुकूलन में लगभग निश्चित रूप से विशेषाधिकार प्राप्त डोमेन और मृत नीति शामिल होती है।

अनावश्यक रूप से बड़ी नीति:

  • मेमोरी पर दोहरा प्रभाव पड़ता है क्योंकि पॉलिसी रैमडिस्क में बैठती है और कर्नेल मेमोरी में भी लोड हो जाती है।
  • बड़ी बूटइमेज की आवश्यकता के कारण डिस्क स्थान बर्बाद होता है।
  • रनटाइम नीति लुकअप समय को प्रभावित करता है।

निम्नलिखित उदाहरण दो डिवाइस दिखाता है जहां निर्माता-विशिष्ट नीति में ऑन-डिवाइस नीति का 50% और 40% शामिल था। जैसा कि नीचे दिखाया गया है, नीति के पुनर्लेखन से कार्यक्षमता में कोई हानि नहीं होने के साथ पर्याप्त सुरक्षा सुधार प्राप्त हुए। (एओएसपी डिवाइस शामू और फ्लाउंडर तुलना के लिए शामिल हैं।)

चित्र 1: सुरक्षा ऑडिट के बाद डिवाइस-विशिष्ट नीति आकार की तुलना।

आकृति 1 । सुरक्षा ऑडिट के बाद डिवाइस-विशिष्ट नीति आकार की तुलना।

दोनों ही मामलों में, नीति आकार और अनुमतियों की संख्या दोनों में नाटकीय रूप से कम हो गई थी। नीति के आकार में कमी लगभग पूरी तरह से अनावश्यक अनुमतियों को हटाने के कारण है, जिनमें से कई audit2allow द्वारा उत्पन्न संभावित नियम थे जिन्हें अंधाधुंध रूप से नीति में जोड़ा गया था। दोनों डिवाइसों के लिए मृत डोमेन भी एक समस्या थी।

dac_override क्षमता प्रदान करना

dac_override इनकार का मतलब है कि आपत्तिजनक प्रक्रिया गलत यूनिक्स उपयोगकर्ता/समूह/विश्व अनुमतियों वाली फ़ाइल तक पहुंचने का प्रयास कर रही है। उचित समाधान लगभग कभी भी dac_override अनुमति नहीं देना है। इसके बजाय फ़ाइल या प्रक्रिया पर यूनिक्स अनुमतियाँ बदलें । कुछ डोमेन जैसे init , vold , और installd वास्तव में अन्य प्रक्रियाओं की फ़ाइलों तक पहुँचने के लिए यूनिक्स फ़ाइल अनुमतियों को ओवरराइड करने की क्षमता की आवश्यकता होती है। अधिक गहन स्पष्टीकरण के लिए डैन वॉल्श का ब्लॉग देखें।