أساسيات التحكم في الوصول باستخدام SELinux في Red Hat Enterprise Linux


محمد أحمد العيل

عرضنا في دروس سابقة من هذه السلسلة لوسيلتين من وسائل التحكّم في الوصول على Red Hat Enterprise Linux، وهما إدارة الأذونات وقوائم التحكّم في الوصول. هاتان الآليتان مهمتان وأساسيّتان؛ إلا أن لديهما نقاطَ قصور تأتي آليّة أخرى تُسمّى Security Enhanced Linux (التأمين المُعزَّز في لينكس، وتشتهر بـSELinux) للتغلّب عليها. تنبغي الإشارة هنا إلى أن SELinux ليست الآليّة الوحيدة المستخدمة في توزيعات لينكس للتغلّب على عوامل النّقص في الآليتين المُشار إليهما سابقا. توجد آليّة أخرى تُسمّى AppArmor تتبناها توزيعات مثل Suse وUbuntu.

عند ما يُشغّل مستخدم برنامجا فإن العمليّة Process التي يُنفّذها تعمل بصلاحيّات هذا المستخدِم. يمكن في غياب آليّة مثل SELinux أن تنفّذ أي عمليّة الإجراءات التي تريد على الملفات التي يمكن للمستخدم الذي تعمل بصلاحياته الوصول إليها، مما قد يتسبّب الوصول غير المرخَّص إلى كامل النظام.

بدأت وكالة الأمن القومي الأمريكية NSA بتصميم SELinux من أجل تقييد قدرة العمليّات على الوصول إلى الكائنات (مثل الملفات، المجلدات، منافذ الشبكة، ..إلخ) أو إجراء عمليّات عليها؛ وقصرها على الحدّ الأدنى. يمكن تعديل التقييدات التي يُطبّقها نظام SELinux حسب الحاجة. تُضمِّن توزيعة Red Hat Enterprise Linux 7 وحدة خاصّة بنظام SELinux في النواة وتُفعّل مبدئيا وضع Enforcing. سنشرح في هذا الدّرس المفاهيم الأساسيّة التي يعتمد عليها نظام SELinux في عمله.

الأوضاع Modes في SELinux

يعمل SELinux في أحد الأوضاع الثلاثة التالية:

  • Enforcing: يمنع SELinux في هذه الحالة الوصول إلى الكائنات بناءً على مجموعة قواعد السياسة الأمنيّة المعرَّفة في النظام.
  • Permissive: لا يمنع SELinux في هذا الوضع العمليّات من الوصول إلى الكائنات، ويكتفي بتسجيل الإجراءات التي كانت ستُمنَع لو كان الوضع Enforcing مستخدما.
  • Disabled. نظام SELinux معطَّل.

يُظهر الأمر getenforce الوضع الذي يعمل عليه SELinux حاليا؛ بينما يضبط الأمر setenforce وضع SELinux للجلسة الحاليّة، ويتلقّى أحد معطييْن: 1 لوضع Enforcing و0 لوضع Permissive. إن أردت أن يكون تغيير وضع عمل SELinux دائما ولا يقتصر على الجلسة الحاليّة فستحتاج لتحرير الملفّ etc/selinux/config/ وتعيين قيمة التعليمة SELINUX بالوضع الذي تريد: permissive، enforcing أو disabled:

# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
# setenforce 1
# getenforce
Enforcing
# cat /etc/selinux/config

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #     enforcing - SELinux security policy is enforced.
    #     permissive - SELinux prints warnings instead of enforcing.
    #     disabled - No SELinux policy is loaded.
    SELINUX=enforcing
    # SELINUXTYPE= can take one of three two values:
    #     targeted - Targeted processes are protected,
    #     minimum - Modification of targeted policy. Only selected processes are protected. 
    #     mls - Multi Level Security protection.
    SELINUXTYPE=targeted

يُستخدَم الأمر setenforce عادةً للانتقال بين وضعيْ Enforcing وPermissive أثناء البحث عن أسباب مشكل. مثلا؛ إن ظهر المشكال أثناء تفعيل الوضع Enforcing واختفى عند الانتقال إلى الوضع Permissive فهذا يعني أن المشكل يتعلّق بقاعدة في سياسة SELinux الأمنيّة.

السيّاقات Contexts في SELinux

السيّاقات هي بيئة تحكّم في الوصول تُتخَّذ فيها الإجراءات بناء على مستخدم SELinux، الدّور Role والنوع Type وبصيغة اختيارية المستوى Level:

  • يُكمّل المستخدمون في SELinux المستخدمين العاديّن، إذ يربط SELinux حساب المستخدم العادي بحساب في SELinux. يُستخدَم حساب SELinux في السيّاق للتحكّم في العمليات من أجل تعريف أدوارها ومستوياتها.
  • يعمل الدّور وسيطا بين أنواع الملفّات والمستخدمين في SELinux إذ يُعرّف ماهي أنواع الملفات التي يمكن لمستخدمي SELinux الوصول إليها. تُساهم الأدوار في الحؤول دون الثغرات التي تؤدي إلى هجمات الارتقاء في الصلاحيّات Privilege escalation.
  • يعرّف SELinux نوعًا لكلّ ملفّ أو عمليّة. تُمنَع العمليّات في الظروف العاديّة من الوصول إلى الملفات التي تستخدمها عمليّات أخرى، أو من الوصول إلى هذه العمليّات. لا يُسمَح لعمليّة بالوصول إلى ملفّات إلا إذا أضيفت قاعدة إلى الساسية الأمنية تُصرّح لها بالوصول إلى النوع المستهدف.

سنرى في ما يلي أمثلة لعمل SELinux.

تغيير المنفذ المبدئي لخدمة SSH

شرحنا في درس سابق أن تغيير المنفذ المبدئي الذي تنصت عبره خدمة SSH هو أحد الإجراءات الأمنيّة المتّبعة لتأمين الخادوم ضدّ الهجمات القادمة من شبكة الإنترنت. نحرّر الملفّ etc/ssh/sshd_config/ لتغييرالمنفذ الذي تعمل عبره هذه الخدمة ليصبح المنفذ رقم 9999 (انزع علامة التعليق # عن التعليمة Port وحدّد القيمة 9999 بدلا من 22):

 
Port 9999

نحفظ التعديلات ونعيد تشغيل خدمة SSH (لاحظ الحرف d في نهاية اسم الخدمة):

# systemctl restart sshd
# systemctl status sshd

01_sshd_status_error.png

غيّرنا المنفذ الذي تُنصت عبره خدمة SSH ثم أعدنا تشغيل العمليّة sshd التي تتحكّم في الخدمة ولكن إعادة تشغيل الخدمة أخفقت كما يظهر ذلك عند إظهار حالة الخدمة (الأمر systemctl status). إن كنت تستخدم واجهة رسوميّة فستظهر رسالة بعد تنفيذ أمر إعادة التشغيل تفيد بأن SELinux لاحظ أمرا ما. مالذي حصل إذن؟

يمكّن الفحص السّريع لملف السّجل var/log/audit/audit.log/ الذي يحوي معلومات متعلّقة بالأحداث الأمنية على مستوى نظام التشغيل من الحصول على معلومات عن ما حدث. يُشار في ملفّ السّجل المذكور بالنوع AVC إلى المعلومات المتعلقة بـSELinux؛ تمكننا الاستعانة بهذه المعلومة للبحث في المُدخلات ذات الصّلة بـSELinux:

 
# grep AVC /var/log/audit/audit.log | tail -1

نلاحظ أن الخدمة sshd مُنعت من استخدام المنفذ 9999 نظرا لكونه محجوزا لصالح خدمة أخرى (JBoss Management):

02_sshd_audit_log.png

يمكنك تعطيل SELinux كما هو موضّح أعلاه وإعادة تشغيل خدمة SSH وستجد أن الخدمة تعمل على المنفذ الجديد؛ لكن لا تفعل. سنستخدم أداة semanage لإخبارنا بما يجب فعله لنتمكّن من تشغيل خدمة SSH على أي منفذ نريده دون مشاكل. ننفّذ الأمر التالي للحصول على لائحة بالمنافذ التي يسمح SELinux لخدمة SSH بالإنصات للاتّصالات القادمة عبرها:

# semanage port -l | grep ssh
ssh_port_t      tcp     22

يظهر في نتيجة الأمر أن SELinux يسمح لـSSH بالإنصات للاتّصالات القادمة عبر المنفذ 22 فقط، لا غير.

ما سنفعله الآن هو العودة إلى ملفّ إعداد SSH على المسار etc/ssh/sshd_config/ وتغيير المنفذ من 9999 إلى 9998:

 
Port 9998

ثم نضيف المنفذ 9998 إلى السيّاق ssh_port_t ونعيد تشغيل الخدمة:

# semanage port -a -t ssh_port_t -p tcp 9998
# systemctl restart sshd
# systemctl is-active sshd

03_ssh_context_port.png

تمكن ملاحظة أن الخدمة شُغّلت دون أية مشاكل هذه المرة. يوضّح هذا المثال كيف أن SELinux يتحكّم في منافذ الشبكة بالاعتماد على تعريفاته الخاصّة لنوع كلّ منفذ.

السّماح لخدمة httpd بالوصول إلى خدمة sendmail

ذكرنا أن SELinux يتحكّم في إمكانيّة وصول عمليّة Process إلى عمليّات أخرى. سنرى الآن مثالا على ذلك. سنفترض أنك تريد تفعيل وحدتي mod_security وmod_evasive على خادوم وِب Apache واستخدامهما لإرسال إشعارات بالبريد الإلكتروني (خدمة sendmail) عند حدوث هجمة حجب خدمة (Dos, Denial of Service). تحتاج في هذه الحالة للسماح لخادوم وِب Apache (خدمة httpd) بالوصول إلى خدمة البريد sendmail.

توجد في SELinux إعدادات تشغيل تُسمّى SELinux booleans (قيم منطقيّة) يمكن عبرها تعطيل أو تفعيل قواعد ضمن سياسة SELinux الأمنية. تُستخدم الأداة semanage للحصول على قائمة بجميع هذه الإعدادات:

 
# semanage boolean -l

يتحكّم الإعداد httpd_can_sendmail في إمكانيّة وصول الخدمة httpd إلى sendmail:

# semanage boolean -l | grep httpd_can_sendmail
httpd_can_sendmail      (off, off)      Allow httpd to can sendmail

يظهر في نتيجة الأمر أعلاه أن الإعداد مضبوط على القيمة off بمعنى أن القاعدة الأمنيّة معطّلة، نفعّلها على النحو التالي:

 
# setsebool -P httpd_can_sendmail 1

استخدمنا الأمر setsebool لتفعيل القاعدة بتمرير اسمها والقيمة 1 (تفعيل). يؤدي استخدام الخيار P- إلى استمرار مفعول الأمر (تفعيل القاعدة) بعد إعادة تشغيل الخادوم. يمكن التأكد من تغيير الإعداد بإعادة تنفيذ أمر semanage السابق:

# semanage boolean -l | grep httpd_can_sendmail
httpd_can_sendmail      (on, off)      Allow httpd to can sendmail

ملحوظة: يشير الحقل الثاني في نتيجة الأمر semanage boolean (أي (on, off)) في المثال أعلاه إلى قيمة الإعداد حاليّا (on)، وقيمته المبدئيّة (off).

تقديم صفحة وِب توجد في مجلّد مغاير للمجلد المبدئي

سنفترض في هذا المثال أن لديك موقع وِب توجد صفحاته في المجلّد websites/ بدلا من المجلّد المبدئي لخادوم الوِب (var/www/html/).

  1. أنشئ ملفا باسم index.html في المجلد websites/ وأضف إليه المحتوى التالي:

    <html>
      <h2>SELinux test</h2>
    </html>

    إن نفّذت الأمر التالي:

    # ls -lZ /websites/index.html

    فستجد أن الملفّ index.html من النوع default_t وهو النوع المبدئي في SELinux ولا يمكن لخادوم الوِب الوصولُ إليه.

  2. غيّر قيمة التعليمة DocumentRoot في الملفّ etc/httpd/conf/httpd.conf/ لتصبح websites/. حدّث كتلة Directory التي يظهر فيها اسم المجلّد المبدئي السابق؛ مثلا:

     
    <Directory "/var/www/html">
      ...
    </Directory>
    

    تصبح:

    <Directory "/websites">
      ...
    </Directory>

     

  3. أعد تشغيل خادوم الوِب:

    # systemctl restart httpd

     

  4. أدخل عنوان الخادوم في المتصفّح (أو 127.0.0.1 إن كان المتصفّح على الخادوم). يجب أن تظهر رسالة خطأ 403 تفيد بأن الوصول إلى هذا المحتوى ممنوع.

    ملحوظة: إن ظهرت الصفحة المبدئيّة لخادوم الوِب فعلّق جميع الأسطر الموجودة في الملفّ etc/httpd/conf.d/welcome.conf/ وأعد تشغيل خادوم الوِب.

  5. نعدّل نوع المجلّد websites/ وجميع محتوياته ليصبح httpd_sys_content_t type (بدلا من النوع المبدئي default_t) ممّا يتيح لخادوم الوِب Apache الوصول إلى هذا المحتوى بصلاحيّة القراءة فقط:

    # semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"

    ثم نطبّق سياسة SELinux التي عدّلناها للتّو:

    # restorecon -R -v /websites

     

أعد تشغيل خادوم الوِب وافتح عنوان الخادوم في المتصفّح من جديد، وستجد أن خادوم الوِب يعرض محتوى ملفّ HTML الذي أنشأناه سابقا.

موضوع SELinux متشعّب جدا؛ إلا أن المفاهيم التي عرضنا لها في هذا المقال ستمكّنك من إيجاد قاعدة تبني عليها للانتقال إلى مواضيع أخرى تتعلّق بنظام الحماية SELinux.

ترجمة - بتصرّف - لمقال RHCSA Series: Mandatory Access Control Essentials with SELinux in RHEL 7 – Part 13 لصاحبه Gabriel Cánepa.





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن