پیاده سازی SELinux

SELinux برای رد پیش فرض تنظیم شده است، به این معنی که هر دسترسی که برای آن یک قلاب در هسته دارد باید به صراحت توسط خط مشی مجاز باشد. این بدان معناست که یک فایل خط مشی از مقدار زیادی اطلاعات در مورد قوانین، انواع، کلاس ها، مجوزها و موارد دیگر تشکیل شده است. در نظر گرفتن کامل SELinux خارج از محدوده این سند است، اما درک نحوه نوشتن قوانین خط مشی اکنون هنگام معرفی دستگاه های اندرویدی جدید ضروری است. در حال حاضر اطلاعات زیادی در مورد SELinux موجود است. برای منابع پیشنهادی به اسناد پشتیبانی مراجعه کنید.

فایل های کلیدی

برای فعال کردن SELinux، آخرین هسته اندروید را ادغام کنید و سپس فایل‌های موجود در فهرست سیستم/سیستم را وارد کنید. هنگام کامپایل، این فایل ها شامل خط مشی امنیتی هسته SELinux می شوند و سیستم عامل بالادستی اندروید را پوشش می دهند.

به طور کلی، شما نباید فایل های system/sepolicy را مستقیماً تغییر دهید. در عوض، فایل‌های خط‌مشی خاص دستگاه خود را در فهرست /device/ manufacturer / device-name /sepolicy اضافه یا ویرایش کنید. در Android نسخه 8.0 و بالاتر، تغییراتی که در این فایل‌ها ایجاد می‌کنید باید فقط روی خط‌مشی فهرست راهنمای فروشنده شما تأثیر بگذارد. برای جزئیات بیشتر در مورد جداسازی سیاست عمومی در Android 8.0 و بالاتر، به سفارشی کردن SEPolicy در Android نسخه 8.0 و بالاتر مراجعه کنید. صرف نظر از نسخه اندروید، شما همچنان در حال تغییر این فایل‌ها هستید:

فایل های خط مشی

فایل‌هایی که با *.te ختم می‌شوند، فایل‌های منبع سیاست SELinux هستند که دامنه‌ها و برچسب‌های آنها را تعریف می‌کنند. ممکن است لازم باشد فایل های خط مشی جدیدی را در /device/ manufacturer / device-name /sepolicy ایجاد کنید، اما باید سعی کنید تا حد امکان فایل های موجود را به روز کنید.

فایل های زمینه

فایل های زمینه جایی هستند که شما برچسب هایی را برای اشیاء خود مشخص می کنید.

  • file_contexts برچسب هایی را به فایل ها اختصاص می دهد و توسط اجزای مختلف فضای کاربری استفاده می شود. همانطور که خط مشی های جدیدی ایجاد می کنید، این فایل را ایجاد یا به روز کنید تا برچسب های جدیدی به فایل ها اختصاص دهید. برای اعمال file_contexts جدید، تصویر سیستم فایل را دوباره بسازید یا restorecon روی فایلی که قرار است دوباره برچسب گذاری شود اجرا کنید. در ارتقاء، تغییرات file_contexts به‌عنوان بخشی از ارتقاء به‌طور خودکار بر روی سیستم و پارتیشن‌های داده‌های کاربر اعمال می‌شود. همچنین می‌توان با افزودن تماس‌های restorecon_recursive به init، تغییرات را به‌طور خودکار در هنگام ارتقا به پارتیشن‌های دیگر اعمال کرد. board .rc فایل پس از نصب پارتیشن خواندن و نوشتن.
  • genfs_contexts برچسب‌هایی را به سیستم‌های فایل، مانند proc یا vfat که از ویژگی‌های توسعه یافته پشتیبانی نمی‌کنند، اختصاص می‌دهد. این پیکربندی به‌عنوان بخشی از خط‌مشی هسته بارگیری می‌شود، اما ممکن است تغییرات برای inodeهای درون هسته‌ای اعمال نشود و برای اعمال کامل تغییر، نیاز به راه‌اندازی مجدد یا نصب مجدد و نصب مجدد فایل سیستم داشته باشد. همچنین ممکن است برچسب‌های خاصی به مانت‌های خاصی مانند 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 اعمال می شود. Keystore همیشه فضاهای نام مبتنی بر UID/AID را ارائه کرده است. Keystore 2.0 علاوه بر این فضاهای نام تعریف شده توسط sepolicy را اعمال می کند. شرح مفصلی از قالب و قراردادهای این فایل را می توانید در اینجا بیابید.

فایل میک BoardConfig.mk

پس از ویرایش یا افزودن فایل‌های خط‌مشی و زمینه، فایل makefil /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 در جای خود قرار می‌گیرند، تنظیمات خط‌مشی جدید به‌طور خودکار در فایل خط‌مشی هسته نهایی ساخته می‌شوند. برای کسب اطلاعات بیشتر در مورد نحوه ساخت سکولیسی بر روی دستگاه، به Building Sepolicy مراجعه کنید.

پیاده سازی

برای شروع کار با SELinux:

  1. SELinux را در هسته فعال کنید: CONFIG_SECURITY_SELINUX=y
  2. پارامتر kernel_cmdline یا bootconfig را تغییر دهید تا:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    یا
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    این فقط برای توسعه اولیه خط مشی برای دستگاه است. پس از اینکه یک خط مشی اولیه بوت استرپ داشتید، این پارامتر را حذف کنید تا دستگاه شما اجرا شود وگرنه CTS خراب می شود.
  3. سیستم را به صورت مجاز راه‌اندازی کنید و ببینید با چه انکارهایی در بوت مواجه می‌شوید:
    در اوبونتو 14.04 یا جدیدتر:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    در اوبونتو 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 اجرا کند و با آنهایی که برچسب‌گذاری شده‌اند app_data_files اما نه shell_data_files یا system_data_files chown .