
Jailer هو نظام عزل عمليات قائم على eBPF يوفر التحكم الإجباري في الوصول (MAC) لنظام Linux. يتتبع العمليات باستخدام خرائط تخزين المهام BPF ويفرض سياسات قائمة على الأدوار على الوصول إلى الملفات، وعمليات الشبكة، وتنفيذ العمليات.
تحذير: هذا المشروع قيد التطوير المكثف وليس جاهزًا للاستخدام في الإنتاج. قد تتغير واجهات برمجة التطبيقات وتنسيقات السياسات والسلوك دون إشعار مسبق. استخدمه للاختبار والتجربة فقط.
ملاحظة: هذا تطبيق مستقل وليس نفس مشروع حل Meta. بينما BpfJailer مشابه وظيفيًا ومستوحى من الفكرة والتصميم الأصلي من قبل Liam Wisehart وJustin Nga وCarl El Khoury وMansee Chadha في Meta، إلا أن هذه قاعدة كود منفصلة تم تطويرها بشكل مستقل. نعرب عن امتناننا للرؤية والمفاهيم الأساسية التي ألهمت هذا العمل.
Jailer هو نظام عزل العمليات قائم على eBPF يوفر التحكم الإلزامي في الوصول (MAC) لنظام Linux. يتتبع العمليات باستخدام خرائط BPF task_storage ويفرض سياسات قائمة على الأدوار للوصول إلى الملفات وعمليات الشبكة وتنفيذ العمليات.
| الميزة | الحالة | الوصف |
|---|---|---|
| تتبع العمليات | ✅ يعمل | يتتبع العمليات باستخدام خريطة BPF task_storage |
| تسجيل المقابس | ✅ يعمل | تسجل العمليات عبر واجهة برمجة تطبيقات مقبس Unix |
| سياسات قائمة على الأدوار | ✅ يعمل | أدوار مقيدة ومتسامحة |
| التحكم في الوصول إلى الملفات | ✅ يعمل | حظر/السماح بعمليات فتح الملفات |
| وراثة العزل | ✅ يعمل | ترث العمليات الفرعية عزل العملية الأم |
| التحكم في الشبكة | ✅ يعمل | حظر/السماح بربط المقابس/الاتصال بها |
| تصفية المنافذ/البروتوكولات | ✅ يعمل | قواعد السماح/المنع لكل منفذ TCP/UDP |
| التحكم في التنفيذ | ✅ يعمل | حظر/السماح بتنفيذ العمليات |
| مطابقة المسار | ✅ يعمل | التجول عبر dentry مع إبطال التخزين المؤقت |
| الملفات الثنائية الموقعة | 🚧 إطار عمل | التحقق من توقيع الملفات الثنائية (غير مطبق) |
| التسجيل البديل | ✅ يعمل | التسجيل التلقائي بواسطة الملف القابل للتنفيذ أو cgroup أو xattr |
| وضع بدون خادم | ✅ يعمل | يقوم الملف الثنائي للتشغيل بتثبيت البرامج في وقت التشغيل المبكر |
| أحداث التدقيق | ✅ يعمل | مخزن perf للتكامل مع systemd-journald |

BPF_MAP_TYPE_TASK_STORAGE)# التحقق من تكوين النواة الحالي
zcat /proc/config.gz 2>/dev/null || cat /boot/config-$(uname -r)
الخيارات المطلوبة:
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_LSM=y
CONFIG_DEBUG_INFO_BTF=y
يجب تفعيل BPF LSM في معلمات تشغيل النواة:
# التحقق مما إذا كان BPF LSM نشطًا
cat /sys/kernel/security/lsm
# يجب أن يتضمن "bpf" في القائمة
# إذا لم يكن، أضفه إلى معلمات تشغيل النواة:
# قم بتحرير /etc/default/grub وأضف إلى GRUB_CMDLINE_LINUX:
# lsm=lockdown,capability,landlock,yama,apparmor,bpf
# ثم قم بتحديث grub وأعد التشغيل:
sudo update-grub
sudo reboot
بالنسبة لأنظمة Ubuntu/Debian، يمكنك أيضًا استخدام:
# إنشاء سكربت لتفعيل BPF LSM
cat > /tmp/enable_bpf_lsm.sh << 'EOF'
#!/bin/bash
GRUB_FILE="/etc/default/grub"
if grep -q "lsm=" "$GRUB_FILE"; then
sudo sed -i 's/lsm=[^""]*/lsm=lockdown,capability,landlock,yama,apparmor,bpf/' "$GRUB_FILE"
else
sudo sed -i 's/GRUB_CMDLINE_LINUX="\(.*\)"/GRUB_CMDLINE_LINUX="\1 lsm=lockdown,capability,landlock,yama,apparmor,bpf"/' "$GRUB_FILE"
fi
sudo update-grub
echo "BPF LSM مفعل. يرجى إعادة التشغيل."
EOF
chmod +x /tmp/enable_bpf_lsm.sh
sudo /tmp/enable_bpf_lsm.sh
# تثبيت Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# تثبيت تبعيات البناء (Ubuntu/Debian)
sudo apt-get install -y clang llvm libelf-dev linux-headers-$(uname -r)
# تثبيت هدف BPF لـ Rust
rustup target add bpfel-unknown-none
cd bpfjail
# بناء برامج BPF
cd bpfjailer-bpf && cargo build --release && cd ..
# بناء الخادم والعميل
cargo build --release
# تشغيل كجذر (يقوم بتحميل config/policy.json إذا كان موجودًا)
sudo RUST_LOG=info ./target/release/bpfjailer-daemon
المخرجات المتوقعة:
[INFO] BpfJailer daemon starting...
[INFO] Loading BpfJailer eBPF programs with libbpf-rs...
[INFO] ✓ pending_enrollments map available for enrollment
[INFO] ✓ network_rules map available for port/protocol filtering
[INFO] ✓ task_storage map created successfully
[INFO] ✓ Program task_alloc attached
[INFO] ✓ Program file_open attached
[INFO] ✓ Program socket_bind attached
[INFO] ✓ Program socket_connect attached
[INFO] ✓ Program bprm_check_security attached
[INFO] Initialized with default roles: restricted (1), permissive (2)
[INFO] Loaded policy from config/policy.json
[INFO] Loaded 5 roles
[INFO] Enrollment server listening on /run/bpfjailer/enrollment.sock
# تشغيل اختبارات الثغرات بدون عزل (يظهر نجاح الهجمات)
sudo python3 tests/vulnerable_apps/run_tests.py
# تشغيل اختبارات الثغرات مع دور مقيد (يظهر حظر الهجمات)
sudo python3 tests/vulnerable_apps/run_tests.py --role 1
# تشغيل اختبار محدد
sudo python3 tests/vulnerable_apps/run_tests.py --role 1 --test path
# عرض الاختبارات والأدوار المتاحة
sudo python3 tests/vulnerable_apps/run_tests.py --list
مثال على المخرجات مع دور مقيد:
============================================================
اختبار: تجاوز المسار / قراءة ملف عشوائي
============================================================
محاولة قراءة /etc/passwd عبر تجاوز المسار...
مُحظَر - تم رفض الإذن (BpfJailer منع الوصول إلى الملف)
============================================================
اختبار: حقن الأوامر
============================================================
محاولة حقن الأوامر...
مُحظَر - تم رفض الإذن (BpfJailer منع التنفيذ)
============================================================
اختبار: شل عكسي / تسريب بيانات
============================================================
الاختبار 1: اتصال شل عكسي إلى 127.0.0.1:4444
مُحظَر - تم رفض الإذن (BpfJailer منع الاتصال)
| الاختبار | الثغرة | يتم التخفيف بواسطة |
|---|---|---|
path_traversal | قراءة ملف عشوائي عبر ../ | مقيد، معزول |
command_injection | تنفيذ أوامر شل | مقيد، خادم ويب، معزول |
reverse_shell | اتصالات صادرة إلى المهاجم | مقيد، معزول |
ssrf | الوصول إلى الخدمات الداخلية/بيانات السحابة الوصفية | مقيد، معزول |
arbitrary_write | الكتابة إلى مسارات حساسة | مقيد |
crypto_miner | تنزيل + تنفيذ + اتصال بمجمع التعدين | مقيد، خادم ويب |
privilege_escalation | قراءة shadow، كتابة sudoers | مقيد |
#!/usr/bin/env python3
import socket
import json
import os
# الاتصال بالخادم
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect("/run/bpfjailer/enrollment.sock")
# التسجيل بدور مقيد (المعرف 1)
request = {"Enroll": {"pod_id": 1, "role_id": 1}}
sock.send((json.dumps(request) + "\n").encode())
response = sock.recv(4096).decode()
print(f"التسجيل: {response}")
sock.close()
# محاولة قراءة ملف (يجب حظره)
try:
open("/etc/passwd").read()
print("الوصول إلى الملف: مسموح")
except PermissionError:
print("الوصول إلى الملف: محظور")
يقوم BpfJailer بتحميل الأدوار من ملف سياسة JSON. يبحث الخادم عن ملف السياسة بهذا الترتيب:
$BPFJAILER_POLICY/etc/bpfjailer/policy.jsonconfig/policy.json (بالنسبة إلى دليل العمل)