Linux में अनुमतियाँ इस सवाल का जवाब देती हैं कि «यह फ़ाइल कौन पढ़ सकता है»। AppArmor दूसरे का जवाब देता है: «यह प्रोग्राम कर क्या सकता है»। फ़र्क़ सेंध के समय दिखता है। web shell वेब सर्वर के उपयोगकर्ता के रूप में चलती है और उसके सारे अधिकार पाती है — यानी आधे से ज़्यादा सिस्टम तक पढ़ने की पहुँच। AppArmor प्रोफ़ाइल प्रक्रिया को उन्हीं चीज़ों की सूची तक सीमित करती है जो उसे काम के लिए चाहिए, और /etc/shadow पढ़ने या /bin/bash चलाने की कोशिश उपयोगकर्ता की अनुमतियों से बेपरवाह इनकार पर ख़त्म होती है।

पहले से क्या चालू है

sudo aa-status

आउटपुट तीन सवालों का जवाब देता है: कितनी प्रोफ़ाइल लोड हैं, उनमें से कितनी enforce और complain मोड में हैं, और कौन सी प्रक्रियाएँ बिना किसी प्रोफ़ाइल के चलती हैं। सामान्य Ubuntu पर कुछ दर्जन प्रोफ़ाइल होंगी, पर लगभग सारी man और tcpdump जैसे सहायक प्रोग्रामों की। मुख्य सेवाएँ — nginx, Apache, PHP-FPM — आमतौर पर सीमित की सूची में नहीं होतीं।

तीन मोड जिनमें फ़र्क़ करना ज़रूरी है:

  • enforce — नियम लागू होते हैं, अतिरिक्त कुछ भी अस्वीकृत;
  • complain — उल्लंघन सिर्फ़ जर्नल में दर्ज होते हैं, कुछ रोका नहीं जाता। ट्यूनिंग का मोड;
  • unconfined — प्रोफ़ाइल है ही नहीं, प्रोग्राम बिना पाबंदी चलता है।

aa-status के आउटपुट का सबसे काम का हिस्सा आख़िरी है: वे प्रक्रियाएँ जो नेटवर्क पर सुनती हैं और किसी चीज़ से सीमित नहीं। शुरुआत उसी सूची से करनी चाहिए।

औज़ार

sudo apt install apparmor-utils

उस पैकेज के बिना aa-complain, aa-enforce और aa-logprof कमांडें सिस्टम में नहीं होतीं, भले ही ख़ुद AppArmor चल रहा हो।

सेवा रोके बिना प्रोफ़ाइल कैसे चालू करें

क्रम बुनियादी है। सीधे enforce में डाली गई प्रोफ़ाइल बड़ी संभावना के साथ सेवा को कुछ ज़रूरी चीज़ से मना कर देगी, और वह काम करना बंद कर देगी — आमतौर पर तुरंत नहीं, बल्कि किसी दुर्लभ क्रिया पर, जैसे फ़ाइल अपलोड या मेल भेजना।

सही क्रम:

sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

उस मोड में एक हफ़्ते का काम, हर असामान्य परिदृश्य समेत: बैकअप लेना, अपडेट, बड़ी फ़ाइलों का अपलोड। फिर जो जमा हुआ उससे गुज़रें:

sudo aa-logprof

कमांड दर्ज उल्लंघनों से गुज़रती है और हर एक के बारे में पूछती है कि अनुमति दें या नहीं। यहाँ ध्यान चाहिए: वही अनुमति दें जो सचमुच सेवा के काम का हिस्सा है, जो सामने आए वह सब नहीं — वरना ऐसी प्रोफ़ाइल बनती है जो सब कुछ अनुमत करती है, और मतलब खो जाता है।

और उसके बाद ही:

sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

इनकार कहाँ दिखते हैं

सारे उल्लंघन कर्नेल के जर्नल में जाते हैं:

sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log

दूसरी फ़ाइल तब होती है जब auditd लगा हो — और उसके साथ प्रविष्टियाँ ध्यान देने योग्य रूप से अधिक विस्तृत होती हैं। इनकार की प्रविष्टि प्रोफ़ाइल का नाम, माँगी गई क्रिया और जिस रास्ते तक पहुँच चाही गई वह दिखाती है; यह बताने के लिए काफ़ी है कि प्रोफ़ाइल ठीक करनी है या ख़ुश होना है कि वह चली।

एक लक्षण याद रखने लायक है: सेवा अजीब बर्ताव करती है — कॉन्फ़िग नहीं पढ़ती, डायरेक्टरी में नहीं लिखती, सॉकेट नहीं खोलती — जबकि उसके अपने लॉग में «permission denied» त्रुटि है और अनुमतियाँ साफ़ तौर पर सही हैं। यह लगभग हमेशा AppArmor होता है, और पहला काम कर्नेल के जर्नल में देखना है।

व्यावहारिक उपाय, सैद्धांतिक नहीं

PHP-FPM या nginx की प्रोफ़ाइल एक ठोस तरीक़े से अपनी क़ीमत वसूलती है। प्रक्रिया सीमित हो, तो साइट तक पहुँची web shell न सिस्टम फ़ाइलें पढ़ सकती है, न शेल चला सकती है, न अनुमत डायरेक्टरियों के बाहर कुछ लिख सकती है। हैक हुई साइट हैक हुई साइट ही रहती है, पूरी मशीन तक की पहुँच में नहीं बदलती — और नुक़सान का बड़ा हिस्सा उसी बदलाव में है।

अपनाने का समझदार क्रम: पहले उसकी प्रोफ़ाइल जो इंटरनेट की ओर है (वेब सर्वर, PHP-FPM), फिर डेटाबेस की, फिर ज़रूरत के अनुसार। सब कुछ एक साथ चालू करने की ज़रूरत नहीं, और कोई सार्वभौमिक तैयार समूह होता भी नहीं: प्रोफ़ाइल इस पर निर्भर करती है कि आपकी फ़ाइलें कहाँ रहती हैं।

नियमित रूप से क्या जाँचें

प्रोफ़ाइल आपकी सोच से ज़्यादा बार unconfined पर लौट जाती हैं: पैकेज अपडेट प्रोफ़ाइल फ़ाइल बदल सकता है, हाथ से की गई डिबगिंग सेवा को complain में छोड़ जाती है, और नई सेवा बिना प्रोफ़ाइल के आती है। दो आँकड़े काम के हैं: कितनी प्रोफ़ाइल enforce में हैं, और नेटवर्क की ओर मुँह किए कितनी प्रक्रियाएँ unconfined हैं। दोनों में से किसी का बदलना जानने लायक है। एक पन्ने पर इकट्ठा यह कैसा लगता है, नीचे डेमो पर।