SELinux را پیاده سازی کنید، SELinux را پیاده سازی کنید

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:

  1. فعال کردن SELinux در هسته: CONFIG_SECURITY_SELINUX=y
  2. پارامتر kernel_cmdline یا bootconfig را به صورت زیر تغییر دهید:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    یا
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    این فقط برای توسعه اولیه سیاست برای دستگاه است. پس از اینکه یک سیاست بوت‌استرپ اولیه داشتید، این پارامتر را حذف کنید تا دستگاه شما در حال اجرا باشد یا CTS را از دست بدهد.
  3. سیستم را در حالت مجاز بوت کنید و ببینید با چه عدم پذیرش‌هایی هنگام بوت مواجه می‌شوید:
    در اوبونتو ۱۴.۰۴ یا جدیدتر:
    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
    
  4. خروجی را برای هشدارهایی که شبیه init: Warning! Service name needs a SELinux domain defined; please fix! برای دستورالعمل‌ها و ابزارها به اعتبارسنجی مراجعه کنید.
  5. دستگاه‌ها و سایر فایل‌های جدیدی که نیاز به برچسب‌گذاری دارند را شناسایی کنید.
  6. از برچسب‌های موجود یا جدید برای اشیاء خود استفاده کنید. به فایل‌های *_contexts نگاه کنید تا ببینید قبلاً اشیاء چگونه برچسب‌گذاری شده‌اند و با استفاده از دانش معانی برچسب، برچسب جدیدی را اختصاص دهید. در حالت ایده‌آل، این یک برچسب موجود است که با سیاست‌ها مطابقت دارد، اما گاهی اوقات به یک برچسب جدید نیاز است و قوانینی برای دسترسی به آن برچسب مورد نیاز است. برچسب‌های خود را به فایل‌های context مناسب اضافه کنید.
  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. فایل‌های device و device را بررسی کنید و مطمئن شوید که هر بار استفاده از mount با یک سیستم فایل با برچسب مناسب مطابقت دارد یا اینکه گزینه context= mount مشخص شده است.
  11. هر مورد انکار را بررسی کنید و برای مدیریت صحیح هر مورد، سیاست 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 .