SELinux به صورت پیشفرض غیرفعال تنظیم شده است، به این معنی که هر دسترسی که برای آن در هسته یک قلاب وجود دارد، باید صریحاً توسط سیاست مجاز باشد. این بدان معناست که یک فایل سیاست شامل حجم زیادی از اطلاعات در مورد قوانین، انواع، کلاسها، مجوزها و موارد دیگر است. بررسی کامل SELinux خارج از محدوده این سند است، اما درک نحوه نوشتن قوانین سیاست اکنون هنگام راهاندازی دستگاههای جدید اندروید ضروری است. در حال حاضر اطلاعات زیادی در مورد SELinux موجود است. برای منابع پیشنهادی به اسناد پشتیبانی مراجعه کنید.
فایلهای کلیدی
برای فعال کردن SELinux، آخرین نسخه کرنل اندروید را ادغام کنید و سپس فایلهای موجود در دایرکتوری system/sepolicy را در آن بگنجانید. پس از کامپایل، این فایلها سیاست امنیتی کرنل SELinux را تشکیل میدهند و سیستم عامل اندروید بالادستی را پوشش میدهند.
به طور کلی، شما نباید فایلهای system/sepolicy را مستقیماً تغییر دهید. در عوض، فایلهای policy مخصوص دستگاه خود را در دایرکتوری /device/ manufacturer / device-name /sepolicy اضافه یا ویرایش کنید. در اندروید ۸.۰ و بالاتر، تغییراتی که در این فایلها ایجاد میکنید فقط باید روی policy موجود در دایرکتوری vendor شما تأثیر بگذارد. برای جزئیات بیشتر در مورد جداسازی seppolicy عمومی در اندروید ۸.۰ و بالاتر، به بخش «سفارشیسازی SEPolicy در اندروید ۸.۰+» مراجعه کنید. صرف نظر از نسخه اندروید، شما همچنان در حال تغییر این فایلها هستید:
فایلهای سیاست
فایلهایی که به *.te ختم میشوند، فایلهای منبع سیاست SELinux هستند که دامنهها و برچسبهای آنها را تعریف میکنند. ممکن است لازم باشد فایلهای سیاست جدیدی را در /device/ manufacturer / device-name /sepolicy ایجاد کنید، اما باید سعی کنید فایلهای موجود را در صورت امکان بهروزرسانی کنید.
فایلهای زمینه
فایلهای زمینه جایی هستند که شما برچسبهایی را برای اشیاء خود مشخص میکنید.
-
file_contextsبرچسبهایی را به فایلها اختصاص میدهد و توسط اجزای مختلف فضای کاربری استفاده میشود. همزمان با ایجاد سیاستهای جدید، این فایل را ایجاد یا بهروزرسانی کنید تا برچسبهای جدیدی به فایلها اختصاص داده شود. برای اعمالfile_contextsجدید، تصویر سیستم فایل را بازسازی کنید یاrestoreconروی فایلی که قرار است برچسبگذاری مجدد شود، اجرا کنید. در هنگام ارتقا، تغییرات درfile_contextsبه عنوان بخشی از ارتقا به طور خودکار روی پارتیشنهای system و userdata اعمال میشوند. همچنین میتوان با اضافه کردن فراخوانیهایrestorecon_recursiveبه فایل .rc board init خود پس از مانت شدن پارتیشن به صورت خواندنی-نوشتنی، تغییرات را به طور خودکار در هنگام ارتقا به پارتیشنهای دیگر اعمال کرد. -
genfs_contextsبرچسبهایی را به سیستمفایلها، مانندprocیاvfatکه از ویژگیهای توسعهیافته پشتیبانی نمیکنند، اختصاص میدهد. این پیکربندی به عنوان بخشی از سیاست هسته بارگذاری میشود، اما تغییرات ممکن است برای inodeهای درون هسته اعمال نشوند و نیاز به راهاندازی مجدد یا unmount کردن و دوباره mount کردن سیستمفایل برای اعمال کامل تغییر داشته باشند. برچسبهای خاص همچنین میتوانند به mountهای خاص، مانندvfatبا استفاده از گزینهcontext=mount، اختصاص داده شوند. -
property_contextsبرچسبهایی را به ویژگیهای سیستم اندروید اختصاص میدهد تا کنترل کند چه فرآیندهایی میتوانند آنها را تنظیم کنند. این پیکربندی توسط فرآیندinitدر هنگام راهاندازی خوانده میشود. -
service_contextsبرچسبهایی را به سرویسهای 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 علاوه بر این، فضاهای نام تعریف شده توسط sepolicy را نیز اعمال میکند. شرح مفصلی از قالب و قراردادهای این فایل را میتوانید اینجا بیابید.
فایل ساخت BoardConfig.mk
پس از ویرایش یا اضافه کردن فایلهای سیاست و زمینه، فایل makefile /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 خود را برای تطبیق با موارد دلخواه خود در سیستم عامل اندروید، همانطور که در بخش «سفارشیسازی» توضیح داده شده است، سفارشی کنید یا تنظیمات موجود خود را همانطور که در بخش «اعتبارسنجی» توضیح داده شده است، تأیید کنید.
وقتی فایلهای سیاست جدید و بهروزرسانیهای BoardConfig.mk نصب شوند، تنظیمات سیاست جدید بهطور خودکار در فایل سیاست نهایی هسته ساخته میشوند. برای اطلاعات بیشتر در مورد نحوه ساخت sepolicy روی دستگاه، به بخش «ساخت sepolicy» مراجعه کنید.
پیادهسازی
برای شروع کار با SELinux:
- فعال کردن SELinux در هسته:
CONFIG_SECURITY_SELINUX=y - پارامتر kernel_cmdline یا bootconfig را به صورت زیر تغییر دهید:
یاBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
این فقط برای توسعه اولیه سیاست برای دستگاه است. پس از اینکه یک سیاست بوتاسترپ اولیه داشتید، این پارامتر را حذف کنید تا دستگاه شما در حال اجرا باشد یا CTS را از دست بدهد.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- سیستم را در حالت مجاز بوت کنید و ببینید با چه عدم پذیرشهایی هنگام بوت مواجه میشوید:
در اوبونتو ۱۴.۰۴ یا جدیدتر: روی اوبونتو ۱۲.۰۴: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نگاه کنید تا ببینید قبلاً اشیاء چگونه برچسبگذاری شدهاند و با استفاده از دانش معانی برچسب، برچسب جدیدی را اختصاص دهید. در حالت ایدهآل، این یک برچسب موجود است که با سیاستها مطابقت دارد، اما گاهی اوقات به یک برچسب جدید نیاز است و قوانینی برای دسترسی به آن برچسب مورد نیاز است. برچسبهای خود را به فایلهای context مناسب اضافه کنید. - دامنهها/پردازشهایی را که باید دامنههای امنیتی خاص خود را داشته باشند، شناسایی کنید. احتمالاً باید برای هر کدام یک سیاست کاملاً جدید بنویسید. به عنوان مثال، تمام سرویسهایی که از
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مراجعه کنید. - فایلهای device و device را بررسی کنید و مطمئن شوید که هر بار استفاده از
mountبا یک سیستم فایل با برچسب مناسب مطابقت دارد یا اینکه گزینهcontext= mountمشخص شده است. - هر مورد انکار را بررسی کنید و برای مدیریت صحیح هر مورد، سیاست SELinux را ایجاد کنید. به مثالها در بخش سفارشیسازی مراجعه کنید.
شما باید با سیاستهای موجود در AOSP شروع کنید و سپس بر اساس آنها، سفارشیسازیهای خود را انجام دهید. برای اطلاعات بیشتر در مورد استراتژی سیاست و نگاهی دقیقتر به برخی از این مراحل، به بخش «نوشتن سیاست SELinux» مراجعه کنید.
موارد استفاده
در اینجا نمونههای خاصی از سوءاستفادههایی که باید هنگام ساخت نرمافزار خودتان و سیاستهای SELinux مرتبط در نظر بگیرید، آورده شده است:
پیوندهای نمادین: از آنجا که پیوندهای نمادین به صورت فایل ظاهر میشوند، اغلب به عنوان فایل خوانده میشوند که میتواند منجر به سوءاستفاده شود. به عنوان مثال، برخی از اجزای دارای امتیاز، مانند init ، مجوزهای فایلهای خاصی را تغییر میدهند، گاهی اوقات به طوری که بیش از حد باز باشند.
سپس مهاجمان ممکن است آن فایلها را با پیوندهای نمادین جایگزین کنند تا کدی را که کنترل میکنند، تغییر دهند و به مهاجم اجازه دهند فایلهای دلخواه را بازنویسی کند. اما اگر میدانید که برنامه شما هرگز از یک پیوند نمادین عبور نمیکند، میتوانید با SELinux مانع از انجام این کار شوید.
فایلهای سیستمی: دستهای از فایلهای سیستمی را در نظر بگیرید که فقط باید توسط سرور سیستم تغییر داده شوند. با این حال، از آنجایی که netd ، init و vold به عنوان root اجرا میشوند، میتوانند به آن فایلهای سیستمی دسترسی داشته باشند. بنابراین اگر netd به خطر بیفتد، میتواند آن فایلها و به طور بالقوه خود سرور سیستم را به خطر بیندازد.
با SELinux، میتوانید آن فایلها را به عنوان فایلهای داده سرور سیستم شناسایی کنید. بنابراین، تنها دامنهای که به آنها دسترسی خواندن/نوشتن دارد، سرور سیستم است. حتی اگر netd به خطر بیفتد، نمیتواند دامنهها را به دامنه سرور سیستم تغییر دهد و به آن فایلهای سیستمی دسترسی پیدا کند، اگرچه به عنوان root اجرا میشود.
دادههای برنامه: مثال دیگر، دستهای از توابع است که باید به عنوان ریشه اجرا شوند اما نباید به دادههای برنامه دسترسی داشته باشند. این فوقالعاده مفید است زیرا میتوان ادعاهای گستردهای را مطرح کرد، مانند اینکه دامنههای خاصی که به دادههای برنامه مرتبط نیستند، از دسترسی به اینترنت منع شوند.
setattr: برای دستوراتی مانند chmod و chown ، میتوانید مجموعه فایلهایی را که دامنه مرتبط میتواند setattr در آنها اجرا کند، شناسایی کنید. هر چیزی خارج از آن میتواند از این تغییرات منع شود، حتی توسط root. بنابراین یک برنامه ممکن است chmod و chown در برابر app_data_files با برچسب اجرا کند، اما نه shell_data_files یا system_data_files .