تنفيذ SELinux

تم إعداد SELinux للرفض التلقائي، ما يعني أنّه يجب أن تسمح السياسة صراحةً بكل عملية وصول تتضمن ربطًا في النواة. ويعني ذلك أنّ ملف السياسة يتألف من كمية كبيرة من المعلومات المتعلّقة بالقواعد والأنواع والفئات والأذونات وغير ذلك. لا يتناول هذا المستند بشكل كامل نظام SELinux، ولكنه يوضّح كيفية كتابة قواعد السياسة، وهو أمر ضروري الآن عند إعداد أجهزة Android الجديدة. تتوفّر حاليًا الكثير من المعلومات حول SELinux. اطّلِع على المستندات الداعمة للاطّلاع على المَراجع المقترَحة.

الملفات الرئيسية

لتفعيل SELinux، عليك دمج أحدث ملف لنظام التشغيل Android ثم دمج الملفات المتوفّرة في الدليل system/sepolicy. عند تجميع هذه الملفات، تتضمّن سياسة أمان ملف kernel في نظام التشغيل SELinux وتغطي نظام التشغيل Android الأساسي.

بوجه عام، يجب عدم تعديل ملفات system/sepolicy بشكل مباشر. بدلاً من ذلك، أضِف ملفات السياسات الخاصة بالأجهزة أو عدِّلها في الدليل /device/manufacturer/device-name/sepolicy. في الإصدار Android 8.0 والإصدارات الأحدث، من المفترض أن تؤثر التغييرات التي تجريها على هذه الملفات فقط في السياسة في دليل المورّد. لمزيد من التفاصيل حول فصل سياسة الأمان العامة في Android 8.0 والإصدارات الأحدث، يُرجى الاطّلاع على مقالة تخصيص سياسة الأمان في Android 8.0 والإصدارات الأحدث. بغض النظر عن إصدار Android، سيظل بإمكانك تعديل الملفات التالية:

ملفات السياسات

الملفات التي تنتهي بـ *.te هي ملفات مصدر سياسة SELinux التي تحدد النطاقات وتسمياتها. قد تحتاج إلى إنشاء ملفات سياسات جديدة في /device/manufacturer/device-name/sepolicy، ولكن عليك محاولة تعديل الملفات الحالية كلما أمكن ذلك.

ملفات السياق

يمكنك تحديد تصنيفات للكائنات في ملفات السياق.

  • يُحدِّد file_contexts تصنيفات للملفات ويستخدمها مختلف مكونات مساحة المستخدم. أثناء إنشاء سياسات جديدة، أنشئ هذا الملف أو عدِّله لتحديد تصنيفات جديدة للملفات. لتطبيق file_contexts جديد، أعِد إنشاء صورة نظام الملفات أو نفِّذ restorecon على الملف الذي تريد إعادة تصنيفه. عند الترقية، يتم تطبيق التغييرات على file_contexts تلقائيًا على قسمَي النظام وuserdata كجزء من عملية الترقية. يمكن أيضًا تطبيق التغييرات تلقائيًا عند الترقية إلى غيرها من الأقسام من خلال إضافة طلبات restorecon_recursive إلىملف init.board.rc بعد تركيب القسم بالقراءة والكتابة.
  • تُحدِّد genfs_contexts تصنيفات لأنظمة الملفات، مثل proc أو vfat التي لا تتوافق مع سمات ممتدة. يتم تحميل هذا الإعداد كجزء من سياسة kernel، ولكن قد لا يتم تطبيق التغييرات على ملفات البيانات في kernel، ما يتطلّب إعادة تشغيل الجهاز أو إزالة تثبيت نظام الملفات وإعادة تثبيته لتطبيق التغيير بالكامل. يمكن أيضًا تخصيص تصنيفات معيّنة لمواضع تثبيت معيّنة، مثل vfat باستخدام الخيار context=mount.
  • يحدِّد property_contexts تصنيفات لسمات نظام Android للتحكّم في العمليات التي يمكنها ضبطها. تقرأ عملية init هذا الإعداد أثناء بدء التشغيل.
  • service_contexts يحدِّد تصنيفات لخدمات رابط Android للتحكّم في العمليات التي يمكنها إضافة (تسجيل) مرجع رابط وابحث عنه (بحث) للخدمة. تقرأ عملية servicemanager هذا الإعداد أثناء بدء التشغيل.
  • seapp_contexts يحدّد تصنيفات لعمليات التطبيقات وملفّات /data/data. تقرأ عملية zygote هذه الإعدادات عند كل عملية تشغيل للتطبيق، كما تقرأها عمليةinstalld أثناء بدء التشغيل.
  • mac_permissions.xml تُسنِد علامة seinfo إلى التطبيقات استنادًا إلى توقيعها واسم حِزمها اختياريًا. يمكن بعد ذلك استخدام علامة seinfo كمفتاح في ملف seapp_contexts لتحديد تصنيف محدّد لجميع التطبيقات التي تحتوي على هذه العلامة seinfo. تقرأ system_server هذه الإعدادات أثناء بدء التشغيل.
  • keystore2_key_contexts تُحدِّد تصنيفات لمساحات أسماء Keystore 2.0. يتم فرض مساحات الأسماء هذه من خلال الخادم الخفي keystore2. يوفّر "متجر المفاتيح" دائمًا مساحات أسماء مستندة إلى UID/AID. تفرض أداة Keystore 2.0 أيضًا مساحات الاسم المحدّدة في سياسة الأمان. يمكنك الاطّلاع على وصف تفصيلي لتنسيق هذا الملف ومخطّطاته هنا.

ملف الإنشاء BoardConfig.mk

بعد تعديل ملفات السياسة والسياق أو إضافتها، عدِّلملف /device/manufacturer/device-name/BoardConfig.mk makefile للإشارة إلى الدليل الفرعي 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، يتم تلقائيًا دمج إعدادات السياسة الجديدة في ملف سياسة kernel النهائي. لمزيد من المعلومات حول كيفية إنشاء سياسة الأمان على الجهاز، يُرجى الاطّلاع على مقالة إنشاء سياسة الأمان.

التنفيذ

لبدء استخدام SELinux:

  1. فعِّل SELinux في النواة: CONFIG_SECURITY_SELINUX=y
  2. غيِّر المَعلمة kernel_cmdline أو bootconfig لكي:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    أو
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    هذا الإجراء مخصّص فقط للتطوير الأولي للسياسة على الجهاز. بعد أن يكون لديك سياسة تمهيد أولية، أزِل هذه المَعلمة لكي يفرض جهازك السياسة أو يفشل في اجتياز CTS.
  3. شغِّل النظام في وضع السماح واطّلِع على حالات الرفض التي تحدث عند التشغيل:
    على نظام التشغيل Ubuntu 14.04 أو الإصدارات الأحدث:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    على نظام التشغيل Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. قيِّم الإخراج بحثًا عن تحذيرات تشبه init: Warning! Service name needs a SELinux domain defined; please fix!. راجِع التحقّق للحصول على التعليمات والأدوات.
  5. تحديد الأجهزة والملفات الجديدة الأخرى التي تحتاج إلى تصنيف
  6. استخدِم تصنيفات حالية أو جديدة للكائنات. اطّلِع علىملفّات *_contexts لمعرفة التصنيفات السابقة واستخدِم معلوماتك عن معاني التصنيفات لتحديد تصنيف جديد. من الأفضل أن يكون هذا تصنيفًا حاليًا يتوافق مع السياسة، ولكن في بعض الأحيان يكون هناك حاجة إلى تصنيف جديد وقواعد للوصول إلى ذلك التصنيف. أضِف تصنيفاتك إلى ملفات السياق المناسبة.
  7. حدِّد النطاقات/العمليات التي يجب أن تتضمّن نطاقات أمان خاصة بها. من المحتمل أن تحتاج إلى كتابة سياسة جديدة تمامًا لكل منها. على سبيل المثال، يجب أن يكون لكل الخدمات التي تم إنشاؤها من init خاص بها. تساعد الأوامر التالية في الكشف عن الخدمات التي لا تزال قيد التشغيل (ولكن تحتاج جميع الخدمات إلى معالجة مماثلة):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. راجِع init.device.rc لتحديد أي نطاقات لا تتضمّن نوع نطاق. امنحهم نطاقًا مبكرًا في عملية التطوير لتجنُّب إضافة قواعد إلى init أو الخلط بين أذونات الوصول إلى init وأذونات الوصول المُدرَجة في سياستهم الخاصة.
  9. إعداد BOARD_CONFIG.mk لاستخدام متغيّرات BOARD_SEPOLICY_* اطّلِع على ملف README في system/sepolicy لمعرفة تفاصيل حول إعداد هذا الإجراء.
  10. راجِع الملفَّين init.device.rc وfstab.device وتأكَّد من أنّ كل استخدام لـ mount يتوافق مع نظام ملف تمت تسميته بشكل صحيح أو أنّ خيار context= mount محدّد.
  11. راجِع كلّ رفض وأنشئ سياسة 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.