تقوية SELinux 2026: دليل السياسات وحل مشكلات الحرمان على RHEL وRocky وAlmaLinux
تعلم تقوية SELinux 2026 على RHEL 10 وRocky وAlmaLinux: تشغيل الوضع الفارض، إصلاح حرمانات AVC، كتابة سياسات Podman بـ udica، وضبط المنطقيات. أوامر مختبرة وأمثلة من الإنتاج.
SELinux في 2026 هو الطبقة الأقوى للتحكم الإلزامي بالوصول على عائلة Red Hat (RHEL وRocky Linux وAlmaLinux)، وتفعيله بالوضع الفارض (enforcing) مع سياسة targeted يحجب معظم محاولات الاستغلال بعد الاختراق الأولي. في هذا الدليل أفكك الهجمات التي أراها أسبوعياً ضد خوادم RHEL 9 وRHEL 10، ثم أربط كل خطوة بضابط SELinux يعطّلها. كل أمر مختبر على Rocky Linux 9.5 وAlmaLinux 10 الصادر مطلع 2026.
يجب أن يكون SELinux في الوضع enforcing مع سياسة targeted على أي خادم إنتاج؛ الوضع permissive مفيد للتشخيص فقط وليس بديلاً.
أغلب أعطال التطبيقات سببها سياق ملف خاطئ يُحَل بـ restorecon أو semanage fcontext، وليس بإيقاف SELinux.
المنطقيات (booleans) تتيح ضبط السياسة دون كتابة وحدات؛ فمثلاً httpd_can_network_connect يمنع حركة شبكة Apache افتراضياً.
عند الحاجة لاستثناء حقيقي اكتب وحدة سياسة محلية بـ audit2allow -M بدل تعطيل النظام بأكمله.
على Podman وDocker تعمل حاويات بسياق container_t منفصل؛ تركيب وحدة تخزين يتطلب علامة :Z لإسناد السياق الصحيح.
أدوات RHEL 10 الجديدة udica وsetroubleshoot تختصر كتابة السياسات للحاويات وتفسير حرمانات AVC تلقائياً.
ما الجديد في SELinux 2026 ولماذا لا يزال ضرورياً
SELinux ليس بقايا حقبة 2005؛ إنه آلية فرض إلزامية مدمجة في النواة عبر إطار Linux Security Modules (LSM) تربط كل عملية وكل ملف وكل مقبس شبكي بسياق أمني (context)، ثم تستشير سياسة مُحَمَّلة قبل السماح بأي عملية. الفرق عن أذونات Unix التقليدية أن المستخدم الجذر (root) لا يستطيع تجاوز سياسة SELinux إذا كانت في الوضع الفارض، وهذا ما يكسر سلاسل الاستغلال الكلاسيكية.
في إصدارات 2026 وصلت سياسة selinux-policy إلى الإصدار 40.x على RHEL 10 مع دعم محسّن لحاويات OCI ومسارات أحدث في /var/lib/containers، وأصبحت أداة udica الجزء القياسي من podman لتوليد سياسات حاويات تلقائياً من ملف JSON ينتجه Podman. كذلك أُضيف نوع systemd_resolved_t منفصل بعد ترقية systemd-resolved الأخيرة، ودخلت قواعد جديدة لمحرّك nftables الذي غطيناه في دليل nftables الشامل 2026.
من زاوية اختبار الاختراق: حين أحصل على شل عبر استغلال PHP-FPM على RHEL 9 بدون SELinux، أكون في الواقع جذراً خلال دقائق. على نفس الخادم مع SELinux في وضع enforcing أبقى محصوراً داخل httpd_t، لا أستطيع قراءة /etc/shadow، ولا تشغيل nc صادر، ولا الكتابة في /var/www خارج httpd_sys_rw_content_t. هذه الفجوة بين «الاختراق» و«التحكم الكامل» هي ما يدفعه ثمناً المهاجم وقتاً، ويعطي فريق الكشف فرصة للرد.
كيفية تشغيل SELinux والتحقق من الحالة
على RHEL وRocky وAlmaLinux يأتي SELinux مفعّلاً في وضع enforcing افتراضياً منذ سنوات، لكن صور السحابة الأصغر وبعض الحاويات المهيأة قد تأتي بـ permissive أو حتى disabled. تحقق أولاً:
# الوضع الحالي
sestatus
# تفصيلياً
getenforce # Enforcing | Permissive | Disabled
cat /etc/selinux/config
إن كان النظام معطّلاً تماماً (SELINUX=disabled في /etc/selinux/config)، الانتقال المباشر إلى enforcing سيُفشل الإقلاع لأن نظام الملفات بلا تسميات. الإجراء الصحيح في 2026 على RHEL 9/10:
# 1) انتقل أولاً إلى permissive
sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
# 2) أنشئ علامة لإعادة وسم نظام الملفات عند الإقلاع
fixfiles onboot
# 3) أعد التشغيل ودع autorelabel يكمل (قد يستغرق دقائق)
reboot
# 4) بعد العودة تحقق ثم انتقل إلى enforcing
getenforce
setenforce 1
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
السياقات والأنواع والسياسة المستهدفة
كل كائن في النظام له سياق من أربعة أجزاء: user:role:type:level. في سياسة targeted (الافتراضية)، يهم عملياً جزء النوع (type). تَفقَّد سياق ملف أو عملية:
# سياقات الملفات
ls -lZ /var/www/html
# system_u:object_r:httpd_sys_content_t:s0 index.html
# سياقات العمليات
ps -eZ | grep nginx
# system_u:system_r:httpd_t:s0 ... nginx: master process
# سياقات منافذ الشبكة
semanage port -l | grep ^http_port_t
# http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
الأنواع الأكثر مواجهة في الإنتاج: httpd_sys_content_t لملفات يستطيع Apache/Nginx قراءتها، httpd_sys_rw_content_t لمسارات الكتابة (التحميلات)، httpd_log_t للسجلات، وcontainer_file_t لما تركّبه في Podman. عندما تنقل ملفاً بـ mv فإنه يحتفظ بسياقه الأصلي، بعكس cp الذي يكتسب سياق الوجهة. خطأ شائع يفسّر «لماذا عاد الموقع يعمل بعد إعادة النسخ».
لتثبيت سياق دائم لمسار خاص بك (تطبيق مخصص في /srv/app/public):
semanage fcontext -a -t httpd_sys_content_t "/srv/app/public(/.*)?"
restorecon -Rv /srv/app/public
السطر الأول يضيف القاعدة لقاعدة بيانات السياقات (يستمر بعد restorecon)، والثاني يطبّقها فعلياً على الملفات.
المنطقيات: ضبط السياسة دون كود
المنطقيات (booleans) مفاتيح on/off تعدّل سلوك السياسة المُحَمَّلة دون كتابة وحدة جديدة. هذه أكثر أداة تُختصر بها مشاكل الإنتاج في 2026:
# سرد المنطقيات المتعلقة بـ httpd
getsebool -a | grep httpd
# اسمح لـ Apache بالاتصال بقواعد بيانات بعيدة
setsebool -P httpd_can_network_connect_db on
# اسمح لـ Apache بإجراء اتصالات شبكة عامة (حذِر منه)
setsebool -P httpd_can_network_connect on
# اسمح بتنفيذ سكربتات CGI الكتابة على القرص
setsebool -P httpd_unified on
راية -P تجعل التغيير دائماً عبر الإقلاع. من منظور المهاجم، httpd_can_network_connect هو هدف ذهبي: تفعيله يفتح إمكانية shell عكسي من خادم ويب مخترق، لذا حافظ عليه off ما لم يكن مطلوباً، وفعّل البديل المحدد httpd_can_network_connect_db لقواعد البيانات فقط.
كيف أصلح حرمانات SELinux (AVC denials)؟
عند رفض SELinux لعملية يُسجَّل حرمان (Access Vector Cache denial) في /var/log/audit/audit.log. القراءة الخام صعبة، لذا استخدم سلسلة الأدوات التالية:
# تابع الحرمانات الحديثة (مفيد أثناء إعادة تشغيل الخدمة المعطّلة)
ausearch -m AVC,USER_AVC -ts recent
# تفسير بشري عبر setroubleshoot
sealert -a /var/log/audit/audit.log
# تابع الحرمانات حياً
journalctl -f _AUDIT_TYPE_NAME=AVC
الترجمة: عملية nginx بسياق httpd_t حاولت قراءة ملف بسياق user_home_t. هذا خاطئ بنيوياً، الإصلاح هو تصحيح سياق الملف لا فتح السياسة. ضع الملف تحت مسار صحيح أو طبّق chcon ثم ثبّت بـ semanage fcontext.
كتابة وحدة سياسة مخصصة بـ audit2allow
حين يكون الحرمان مشروعاً (تطبيق مخصص يحتاج إذن غير قياسي)، ولّد وحدة محلية بدل إيقاف SELinux:
# 1) أعد تشغيل الخدمة لتجميع كل الحرمانات
systemctl restart myapp
# 2) ولّد وحدة سياسة من سجل التدقيق
ausearch -m AVC -ts recent | audit2allow -M myapp_local
# هذا ينتج ملفين: myapp_local.te (مصدر) و myapp_local.pp (وحدة مُترجَمة)
# 3) راجع .te يدوياً قبل التحميل
cat myapp_local.te
# 4) حمّل الوحدة
semodule -i myapp_local.pp
# سرد الوحدات المحملة
semodule -l | grep myapp
لإزالة وحدة محلية لاحقاً: semodule -r myapp_local. حافظ على ملفات .te في مستودع Git مع رسائل التزام تشرح لماذا كل قاعدة لازمة. هذه وثيقة تدقيق امتثال PCI/HIPAA حقيقية.
SELinux مع الحاويات وPodman
على RHEL 9/10 يُشغّل podman الحاويات بسياق container_t وهو معزول تماماً عن المضيف. المشكلة الشائعة: تركيب وحدة تخزين (-v) دون علامة سياق فيفشل الوصول. الحل:
# خطأ شائع
podman run -v /srv/data:/data nginx:alpine
# داخل الحاوية: Permission denied على /data
# الحل: علامة Z تُعيد وسم المسار بسياق container_file_t خاص بالحاوية
podman run -v /srv/data:/data:Z nginx:alpine
# علامة z (صغيرة) تسمح بالمشاركة بين حاويات متعددة
podman run -v /srv/shared:/shared:z nginx:alpine
لخدمات تحتاج صلاحيات إضافية (Falco، عُملاء مراقبة)، ولّد سياسة مخصصة بـ udica بدل تشغيل الحاوية --privileged:
هذه الطريقة تتكامل جيداً مع منصة كشف التسلل التي شرحناها في دليل Wazuh الشامل، حيث تُستهلك حرمانات AVC كقواعد تنبيه عالية الأولوية.
ما الفرق بين SELinux وAppArmor؟
السؤال يتكرر في كل ورشة عمل تقوية ألقّيها. كلاهما LSM ينفّذان MAC لكن النموذج مختلف:
الميزة
SELinux
AppArmor
التوزيعات الأم
RHEL, Rocky, AlmaLinux, Fedora, CentOS Stream
Ubuntu, Debian, openSUSE
نموذج التعريف
سياقات + أنواع (Type Enforcement)
مسارات ملفات + قدرات
منحنى التعلم
حاد (سياسة معقدة لكن قوية)
أسهل (ملفات تعريف نصية مقروءة)
دقة التحكم
عالية جداً (لكل سياق نوع)
جيدة لكن أقل تعبيرية
الأدوات
semanage, audit2allow, sealert
aa-genprof, aa-logprof
دعم الحاويات
ممتاز عبر container-selinux وudica
أساسي عبر ملفات تعريف موقعة
الافتراضي في 2026
enforcing على RHEL 10
enforce على Ubuntu 24.04 LTS
القاعدة العملية: استخدم نظام MAC الذي تأتي به توزيعتك. لا تركّب SELinux على Ubuntu ولا AppArmor على RHEL. التوافق ضعيف والصيانة كابوس. إن كنت تدير الاثنين، راجع دليل AppArmor 2026 للجانب المقابل من المعركة.
قائمة تقوية SELinux في الإنتاج
تأكد getenforce يعيد Enforcing. أي خادم في Permissive دون تذكرة JIRA مُسبّبة هو انحراف.
نعم، خاصة على أي مضيف يشغّل حاويات أو خدمات إنترنت. أوقفت SELinux ثلاثَ سلاسل استغلال CVE هذا العام وحده عبر حصر الجذر داخل نطاق محصور. الحجة الوحيدة لإيقافه هي عدم القدرة على تعلّمه، وهذا حلّه تدريب لا تعطيل.
كيف أتحقق من حالة SELinux بسرعة؟
شغّل sestatus لرؤية الوضع والسياسة وعدد الوحدات المحملة، أو getenforce لمخرج كلمة واحدة (Enforcing/Permissive/Disabled) مناسب للسكربتات.
لماذا فشل تطبيقي بعد ترقية RHEL إلى 10؟
غالباً السبب أن سياسة selinux-policy الجديدة أضافت أنواعاً صارمة أو غيّرت سياق مسار. شغّل sealert -a /var/log/audit/audit.log أولاً، ثم طبّق restorecon -RFv /path. لا تعطّل النظام كحل سريع.
هل يمكن تشغيل SELinux داخل حاوية Docker؟
SELinux يعمل على المضيف، والحاوية ترث الحصر دون أن تشغّله بنفسها. تأكد أن صورة الحاوية لا تطلب صلاحيات على /sys/fs/selinux ما لم تكن أداة إدارة سياسات.
ما الفرق بين chcon وsemanage fcontext؟
chcon يغيّر السياق مؤقتاً وسيُستبدل عند أول restorecon. semanage fcontext -a يسجّل التغيير في قاعدة السياسة بشكل دائم. للإنتاج استخدم semanage دائماً.
دليل عملي لتقوية وحدات systemd في 2026: طبقات عزل نظام الملفات وseccomp وCapabilityBoundingSet وتصفية استدعاءات النظام، مع مثال كامل لخفض درجة nginx من 9.6 UNSAFE إلى ما دون 2.5 OK دون كسر الخدمة.