newrole -r role_r -t domain_t
استفاده کنید (معمولا تنها یک دامنه منفرد برای هر نقش وجود دارد، پس پارامتر -t
میتواند حذف گردد). این دستور با درخواست گذرواژه، شما را احرازهویت میکند. این ویژگی باعث میشود که برنامهها به صورت خودکار نتوانند بین نقشها تعویض شوند. چنین تغییراتی تنها زمانی اتفاق میافتند که به صورت صریح در خط مشی SELinux آمده باشند.
ssh
توسط ssh_exec_t
برچسبگذاری شده و زمانی که برنامه آغاز شود به صورت خودکار به دامنه ssh_t
تغییر مییابد). این مکانیزم خودکار انتقال دامنه امکان اختصاص دسترسیهای لازم برای هر بر نامه را فراهم میکند. این یک اصل پایه در SELinux به حساب میآید.
apt install selinux-basics selinux-policy-default
به صورت خودکار تمام بستههای مورد نیاز برای پیکربندی یک سیستم SELinux را نصب میکند.
unconfined
را غیرفعال کنید (مدیریت ماژولها در ادامه آورده میشود).
fixfiles relabel
صورت پذیرد.
selinux=1 security=selinux
را به کرنل لینوکس اضافه کنید. پارامتر enforcing=1
امکان ثبت گزارش در SELinux که تمام عملیات غیرمجاز را ثبت میکند. در نهایت، پارامتر audit=1
قوانین را برای برنامهها اجرایی میکند: بدون این پارامتر SELinux در حالت پیشفرض permissive خود فعالیت کرده به صورتی که عملیات غیرمجاز ثبت شده ولی هنوز اجرا میشوند. برای افزودن پارامترهای مورد نیاز باید فایل پیکربندی راهانداز GRUB را تغییر دهید. یک روش ساده برای اینکار تغییر متغیر GRUB_CMDLINE_LINUX
در /etc/default/grub
و اجرای update-grub
است. SELinux پس از راهاندازی مجدد سیستم فعالسازی میشود.
selinux-activate
این عملیات را خودکارسازی کرده و در راهاندازی بعدی عملیات برچسبگذاری را انجام میدهد (که این عمل از ایجاد فایلهای برچسبگذاری نشده در زمان غیرفعال بودن SELinux و زمانی که عملیات برچسبگذاری انجام میشود، پیشگیری میکند).
semodule
نیز همین است. علاوه بر این، باید بتوانید نقشهای مورد نیاز هر کاربر را تعریف کنید که اینکار با استفاده از دستور semanage
انجام میشود.
/etc/selinux/default/
ذخیرهسازی شده است، بکار روند. برخلاف تمام فایلهای پیکربندی که میتوانید در /etc/
پیدا کنید، این فایلها نباید به صورت دستی تغییر یابند. باید از برنامههای مخصوص برای تغییر آنها استفاده کنید.
/usr/share/selinux/default/
قرار دارند. برای فعالسازی یکی از این ماژولها در پیکربندی فعلی، باید از semodule -i module.pp.bz2
استفاده کنید. پسوند pp.bz2 مخفف عبارت policy package است (که توسط bzip2 فشردهسازی شده است).
semodule -r module
صورت میپذیرد. در نهایت، دستور semodule -l
فهرستی از تمام ماژولهای نصب شده را نشان میدهد. همچنین شماره نسخه را نیز نمایش میدهد. ماژولها میتوانند توسط semodule -e
فعال یا semodule -d
غیرفعال شوند.
#
semodule -i /usr/share/selinux/default/abrt.pp.bz2
#
semodule -l
abrt 1.5.0 Disabled accountsd 1.1.0 acct 1.6.0 [...]
#
semodule -e abrt
#
semodule -d accountsd
#
semodule -l
abrt 1.5.0 accountsd 1.1.0 Disabled acct 1.6.0 [...]
#
semodule -r abrt
#
semodule -l
accountsd 1.1.0 Disabled acct 1.6.0 [...]
semodule
بلافاصله پیکربندی جدید را بارگیری میکند مگر اینکه از گزینه -n
استفاده کنید. شایان ذکر است که برنامه به صورت پیشفرض با پیکربندی فعلی کار میکند (که توسط متغیر SELINUXTYPE
در /etc/selinux/config
مشخص شده است)، اما میتوانید آن را با استفاده از گزینه -s
تغییر دهید.
semanage
قابل پیکربندی هستند.
-a
برای افزودن، -d
برای حذف، -m
برای تغییر، -l
برای فهرست کردن و -t
برای مشخص کردن یک نوع (یا دامنه).
semanage login -l
نگاشت فعلی بین شناسههای کاربر و هویتهای SELinux را فهرست میکند. کاربرانی که هیچ مدخل واضحی ندارند از شناسه موجود در مدخل __default__
استفاده میکنند. دستور semanage login -a -s user_u user
شناسه user_u را به کاربر مورد نظر اختصاص میدهد. در نهایت، semanage login -d user
نگاشت موجود برای کاربر را از بین میبرد.
#
semanage login -a -s user_u rhertzog
#
semanage login -l
Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u SystemLow-SystemHigh * rhertzog user_u SystemLow * root unconfined_u SystemLow-SystemHigh * system_u system_u SystemLow-SystemHigh * #
semanage login -d rhertzog
semanage user -l
نگاشت فعلی بین شناسههای کاربری SELinux و نقشهای مجاز را فهرست میکند. افزودن یک شناسه جدید مستلزم تعریف نقشهای مرتبط با آن همراه با پیشوند برچسبگذاری برای اختصاص نوع به فایلهای شخصی کاربر میباشد (/home/user/*
). پیشوند باید از میان user
، staff
یا sysadm
انتخاب شود. پیشوند “staff
” روی فایلهایی از نوع “staff_home_dir_t
” تاثیر میگذارد. ایجاد یک شناسه کاربری جدید SELinux توسط semanage user -a -R roles -P prefix identity
انجام میشود. در نهایت، با استفاده از semanage user -d identity
میتوانید یک شناسه کاربری SELinux را حذف کنید.
#
semanage user -a -R 'staff_r user_r' -P staff test_u
#
semanage user -l
Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles root sysadm SystemLow SystemLow-SystemHigh staff_r sysadm_r system_r staff_u staff SystemLow SystemLow-SystemHigh staff_r sysadm_r sysadm_u sysadm SystemLow SystemLow-SystemHigh sysadm_r system_u user SystemLow SystemLow-SystemHigh system_r test_u staff SystemLow SystemLow staff_r user_r unconfined_u unconfined SystemLow SystemLow-SystemHigh system_r unconfined_r user_u user SystemLow SystemLow user_r #
semanage user -d test_u
/srv/www/
را بخواند، میتوانید دستور semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
را همراه با restorecon -R /srv/www/
اجرا کنید. دستور اول قوانین جدید برچسبگذاری را ثبت و دستور دوم انواع فایل را متناسب با قوانین جدید برچسبگذاری میکند.
semanage port -m -t http_port_t -p tcp 8080
را اجرا کنید.
getsebool
میتوان برای شناسایی این گزینهها استفاده کرد (getsebool boolean
یک گزینه و getsebool -a
تمام گزینهها را نمایش میدهد). دستور setsebool boolean value
مقدار فعلی یک گزینه منطقی را تغییر میدهد. گزینه -P
باعث میشود که این تغییرات به صورت ثابت باقیمانده و در راهاندازیهای بعدی سیستم دچار تغییر نشوند. مثال زیر به یک سرور وب اجازه میدهد که با دایرکتوریهای home دسترسی یابد (در صورتی مفید است که وبسایت کاربران در ~/public_html/
قرار داشته باشد).
#
getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off #
setsebool -P httpd_enable_homedirs on
#
getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
/usr/share/doc/selinux-policy-doc/html/
) و فایلهای نمونه است که میتوانند به عنوان قالب برای ایجاد ماژولهای جدید بکار روند. این فایلها را نصب کرده و به دقت مطالعه نمایید:
$
cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile
$
cp /usr/share/doc/selinux-policy-doc/example.fc ./
$
cp /usr/share/doc/selinux-policy-doc/example.if ./
$
cp /usr/share/doc/selinux-policy-doc/example.te ./
.te
مهمترین آنها است که قوانین را تعریف میکند. فایل .fc
“زمینههای فایل” را تعریف میکند، که همان نوع اختصاص یافته به فایلهای مرتبط با این ماژول است. از داده موجود درون فایل .fc
در گام برچسبگذاری استفاده میشود. در نهایت، فایل .if
رابط مرتبط با ماژول را تعریف میکند: یک مجموعه از “توابع عمومی” است که سایر ماژولها میتوانند به منظور تعامل بهتر با این ماژول از آنها استفاده کنند.
myapp_domtrans
”) کنترل میکند چه کسی میتواند برنامه را اجرا کند. رابط دوم (“myapp_read_log
”) اجازه خواندن و نوشتن روی فایلهای گزارش برنامه را میدهد.
.te
قرار میگیرند تعریف کند. بنابراین باید تمام انواع مورد استفاده خود را تعریف کنید (با استفاده از ماکرو gen_require
) و از عبارتهای استاندارد به منظور تخصیص دسترسی بهره ببرید. با این حال، به یاد داشته باشید که میتوانید از رابطهای سایر ماژولها نیز استفاده کنید. قسمت بعد توضیحات بیشتری در مورد چگونگی تخصیص این دسترسیها ارائه میدهد.
مثال 14.3. فایل example.if
## <summary>Myapp example policy</summary> ## <desc> ## <p> ## More descriptive text about myapp. The <desc> ## tag can also use <p>, <ul>, and <ol> ## html tags for formatting. ## </p> ## <p> ## This policy supports the following myapp features: ## <ul> ## <li>Feature A</li> ## <li>Feature B</li> ## <li>Feature C</li> ## </ul> ## </p> ## </desc> # ######################################## ## <summary> ## Execute a domain transition to run myapp. ## </summary> ## <param name="domain"> ## Domain allowed to transition. ## </param> # interface(`myapp_domtrans',` gen_require(` type myapp_t, myapp_exec_t; ') domtrans_pattern($1,myapp_exec_t,myapp_t) ') ######################################## ## <summary> ## Read myapp log files. ## </summary> ## <param name="domain"> ## Domain allowed to read the log files. ## </param> # interface(`myapp_read_log',` gen_require(` type myapp_log_t; ') logging_search_logs($1) allow $1 myapp_log_t:file r_file_perms; ')
example.te
بیندازید:
policy_module(myapp,1.0.0) ######################################## # # Declarations # type myapp_t; type myapp_exec_t; domain_type(myapp_t) domain_entry_file(myapp_t, myapp_exec_t) type myapp_log_t; logging_log_file(myapp_log_t) type myapp_tmp_t; files_tmp_file(myapp_tmp_t) ######################################## # # Myapp local policy # allow myapp_t myapp_log_t:file { read_file_perms append_file_perms }; allow myapp_t myapp_tmp_t:file manage_file_perms; files_tmp_filetrans(myapp_t,myapp_tmp_t,file)
ماژول باید توسط نام و شماره نسخهاش معرفی شود. این عبارت مورد نیاز است.
| |
اگر ماژول انواع جدیدی را معرفی کند، باید به شکل عبارت مشابه بالا باشد. از ایجاد انواع مورد نیاز خود دریغ نکنید بجای اینکه تعداد زیادی دسترسی بیمعنا صادر کنید.
| |
این رابطها نوع myapp_t را به عنوان یک دامنه فرآیند تعریف میکنند که باید برای هر برنامه اجرایی برچسبگذاری شده با myapp_exec_t بکار روند. به طور ضمنی، اینکار یک صفت exec_type روی آن اشیا اضافه میکند، که در عوض به سایر ماژولها اجازه میدهد برای اجرای برنامهها دسترسیهای لازم را صادر کنند: برای نمونه، ماژول userdomain به فرآیندهای موجود در دامنههای user_t ، staff_t و sysadm_t اجازه اجرا میدهد. دامنههای سایر برنامههای محدود شده اجازه دسترسی برای اجرا را ندارند، مگر اینکه قوانین همان دسترسیها را برایشان تعریف کنند (برای نمونه، در مورد dpkg همراه با دامنه dpkg_t آن).
| |
logging_log_file رابطی است که توسط خط مشی مرجع فراهم شده است. مشخص میکند فایلهایی که با این نوع برچسبگذاری شدهاند از نوع گزارش بوده و باید از مزیت قوانین اختصاصی آن بهرهمند شوند (برای مثال دسترسی دادن به logrotate تا بتواند گزارشها را تغییر دهد).
| |
allow عبارت پایهای است که برای احرازهویت یک عملیات استفاده میشود. پارامتر اول آن دامنه فرآیندی است که امکان اجرای عملیات را دارد. پارامتر دوم به تعریف یک شی میپردازد که فرآیند دامنه قبلی میتواند آن را تغییر دهد. این پارامتر به شکل “type:class“ است که در آن type نوع SELinux است و class طبیعت آن شی را تعریف میکند (فایل، دایرکتوری، سوکت و از این قبیل). در نهایت، پارامتر آخر به تعریف مجوزها میپردازد (همان عملیات مجاز).
مجوزها مجموعهای از عملیات مجاز هستند که از قالب روبهرو تبعیت میکنند: { operation1 operation2 } . اگرچه، میتوانید از ماکروها برای نمایش کاربردیترین مجوزها نیز استفاده کنید. فایل /usr/share/selinux/devel/include/support/obj_perm_sets.spt فهرستی از آنها را شامل میشود.
صفحه وب پیشرو فهرستی طولانی از کلاسهای اشیا و مجوزهای مربوط به هر کدام را نمایش میدهد.
|
avc: denied { read write } for pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=fifo_file permissive=1
جدول 14.1. بررسی و تحلیل گزارش SELinux
پیام | توضیحات |
---|---|
avc: denied | عملیات غیرمجاز است. |
{ read write } | این عملیات نیازمند مجوزهای read و write است. |
pid=1876 | فرآیندی با شناسه ۱۸۷۶ اقدام به اجرای عملیات کرده است. |
comm="syslogd" | فرآیند یک نمونه از برنامه syslogd بوده است. |
name="xconsole" | شی هدف xconsole نام دارد. بعضی وقتها میتوانید یک متغیر “path” داشته باشید - همراه با مسیر کامل-. |
dev=tmpfs | دستگاهی که از شی هدف میزبانی میکند یک tmpfs است (یک فایل سیستم داخل-حافظهای). برای یک دیسک حقیقی، میتوانید شماره پارتیشن آن را مشاهده کنید (برای مثال: “sda3”). |
ino=5510 | شی با inode ۵۵۱۰ شناسایی شده است. |
scontext=system_u:system_r:syslogd_t:s0 | این همان زمینه امنیتی فرآیندی است که عملیات را اجرا کرده است. |
tcontext=system_u:object_r:device_t:s0 | این همان زمینه امنیتی شی هدف میباشد. |
tclass=fifo_file | شی هدف یک فایل FIFO است. |
allow syslogd_t device_t:fifo_file { read write }
. این فرآیند میتواند خودکارسازی شده و دقیقا همان کاری است که دستور audit2allow
(از بسته policycoreutils) پیشنهاد میکند. این رویکرد تنها زمانی موثر است که اشیای گوناگون به شیوهای درست و متناسب با آنچه محدود شده است برچسبگذاری شده باشند. در هر صورت، باید به دقت قوانین تولید شده را متناسب با دانش خود از چگونگی کارکرد برنامه بررسی و تحلیل کنید. البته، این رویکرد تمایل دارد تا دسترسیهای بیشتری را نسبت به آنچه مورد نیاز است صادر کند. راهکار صحیح اغلب ایجاد انواع جدیدی است که دسترسیها میتوانند به آنها اختصاص یابند. همچنین پیش میآید که یک عملیات غیرمجاز برای برنامه مرگبار نباشد، که در این صورت بهتر است به صورت یک قانون “dontaudit
” برای پیشگیری از ثبت در فایل گزارش افزوده شود.
example.if
، example.fc
و example.te
با انتظارات شما از قوانین جدید سازگار شوند، تنها کافی است دستور make NAME=devel
را برای تولید یک ماژول در فایل example.pp
استفاده کنید (که بلافاصله میتوانید با دستور semodule -i example.pp
آن را فعالسازی کنید). اگر چندین ماژول تعریف شده باشند، make
تمام فایلهای .pp
متناسب با آنها را میسازد.