نقش کامپیوتر در توسعه ی دنیای کنونی را نمی شود انکار کرد، کامپیوتر در اموری مانند آموزش، تجاری و اداری، پزشکی، صنایع و غیره نقش پر رنگی را ایفا کرده است، در کنار تمام مزایایی که برای ما خلق کرده، میتواند بستری برای آسیب زدن به تمام دستاورد های ما را نیز فراهم کند و اینجا نقطه ای است که به امنیت می اندیشم؛ امنیت بخش جداناپذیر هرفناوری است.
بگذارید با چند سوال ساده مسیرمان را آغاز کنیم، آیا با دنیای متن باز و متعلقات آن آشنا هستید؟ یا تا به حال از لینوکس استفاده کرده اید؟ یا شاید در مورد آن چیزهایی شنیده باشید، برای نمونه یکی از پرتکرار ترین گزاره ها، امنیت در لینوکس است فارغ از آنکه امنیت آن در چه وضعیتی است، در این نوشتار قصد داریم یکی از راهکارهای (Solution) امنیت در لینوکس را تشریح کنیم؛ قبل از هر چیزی جا دارد یادآور شوم که این نوشتار حاوی کلمات و اصطلاحات تخصصی است که سعی شده تا جایی که امکان دارد با کلمات فارسی جایگزین و ترجمه نشود.
بگذارید با یک سؤال دیگر، به اصل مطلب بپردازیم، چگونه میتوان امنیت لینوکس را افزایش داد؟ سؤالی بسیار کلی است میدانم ولی خوشبختانه نیاز نیست شما به آن پاسخ دهید بلکه در آژانس امنیت ملی آمریکا (NSA) با راهکاری جامع به آن پاسخ و در نهایت با همکاری Red Hat اقدام به توسعه پروژه ای به نام SELinux شد که در یکسری از توزیع های لینوکسی مثل فدورا و Red Hat نسخه سازمانی به صورت پیش فرض وجود دارد.
پیشینه و تاریخچه مختصر
پروژه SELinux یک طرح توسعه از آژانس امنیت ملی آمریکا بوده است که از معماری به نام Flask پیاده سازی شده که مخفف عبارت Flux Advanced Security Kernel است، معماری امنیتی سیستم عامل، یک پروژه مشترک بین آژانس امنیت ملی و دانشگاه یوتا (واقع در سالت لیک سیتی مرکز ایالت یوتا آمریکا) بوده است.
ورژن اولیه پروژه مذکور در ۲۲ دسامبر سال ۲۰۰۰ توسط تیم اصلی توسعه آژانس امنیت ملی در جامعه توسعه دهندگان متن باز تحت لایسنس GNU GPL منتشر شد. در همایش کرنل لینوکس سال ۲۰۰۱ آژانس امنیت ملی پیشنهاد کرد که SELinux در لینوکس کرنل نسخه ۲٫۵ به
عنوان پچ کرنل گنجانده شود ولی چون در آن زمان پروژه های امنیتی متعددی در حال توسعه بود و با هم تفاوت های بسیاری داشتند و هرکدام به صورت کرنل پچ ارائه می شدند به همین علت جامعه امنیت هنوز در مورد مدل امنیتی نهایی اجماع نکرده بود و لینوس توروالدز خالق کرنل لینوکس با آگاهی بر این موضوع، پیشنهاد آژانش امنیت ملی را رد کرد، و یک فریمورک کلی را تشریح کرد که توانایی لود کردن ماژول های کرنل را داشته باشد تا هرگونه مدل امنیتی را پیاده سازی کند؛ در پاسخ کریسپین کوان LSM را که مخفف عبارت Linux Security Modules است راپیشنهاد کرده است، فریمورکی که به کرنل لینوکس این امکان را می دهد که از مدل های امنیتی متعدد پشتیبانی کند؛ LSM تحت لایسنس GNU GPL منتشر و در جریان اصلی کرنل لینوکس پذیرفته شد و در تاریخ دسامبر ۲۰۰۳ و به عنوان بخشی از استاندارد لینوکس ۲٫۶ گنجانده شد.
آشنایی با Linux Security Modules
پروژه LSM توسط WireX شروع شد و یک پروژه مشترک بین چندین پروژه مثل SELinux و Immunix و SGI و دیگر اشخاص بود که در توسعه این پروژه حضور داشتند؛ شاید پاسخ به این سوال درک درستی از مطلب را به ما بدهد، که دقیقا چرا پشتیبانی LSM در داخل کرنل مورد نیاز است؟ نرم افزار های بسیار متنوعی تولید می شود و در موازی با آن آسیب پذیری هم به صورت چشم گیری افزایش پیدا می کند، یکی از روش های کاهش impact نرم افزار های آسیب پذیر، استفاده از کنترل دسترسی (Access Control) است که در ادامه ی مقاله آن را توضیح خواهیم داد که چگونه کنترل دسترسی می تواند امنیت را افزایش دهد (کافی نیست ولی لازم است). نکته مهم دیگر این است که LSM به خودی خود باعث افزایش امنیت نمی شود و یک بستری را فراهم می کند تا بتوانیم از ماژول های امنیتی استفاده کنیم.
LSM یک فریمورک است که با استفاده از آن می توانید از ماژول های امنیتی استفاده کنید و از ماژول هایی که پشتیبانی می کند می توان به موارد زیر اشاره کرد:
- SELinux
- AppArmor
- Smack
- TOMOYO
- Landlock
قبل از آنکه SELinux را توضیح دهیم بهتر است ابتدا به سیستم سنتی امنیت در لینوکس را برسی کنیم تا بهتر متوجه شویم که SELinux دقیقا چه مزیتی دارد و استفاده از آن چرا در سرور ها توصیه می شود.
سیستم سنتی امنیت در لینوکس چطور کار می کند؟
بهتر است ابتدا به صورت مختصر کنترل دسترسی را توضیح دهیم تا خللی در فهم مطلب رخ ندهد، کنترل دسترسی یکی از مکانیزم های امنیتی است که تعیین می کند چه کسی یا چه چیزی، مجاز به دسترسی منابع است و این منابع می تواند داده ها، برنامه ها و … باشد.
بگذارید قبل از آنکه مثالی بزنم، چند اصطلاح را در کنترل دسترسی توضیح دهم؛
- User: کاربر، یک شخص
- Subject: فرایندی که از طرف یک کاربر انجام می شود.
- Object: بخشی از داده یا منابع
مثال اول؛ شما به عنوان یک نویسنده یک فایلی به اسم فیلمنامه ایجاد می کنید، شما به عنوان صاحب فایل یا owner باید تصمیم بگیرید که آیا دوستان دیگر شما می توانند این فایل را مشاهده کنند؟ اگر بله چه مقداری می توانند دسترسی داشته باشند؟ مثلا می توانند چیزی به آن اضافه کنند یا حتی برخی خطوط فیلمنامه را حذف کنند؟ باید برای این موارد تصمیم بگیرید و درواقع شما به عنوان صاحب فایل باید سطح دسترسی یا permission را مشخص کنید، اینجاست که ما به مفهومی تحت عنوان Access Control نیازمند هستیم. به این نوع کنترل دسترسی DAC یا Discretionary Access Control می گوئیم؛ یک کنترل دسترسی اختیاری است و نسبت به مدلی که در ادامه برسی خواهیم کرد محدودیت دارد.
به تصویر زیر خوب دقت کنید تا در فهم مطلب به شما کمک کند.
یک مثال دیگر نیاز است تا کامل به ماژول SELinux احساس نیاز شود؛ ولی قبل از آن باید مختصرا مدیریت اکانت در لینوکس را تشریح کنیم، زمانی که شما در لینوکس یک اکانت می سازید لینوکس به صورت اتوماتیک یک شناسه عددی که باید منحصر به فرد باشد را به اکانت می دهد که به آن User Identifier می گویند، چرا؟ چون لینوکس هیچ درکی از نام اکانتی که ما به آن می دهیم ندارد و صرفا تمام عملیات مورد نیاز با همین شناسه عددی انجام می شود در مورد مشابه، ویندوز هم برای اکانت ها از SID که یک شناسه است استفاده می کند.
در لینوکس با دستور id می توانید UID مربوط به اکانت خود را ببینید.
اگر کمی دقت کرده باشید در تصویر بالا بعد از UID، عددی مربوط به GID می بینید که این شناسه عددی مربوط به گروه هاست درواقع گروه هایی که اکانت ها در آن قرار می گیرند.
در تصویر زیر هم لیستی از اکانت های سیستم لینوکس را می بینید که گل سر سبد آن اکانت root است.
به تصویر زیر نگاه کنید، ما یک برنامه در حال اجرا داریم که دارای یک UID و GID است که به عنوان Subject آن را می شناسیم و باید به منابع مورد نیاز دسترسی پیدا کند، منابع می تواند هرچیزی باشد فایل یا دایرکتوری یا حتی یک پورت شبکه، که به عنوان Object آن را می شناسیم، این File دارای یک سطح دسترسی یا Permissions است و وقتی یک برنامه به یک فایل دسترسی دارد روی آن می تواند Action انجام دهد که شامل Write، Read و Execute است. تنها راه حفاظت از objectها تنظیم permissions است.
باید یادآور شوم که هر object یک owner یا صاحب دارد که دارای uid و gid است آن اکانت است که برای فایل سطح دسترسی مشخص می کند این نوع کنترل دسترسی را DAC می گوئیم که پیشتر آن را توضیح دادیم، نکته ای که وجود دارد این است که به اندازه کافی امن نیست.
یک وب سرور در حال اجرا را تصور کنید که id آن برابر با ۵۰ است و این فرایند یا Process توسط یک هکر Compromised شده است، هکر می تواند به تمامی فایل هایی که فرایند کاربر با id 50 به آن دسترسی دارد دسترسی داشته باشد! و این شروع آسیب به سیستم شما خواهد بود. در واقع هکر می تواند فرضا دایرکتوری /etc/passwd را بخواند.
اینجا نقطه ای است که ما به SELinux در سرور ها نیاز خواهیم داشت، این ماژول جایگزین سیستم سنتی نشده است بلکه یک لایه ی امنیتی اضافی است که امنیت را ارتقاء می دهد.
SELinux چطور کار می کند؟
SELinux کنترل دسترسی MAC را پیاده سازی می کند، و به ادمین لینوکس این امکان را می دهد تا یک سیستم سیاست امنیت متمرکز را ایجاد کند و اینکه چه کاربر و فرایندی به چه منابعی دسترسی دارد مشخص می شود. مهم ترین بخش این است که از اصل Least-Privilege استفاده می شود و به صورت پیش فرض دسترسی به منابع مسدود شده است.
SELinux به طور کلی به سوال زیر پاسخ می دهد:
که این سوال را می توان اینطور مطرح کرد که آیا فلان Subject می تواند بهمان Action را بر روی فولان Object انجام دهد؟ که در ادامه جزئیات آن را برسی خواهیم کرد.
ماژول مذکور از SELinux Policies استفاده می کند تا برای هر درخواست (Request) تصمیمی گرفته شود، خروجی تصمیم می تواند تائید یا انکار شود (Allow و Deny). در این پالیسی مجموعه ای از قوانین یا Rules وجود دارد که تعیین می کند نحوه دسترسی به منابع به چه صورتی باشد در واقع این قوانین هستند که مجوز ها را برای هر کاربر، برنامه و منابع تعیین می کند و تصمیم ها براساس این قوانین گرفته می شود.
بخش دیگری به نام AVC در SELinux وجود دارد که مخفف عبارت Access Vector Cache است که امکان افزایش سرعت چک کردن درخواست ها را می دهد، اما چطور؟ به این صورت که یکسری درخواست-ها برای یکسری از منابع، پرتکرار خواهد بود و نتیجه ی تصمیم در AVC به صورت موقت ذخیره می شود یا به عبارتی کش می شود تا دیگر نیاز نشود هر درخواست به سمت SELinux Policies برود و همین امر باعث افزایش بهره وری می شود.
فرایند یا Process که به عنوان Subject شناخته می شود قصد دارد از یک منبعی استفاده کند و یک Action خاصی را انجام دهد برای همین سمت SELinux یک درخواست را ارسال میکند، درخواست ابتدا توسط AVC چک و برسی می شود که آیا در رابطه با این درخواست قبلا تصمیم گیری (کش) شده است یا خیر. اگر تصمیم گیری شده باشد پاسخی به فرایند می دهد اما اگر تصمیمی نسبت به این درخواست کش شده نباشد، AVC درخواست را سمت SELinux فوروارد میکند تا طبق قوانین و مجوز ها بتواند یک تصمیم جدیدی تولید کند که در نهایت یا به فرایند اجازه دسترسی داده می شود یا نمی شود، چیزی که مهم است این است که در تصمیم جدید که در AVC کش می شود تا اگر بار دیگر این فرایند درخواستی را به سمت SELinux ارسال کرد، سریعتر پاسخ را دریافت کند.
SELinux Labels و Type Enforcement
هر فرایند (Subject) و منابع (object) دارای یک Label یا برچسب است که به آن Context می گویند که توسط ادمین فراهم می شود تا در کنار قوانین پالیسی، SELinux بتواند تصمیم بگیرد که دقیقا چه اقداماتی مجاز است. Context دارای فرمت user:role:type:level است.
۱٫ User: کاربر لینوکس با کاربر SELinux اصطلاحا Map می شود.
۲٫ Role: نشان دهنده نقشی است که کاربر دارد مثلا یک normal user است.
۳٫ Type: این مجوزهای اجرا شده را تعیین می کند.
۴٫ Level: اختیاری است اما سطح مجوز امنیتی را مشخص میکند.
قسمت type برچسب مهم ترین بخش است. Type Enforcement به این معنی است که SELinux نوع برچسب را بررسی میکند و فقط به type های مجاز اجازه دسترسی به منابع را میدهد. هر type دارای لیستی از اقدامات مجاز است. هنگامی که یک کاربر/برنامه سعی می کند به چیزی دسترسی پیدا کند، SELinux برچسب های نوع را با هم مقایسه می کند. اگر typeها با قوانین پالیسی مطابقت داشته باشند، دسترسی داده می شود.
حالت های SELinux یا SELinux Modes
یکی از ویژگی های کلیدی SELinux توانایی کار در حالت های مختلف است که به sysadmin ها اجازه می دهد تا امنیت سیستم را به دقت تنظیم کنند.
سه حالت اصلی که در SELinux وجود دارد:
۱٫ Enforcing Mode: این حالت به صورت پیش فرض فعال است و در بین حالت های دیگر امن-ترین محسوب میشود. اگر کاربر یا فرآیندی تلاش کند به منبعی دسترسی پیدا کند که توسط پالسی مجاز نیست، SELinux درخواست را رد کرده و خروجی تصمیم را در AVC لاگ میکند.
۲٫ Permissive Mode: نسبت به حالت قبلی امنیت کمتری دارد به این شکل عمل میکند که دسترسی مسدود نمی شود صرفا اخطار داده میشود و آن را لاگ میکند.
۳٫ Disabled Mode: یعنی راحت باشید من کاری با کسی ندارم.
نویسنده : حسین نایئجی – دانشجوی دوره مقدمات لینوکس
منابع
- https://en.wikipedia.org/wiki/Linux_Security_Modules
- https://www.infradead.org/~mchehab/rst_conversion/security/lsm.html
- https://www.cs.utah.edu/flux/fluke/html/flask.html
- https://blog.cloudflare.com/live-patch-security-vulnerabilities-with-ebpf-lsm
- https://github.com/kubearmor/KubeArmor/wiki/Introduction-to-Linux-Security-Modules-(LSMs)
- https://www.microsoft.com/en-ca/security/business/security-101/what-is-access-control
- https://www.cs.cornell.edu/courses/cs5430/2015sp/notes/dac.php#:~:text=Determine%20access%3A%20decide%20whether%20a,to%20enable%20access%20to%20one.
- https://phoenixnap.com/kb/selinux#:~:text=SELinux%20works%20by%20implementing%20mandatory,this%2C%20SELinux%20uses%20security%20policies.