تم إعداد SELinux على وضع الرفض التلقائي، ما يعني أنّه يجب السماح صراحةً بموجب السياسة بكل عملية وصول فردية يكون لها خطاف في النواة. ويعني ذلك أنّ ملف السياسة يتألف من قدر كبير من المعلومات المتعلقة بالقواعد والأنواع والفئات والأذونات وغير ذلك. لا يهدف هذا المستند إلى تقديم شرح شامل عن SELinux، ولكن من الضروري الآن فهم كيفية كتابة قواعد السياسة عند إعداد أجهزة Android جديدة. تتوفّر حاليًا معلومات كثيرة عن SELinux. يُرجى الاطّلاع على المستندات الداعمة للاطّلاع على المَراجع المقترَحة.
الملفات الرئيسية
لتفعيل SELinux، عليك دمج الـ أحدث نواة Android ثم دمج الملفات الموجودة في دليل الـ system/sepolicy. عند تجميع هذه الملفات، فإنّها تشكّل سياسة أمان نواة SELinux وتغطّي نظام التشغيل Android الأساسي.
بشكل عام، ننصحك بعدم تعديل ملفات system/sepolicy مباشرةً. بدلاً من ذلك، يمكنك إضافة ملفات السياسة الخاصة بجهازك أو تعديلها في
/device/manufacturer/device-name/sepolicy
الدليل. في الإصدار 8.0 من Android والإصدارات الأحدث، يجب ألا تؤثّر التغييرات التي تجريها على هذه الملفات إلا في السياسة في دليل مورِّدك. لمزيد من التفاصيل حول فصل سياسة الأمان العامة في الإصدار 8.0 من Android والإصدارات الأحدث، يُرجى الاطّلاع على مقالة تخصيص سياسة الأمان في الإصدار 8.0 من Android والإصدارات الأحدث. بغض النظر عن إصدار Android، ستظل تعدّل هذه الملفات:
ملفات السياسة
الملفات التي تنتهي بـ *.te هي ملفات مصدر سياسة SELinux، التي تحدّد النطاقات وتصنيفاتها. قد تحتاج إلى إنشاء ملفات سياسة جديدة في
/device/manufacturer/device-name/sepolicy,
ولكن ننصحك بمحاولة تعديل الملفات الحالية متى أمكن ذلك.
ملفات السياق
ملفات السياق هي المكان الذي تحدّد فيه تصنيفات عناصرك.
file_contextsيُعيّن تصنيفات للملفات وتستخدمه مكوّنات مختلفة لمساحة المستخدم. أثناء إنشاء سياسات جديدة، عليك إنشاء هذا الملف أو تعديله لتعيين تصنيفات جديدة للملفات. لتطبيقfile_contextsالجديدة، عليك إعادة إنشاء صورة نظام الملفات أو تشغيلrestoreconعلى الملف الذي تريد إعادة تصنيفه. عند إجراء الترقيات، يتم تلقائيًا تطبيق التغييرات علىfile_contextsعلى قسمَي النظام وبيانات المستخدم كجزء من الترقية. يمكن أيضًا تطبيق التغييرات تلقائيًا على أقسام أخرى عند الترقية من خلال إضافة طلباتrestorecon_recursiveإلى ملف init.board.rc بعد تثبيت القسم في وضع القراءة والكتابة.genfs_contextsيُعيّن تصنيفات لأنظمة الملفات، مثلprocأوvfatالتي لا تتيح استخدام السمات الموسّعة. يتم تحميل هذا الإعداد كجزء من سياسة النواة، ولكن قد لا تسري التغييرات على العُقد الداخلية، ما يتطلب إعادة التشغيل أو إلغاء تثبيت نظام الملفات وإعادة تثبيته لتطبيق التغيير بالكامل. يمكن أيضًا تعيين تصنيفات معيّنة لعمليات تثبيت معيّنة، مثلvfatباستخدام الخيارcontext=mountproperty_contextsيُعيّن تصنيفات لسمات نظام Android للتحكّم في العمليات التي يمكنها ضبطها. تتم قراءة هذا الإعداد من خلال عمليةinitأثناء بدء التشغيل.service_contextsيُعيّن تصنيفات لخدمات Android binder للتحكّم في العمليات التي يمكنها إضافة (تسجيل) مرجع binder للخدمة والعثور عليه (البحث عنه). تتم قراءة هذا الإعداد من خلال الـservicemanagerعملية أثناء بدء التشغيل.- يُعيّن
seapp_contextsتصنيفات لعمليات التطبيقات و/data/dataأدلة. تتم قراءة هذا الإعداد من خلال عمليةzygoteعند كل عملية تشغيل للتطبيق ومن خلالinstalldأثناء بدء التشغيل. mac_permissions.xmlيُعيّن علامةseinfoللتطبيقات استنادًا إلى توقيعها واسم حزمتها بشكل اختياري. يمكن بعد ذلك استخدام علامةseinfoكمفتاح في ملفseapp_contextsلتعيين تصنيف معيّن لجميع التطبيقات التي تحمل علامةseinfoهذه. تتم قراءة هذا الإعداد من خلالsystem_serverأثناء بدء التشغيل.- يُعيّن
keystore2_key_contextsتصنيفات لمساحات أسماء Keystore 2. يتم فرض مساحات الأسماء هذه من خلال البرنامج الخفيkeystore2. لطالما وفّر Keystore مساحات أسماء تستند إلى رقم تعريف المستخدم (UID)/رقم تعريف التطبيق (AID). يفرض Keystore 2 بالإضافة إلى ذلك مساحات الأسماء المحدّدة في سياسة الأمان. يمكنك الاطّلاع هنا على وصف تفصيلي لتنسيق هذا الملف واصطلاحاته.
ملف BoardConfig.mk
بعد تعديل ملفات السياسة والسياق أو إضافتها، عليك تعديل ملف
/device/manufacturer/device-name/BoardConfig.mk
للإشارة إلى الدليل الفرعي sepolicy وكل ملف سياسة جديد.
لمزيد من المعلومات عن متغيّرات BOARD_SEPOLICY، يُرجى الاطّلاع على
system/sepolicy/README ملف.
BOARD_SEPOLICY_DIRS += \
<root>/device/manufacturer/device-name/sepolicy
BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te
بعد إعادة الإنشاء، يتم تفعيل SELinux على جهازك. يمكنك الآن إما تخصيص سياسات SELinux لتضمين الإضافات الخاصة بك إلى نظام التشغيل Android كما هو موضّح في التخصيص أو التحقّق من الإعداد الحالي كما هو موضّح في التحقّق من الصحة.
عند توفّر ملفات السياسة الجديدة وتعديلات BoardConfig.mk، يتم تلقائيًا إنشاء إعدادات السياسة الجديدة في ملف سياسة النواة النهائي. لمزيد من المعلومات عن كيفية إنشاء سياسة الأمان على الجهاز، يُرجى الاطّلاع على مقالة إنشاء سياسة الأمان.
التنفيذ
للبدء في استخدام SELinux، يُرجى اتّباع الخطوات التالية:
- تفعيل SELinux في النواة:
CONFIG_SECURITY_SELINUX=y - تغيير مَعلمة kernel_cmdline أو bootconfig على النحو التالي:
أوBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
لا ينطبق ذلك إلا على التطوير الأولي للسياسة الخاصة بالجهاز. بعد توفّر سياسة أولية للتشغيل، عليك إزالة هذه المَعلمة لفرض السياسة على جهازك أو تعذُّر اجتيازه اختبارات مجموعة اختبارات التوافق (CTS).BOARD_BOOTCONFIG := androidboot.selinux=permissive
- تشغيل النظام في الوضع المتساهل والاطّلاع على عمليات الرفض التي يتم رصدها عند بدء التشغيل:
على Ubuntu 14.04 أو إصدار أحدث: على Ubuntu 12.04:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- تقييم الناتج بحثًا عن تحذيرات مشابهة لـ
init: Warning! Service name needs a SELinux domain defined; please fix!يُرجى الاطّلاع على التحقّق من الصحة للحصول على التعليمات والأدوات. - تحديد الأجهزة والملفات الجديدة الأخرى التي تحتاج إلى تصنيف.
- استخدام التصنيفات الحالية أو الجديدة لعناصرك. يمكنك الاطّلاع على ملفات
*_contextsلمعرفة كيفية تصنيف العناصر سابقًا واستخدام معرفتك بمعاني التصنيفات لتعيين تصنيف جديد. من المفترض أن يكون هذا التصنيف حاليًا ومناسبًا للسياسة، ولكن في بعض الأحيان يكون من الضروري استخدام تصنيف جديد، كما يجب وضع قواعد للوصول إلى هذا التصنيف. عليك إضافة تصنيفاتك إلى ملفات السياق المناسبة. - تحديد النطاقات أو العمليات التي يجب أن يكون لها نطاقات أمان خاصة بها.
من المحتمل أن تحتاج إلى كتابة سياسة جديدة تمامًا لكل منها. على سبيل المثال، يجب أن يكون لكل
الخدمات التي يتم إنشاؤها من
initنطاق أمان خاص بها. تساعد الأوامر التالية في الكشف عن الخدمات التي تظل قيد التشغيل (ولكن يجب أن تخضع جميع الخدمات لهذا الإجراء):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- مراجعة
init.device.rcلتحديد أي نطاقات ليس لها نوع نطاق. عليك منحها نطاقًا في مرحلة مبكرة من عملية التطوير لتجنُّب إضافة قواعد إلىinitأو إرباك عمليات وصولinitالأخرى التي تكون في سياستها الخاصة. - إعداد
BOARD_CONFIG.mkلاستخدامBOARD_SEPOLICY_*متغيّرات. يُرجى الاطّلاع على ملف README فيsystem/sepolicyللحصول على تفاصيل حول إعداد ذلك. - فحص ملف init.device.rc وملف fstab.device والتأكّد من أنّ كل استخدام لـ
mountيتوافق مع نظام ملفات مصنّف بشكل صحيح أو أنّه تم تحديد الخيارcontext= mount. - مراجعة كل عملية رفض وإنشاء سياسة SELinux للتعامل مع كل منها بشكل صحيح. يُرجى الاطّلاع على الأمثلة في التخصيص.
ننصحك بالبدء بالسياسات في AOSP ثم البناء عليها لإجراء التخصيصات الخاصة بك. لمزيد من المعلومات عن استراتيجية السياسة وإلقاء نظرة فاحصة على بعض هذه الخطوات، يُرجى الاطّلاع على مقالة كتابة سياسة SELinux.
حالات الاستخدام
في ما يلي أمثلة محدّدة على الثغرات الأمنية التي يجب مراعاتها عند إنشاء البرامج وسياسات SELinux المرتبطة بها:
الروابط الرمزية: تظهر الروابط الرمزية كملفات، لذا غالبًا ما تتم قراءتها كملفات، ما قد يؤدي إلى حدوث ثغرات أمنية. على سبيل المثال، تغيّر بعض المكوّنات المميّزة، مثل init، أذونات ملفات معيّنة، وأحيانًا تكون هذه الأذونات مفتوحة بشكل مفرط.
قد يستبدل المهاجمون بعد ذلك هذه الملفات بروابط رمزية تؤدي إلى رمز يتحكّمون فيه، ما يسمح لهم بالكتابة فوق ملفات عشوائية. ولكن إذا كنت تعرف أنّ تطبيقك لا يتنقّل مطلقًا عبر رابط رمزي، يمكنك منعه من إجراء ذلك باستخدام SELinux.
ملفات النظام: ننصحك بمراعاة فئة ملفات النظام التي يجب ألا يتم تعديلها إلا من خلال خادم النظام. ومع ذلك، بما أنّ netd وinit وvold تعمل كجذر، يمكنها الوصول إلى ملفات النظام هذه. لذا، إذا تم اختراق netd، يمكنه اختراق هذه الملفات وربما خادم النظام نفسه.
باستخدام SELinux، يمكنك تحديد هذه الملفات كملفات بيانات خادم النظام.
لذلك، فإنّ النطاق الوحيد الذي لديه إذن القراءة والكتابة إليها هو خادم النظام.
حتى إذا تم اختراق netd، لن يتمكّن من تبديل النطاقات إلى نطاق خادم النظام والوصول إلى ملفات النظام هذه على الرغم من أنّه يعمل كجذر.
بيانات التطبيق: مثال آخر هو فئة الدوال التي يجب تشغيلها كجذر ولكن يجب ألا تتمكّن من الوصول إلى بيانات التطبيق. ويكون ذلك مفيدًا للغاية لأنّه يمكن إجراء تأكيدات واسعة النطاق، مثل منع نطاقات معيّنة غير مرتبطة ببيانات التطبيق من الوصول إلى الإنترنت.
setattr: بالنسبة إلى أوامر مثل chmod وchown، يمكنك تحديد مجموعة الملفات التي يمكن للنطاق المرتبط بها إجراء setattr عليها. يمكن منع أي شيء خارج ذلك من إجراء هذه التغييرات، حتى من خلال الجذر. لذا، قد يشغّل أحد التطبيقات chmod وchown على الملفات التي تم تصنيفها على أنّها app_data_files ولكن ليس shell_data_files أو system_data_files.