تقرير تقني: آلية عمل MurshidBackend_Colab.ipynb
مشروع مُرشِد | From Alerts to Guidance
MITRE ATT&CK-Aligned Techniques Mapping for SOC Analysts
1. نظرة عامة
MurshidBackend_Colab.ipynb هو دفتر Jupyter مُصمَّم لتشغيل الباكند الكامل لمشروع مُرشِد على بيئة Google Colab باستخدام **GPU (Tesla T4)**، مما يُتيح تشغيل نموذج LLaMA 3 8B بتكميم 4-bit لتوليد ملخصات دلالية غنية لقواعد Wazuh XML، وذلك على عكس البيئة المحلية التي تعمل بدون LLaMA (LOCAL mode).
الهدف الرئيسي
تشغيل FULL mode للـ pipeline:
قاعدة Wazuh XML
↓
LLaMA 3 8B ←── ملخص دلالي غني (GPU)
↓
SecureBERT+ ←── 768-dim embedding
↓
Logistic Regression ←── confidence scores لكل تقنية
↓
FastAPI + SQLite ←── تخزين وخدمة النتائج
↓
Cloudflare Tunnel ←── رابط عام للفرونت
2. المتطلبات قبل التشغيل
2.1 إعداد Google Colab
| المتطلب | التفاصيل |
|---|---|
| GPU | Tesla T4 — يُفعَّل من: Runtime → Change runtime type → T4 GPU |
| الذاكرة | High RAM (machine_shape: "hm") |
| الإنترنت | مفعَّل لتنزيل النماذج من Hugging Face |
2.2 الملفات المطلوبة على Google Drive
MyDrive/
├── murshid_backend_for_drive.zip ← ملفات الباكند مضغوطة (44 KB)
│ أو
├── murshid_backend/ ← المجلد مستخرج مسبقاً
│ ├── app/
│ │ ├── main.py
│ │ ├── config.py
│ │ ├── api/routes/
│ │ ├── ml/
│ │ ├── models/
│ │ ├── services/
│ │ └── repositories/
│ ├── alembic/
│ ├── scripts/
│ ├── alembic.ini
│ └── requirements.txt
│
└── Needed/
├── murshid_logreg_pipeline_manual_oof_pcatuned.joblib ← نموذج LogReg
├── murshid_logreg_thresholds_manual_oof_pcatuned.npy ← عتبات التنبؤ
├── murshid_label_columns.json ← أسماء التقنيات الـ 20
└── murshid_query_template_structure_clean_shared.xlsx ← 60 قالب WQL
2.3 Hugging Face Token
مطلوب للوصول إلى نموذج meta-llama/Meta-Llama-3-8B-Instruct:
- يُضاف في
Colab SecretsباسمHF_TOKEN - أو مباشرةً في خلية 5 من الدفتر
3. شرح الخلايا بالتفصيل
الخلية 1: التحقق من GPU
الهدف: التأكد من وجود GPU قبل البدء.
import torch
print('CUDA available:', torch.cuda.is_available())
print('GPU:', torch.cuda.get_device_name(0))
print('Memory:', round(torch.cuda.get_device_properties(0).total_memory / 1e9, 1), 'GB')
المخرج المتوقع:
CUDA available: True
GPU: Tesla T4
Memory: 15.8 GB
ماذا يحدث إذا لم يكن هناك GPU؟
- LLaMA لن يُحمَّل (يحتاج CUDA)
- الخادم سيعمل بـ LOCAL mode فقط (بدون تلخيص)
الخلية 2: تحميل Google Drive والتحقق من الملفات
الهدف: ربط Colab بـ Google Drive والتحقق من وجود جميع الملفات المطلوبة.
from google.colab import drive
drive.mount('/content/drive')
NEEDED_PATH = '/content/drive/MyDrive/Needed'
BACKEND_PATH = '/content/drive/MyDrive/murshid_backend'
ZIP_PATH = '/content/drive/MyDrive/murshid_backend_for_drive.zip'
ما يتحقق منه:
| الملف | النوع | الحالة |
|---|---|---|
murshid_logreg_pipeline_manual_oof_pcatuned.joblib |
إلزامي | ✅ / ❌ |
murshid_logreg_thresholds_manual_oof_pcatuned.npy |
إلزامي | ✅ / ❌ |
murshid_label_columns.json |
إلزامي | ✅ / ❌ |
murshid_query_template_structure_clean_shared.xlsx |
اختياري | ✅ / ⚠️ |
murshid_backend/ أو .zip |
إلزامي | ✅ / ❌ |
الخلية 3: تجهيز الباكند في /content
الهدف: نقل ملفات الباكند من Drive إلى /content لتسريع القراءة (Drive أبطأ في I/O).
المنطق الذكي:
هل murshid_backend/ موجود على Drive؟
↓ نعم → انسخ مباشرةً إلى /content
↓ لا
هل murshid_backend_for_drive.zip موجود؟
↓ نعم → استخرجه إلى Drive أولاً ثم انسخ
↓ لا
→ ❌ خطأ: "ارفعي ZIP إلى Google Drive"
الخطوات المنفَّذة:
- استخراج ZIP (إذا لزم) إلى
MyDrive/ - نسخ
murshid_backend/إلى/content/murshid_backend/(بدون pycache وملفات مؤقتة) - إضافة
/content/murshid_backendإلىsys.path - تغيير working directory إلى
/content/murshid_backend
لماذا النسخ إلى /content؟
- Drive يعتمد على FUSE mount = بطيء للقراءة المتكررة
/contentعلى SSD محلي للـ VM = أسرع بـ 5-10x
الخلية 4: تثبيت المتطلبات
الهدف: تثبيت جميع المكتبات اللازمة لتشغيل الباكند.
المكتبات المثبَّتة:
| المكتبة | الإصدار | الغرض |
|---|---|---|
fastapi |
0.115.0 | إطار API |
uvicorn |
0.32.0 | خادم ASGI |
pydantic |
2.9.0 | تحقق من البيانات |
sqlalchemy |
2.0.0 | ORM |
alembic |
1.13.0 | هجرة DB |
scikit-learn |
1.6.1 | نموذج LogReg (يطابق بيئة التدريب) |
bitsandbytes |
≥0.46.1 | تكميم LLaMA 4-bit |
accelerate |
آخر نسخة | device_map="auto" للـ GPU |
openpyxl |
آخر نسخة | قراءة ملف Excel |
lxml |
آخر نسخة | معالجة XML |
pyngrok |
آخر نسخة | (احتياطي — غير مستخدم) |
ملاحظة مهمة:
scikit-learn==1.6.1محدَّد بدقة لأن ملفات joblib دُرِّبت بهذه النسخة — استخدام نسخة مختلفة يُنتج تحذيراتInconsistentVersionWarning.
الخلية 5: إعداد ملف .env
الهدف: إنشاء ملف الإعدادات لتشغيل FULL mode.
محتوى الملف المُولَّد:
MURSHID_DB_URL=sqlite:////content/murshid.db
MURSHID_MODELS_DIR=/content/drive/MyDrive/Needed
HF_TOKEN=****
MURSHID_SKIP_LLM=false ← مفتاح FULL mode
SECRET_KEY=murshid_colab_2026
LLAMA_MODEL_ID=meta-llama/Meta-Llama-3-8B-Instruct
EMBED_MODEL_ID=ehsanaghaei/SecureBERT_Plus
LOGREG_JOBLIB=murshid_logreg_pipeline_manual_oof_pcatuned.joblib
LOGREG_THRESHOLDS_NPY=murshid_logreg_thresholds_manual_oof_pcatuned.npy
LABEL_COLUMNS_JSON=murshid_label_columns.json
الفرق بين FULL و LOCAL mode:
| المتغير | FULL mode | LOCAL mode |
|---|---|---|
MURSHID_SKIP_LLM |
false |
true |
| LLaMA يُحمَّل؟ | ✅ نعم | ❌ لا |
| جودة التلخيص | عالية | الوصف الخام فقط |
| T1484 confidence (مثال) | 94.76% | 89.29% |
الخلية 6: تهجير قاعدة البيانات (Alembic)
الهدف: إنشاء جداول قاعدة البيانات SQLite.
python -m alembic upgrade head
الجداول المُنشأة (من migration 0001):
| الجدول | الغرض | مصدره في التقرير |
|---|---|---|
users |
مستخدمو النظام (admin/analyst) | ER Diagram §3.2.6 |
mapping_jobs |
وظائف معالجة ملفات القواعد | ER Diagram §3.2.6 |
rules |
قواعد Wazuh المُحلَّلة | ER Diagram §3.2.6 |
techniques |
تقنيات MITRE ATT&CK | ER Diagram §3.2.6 |
rule_technique_mappings |
ربط القواعد بالتقنيات + confidence | ER Diagram §3.2.6 |
query_templates |
قوالب WQL للتحقيق | ER Diagram §3.2.6 |
ملاحظة: قاعدة البيانات في
/content/murshid.db— تُنشأ من جديد في كل جلسة Colab.
الخلية 7: استيراد قوالب WQL من Excel
الهدف: تحميل 60 قالب WQL من ملف Excel إلى قاعدة البيانات.
البيانات المستوردة:
| الإحصائية | القيمة |
|---|---|
| إجمالي التقنيات | 20 تقنية |
| إجمالي القوالب | 60 قالب (3 لكل تقنية) |
| التقنيات المشمولة | T1047, T1055, T1059.001, T1070.004, T1078, T1083, T1095, T1098, T1105, T1110, T1112, T1114, T1176, T1190, T1484, T1498, T1499, T1529, T1531, T1562.001 |
مثال على قالب WQL (T1484):
Template 1: Host pivot
agent.name:${HOST} AND win.system.eventID:(4728 OR 4729 ...) AND @timestamp:[now-24h TO now]
Template 2: Actor pivot
win.eventdata.SubjectUserName:${USER} AND win.system.eventID:(...) AND @timestamp:[now-24h TO now]
Template 3: High-impact target change
win.system.eventID:(...) AND win.eventdata.TargetUserName:("Domain Admins" OR ...) AND @timestamp:[now-24h TO now]
منع التكرار:
- يتحقق من وجود (
technique_id+purpose) قبل الإضافة replace=Falseبشكل افتراضي (لا يُعيد الكتابة)
الخلية 8: تشغيل FastAPI + Cloudflare Tunnel
الهدف: الخلية الرئيسية — تُشغّل الباكند وتُنشئ رابطاً عاماً.
8.1 التحقق من bitsandbytes
import bitsandbytes as bnb
print(f'✅ bitsandbytes {bnb.__version__}')
إذا فشل: يُوقف التشغيل فوراً مع رسالة واضحة.
8.2 تشغيل uvicorn
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --log-level info
--host 0.0.0.0: يستمع على كل الواجهات (مطلوب للـ tunnel)- اللوج يُحفظ في
/content/murshid_server.log
8.3 تحميل النماذج (lifespan)
عند بدء الخادم تُنفَّذ load_models() بهذا الترتيب:
1. hf_login(token) ← 1-2 ثانية
2. LLaMA 3 8B-Instruct (4-bit NF4) ← 5-8 دقائق (4.5 GB)
- BitsAndBytesConfig: load_in_4bit=True
- bnb_4bit_quant_type="nf4"
- bnb_4bit_compute_dtype=float16
3. SecureBERT+ (ehsanaghaei) ← 1-2 دقيقة
- AutoModel + AutoTokenizer
- mean pooling 768-dim
4. LogisticRegressionModel ← < 1 ثانية
- joblib.load (Pipeline: PCA + OneVsRestClassifier)
- np.load thresholds
8.4 الانتظار الذكي
for i in range(180): # 15 دقيقة كحد أقصى
time.sleep(5)
# فحص /health كل 5 ثوانٍ
# عرض اللوج كل 30 ثانية
# كشف مبكر للأخطاء (ERROR, ImportError)
8.5 Cloudflare Tunnel
wget cloudflared-linux-amd64 → /usr/local/bin/cloudflared
cloudflared tunnel --url http://localhost:8000
- لا يحتاج حساباً أو توكناً
- يُنتج رابطاً مثل:
https://xxxx.trycloudflare.com - صالح طوال جلسة Colab
الخلية 9: ربط الفرونت تلقائياً
الهدف: تحديث index.html بالرابط الجديد من Cloudflare تلقائياً.
# استخراج الرابط
match = re.search(r'https://[a-z0-9\-]+\.trycloudflare\.com', content)
public_url = match.group(0)
# تحديث index.html على Drive
html = re.sub(
r"const BASE = '[^']*';",
f"const BASE = '{public_url}';",
html
)
النتيجة:
// قبل
const BASE = 'http://127.0.0.1:8000';
// بعد
const BASE = 'https://xxxx.trycloudflare.com';
الخلية 10: اختبار الـ API
الهدف: التحقق من عمل كل مكون.
10.1 Health Check
urllib.request.urlopen('http://localhost:8000/health')
المخرج المتوقع (FULL mode):
{
"pipeline_mode": "full",
"pipeline_description": "LLaMA + SecureBERT+ + LogReg",
"components": {
"llama_loaded": true,
"embedder_loaded": true,
"logreg_loaded": true,
"cuda_available": true
},
"all_model_files_present": true
}
10.2 تحليل قاعدة اختبار
rule_xml = '<rule id="18205" level="5">...'
POST http://localhost:8000/rules/analyze
الـ pipeline خطوة بخطوة:
XML Input (rule 18205)
↓
sanitize_rule_from_string()
- حذف: mitre, if_sid, group, if_group
↓
summarize_one_rule() [LLaMA]
- Input: sanitized XML
- Output: "Detects the deletion of a security-enabled global group on a Windows system."
↓
build_text_for_embedding()
- text = summary + ". " + description
- "Detects the deletion of a security-enabled global group on a Windows system. Windows: Security Enabled Global Group Deleted."
↓
SecureBERTEmbedder.embed_text()
- Chunks (256 tokens max)
- mean pooling per chunk
- average chunks → 768-dim vector
- L2 normalize
↓
LogisticRegressionModel.predict()
- predict_proba(X_user)
- pred = (proba >= logreg_thr)
- conf = proba * 100
- gap = proba - logreg_thr
↓
save_technique_mappings() [DB]
- حفظ 20 تقنية مع confidence
↓
JSON Response
المخرج للقاعدة 18205:
Technique Pred Conf% Proba Thr Gap
T1484 ✅ 94.76 0.9476 0.74 +0.2076 ← Primary
T1531 ❌ 27.92 0.2792 ... ...
T1070.004 ❌ 21.03 0.2103 ... ...
T1098 ❌ 10.65 0.1065 ... ...
T1112 ❌ 9.27 0.0927 ... ...
الخطوات القادمة للمود المحلي (lOCAL Mode) غير ضروريه
الخلية 11: تصدير النتائج (اختياري)
الهدف: تصدير نتائج القواعد المُحلَّلة إلى JSON لاستخدامها لاحقاً على الجهاز المحلي.
export_path = f'{NEEDED_PATH}/murshid_full_results.json'
json.dump(export_results, f, ensure_ascii=False, indent=2)
الاستخدام: يُمكِّن استيراد نتائج FULL mode في الباكند المحلي بدون GPU.
الخلية 12: إيقاف الخادم
cf_proc.terminate() # إغلاق Cloudflare tunnel
server_proc.terminate() # إيقاف uvicorn
4. مقارنة أوضاع التشغيل
| FULL mode (Colab) | LOCAL mode (الجهاز) | LITE mode | |
|---|---|---|---|
| LLaMA | ✅ | ❌ | ❌ |
| SecureBERT+ | ✅ | ✅ | ❌ |
| LogReg | ✅ | ✅ | ✅ |
| GPU | Tesla T4 | لا يلزم | لا يلزم |
| Embedding | نص مُثرى بـ LLaMA | وصف القاعدة فقط | عشوائي |
| T1484 confidence | 94.76% | 89.29% | غير موثوق |
| القرار النهائي | T1484 ✅ | T1484 ✅ | غير موثوق |
| وقت التحليل/قاعدة | ~30-60 ثانية | ~2-5 ثوانٍ | < 1 ثانية |
| الاستخدام | إنتاج / عرض | تطوير محلي | اختبار فقط |
5. معمارية النظام الكاملة على Colab
┌─────────────────────────────────────────────────────┐
│ Google Colab VM │
│ │
│ ┌─────────────────────────────────┐ │
│ │ /content/murshid_backend/ │ │
│ │ │ │
│ │ FastAPI (uvicorn :8000) │ │
│ │ ├── /health │ │
│ │ ├── POST /rules/analyze │ │
│ │ ├── GET /results/{rule_id} │ │
│ │ ├── GET /queries/{tech_id} │ │
│ │ └── GET /api/db/... │ │
│ └───────────────┬─────────────────┘ │
│ │ │
│ ┌───────────────┴───────────┐ │
│ │ ML Models (GPU VRAM) │ │
│ │ ├── LLaMA 3 8B (4-bit) │ │
│ │ ├── SecureBERT+ │ │
│ │ └── LogReg Pipeline │ │
│ └───────────────────────────┘ │
│ │ │
│ ┌───────────────┴───────────┐ │
│ │ /content/murshid.db │ │
│ │ (SQLite — 6 جداول) │ │
│ └───────────────────────────┘ │
│ │
│ ┌───────────────────────────┐ │
│ │ cloudflared tunnel │ │
│ │ localhost:8000 → HTTPS │ │
│ └───────────────┬───────────┘ │
└──────────────────┼──────────────────────────────────┘
│
▼
https://xxxx.trycloudflare.com
│
▼
┌─────────────────────────┐
│ المتصفح / الفرونت │
│ index.html (React) │
└─────────────────────────┘
6. الأخطاء الشائعة وحلولها
| الخطأ | السبب | الحل |
|---|---|---|
ImportError: bitsandbytes>=0.46.1 |
نسخة قديمة | شغّلي !pip install -U bitsandbytes>=0.46.1 |
FileNotFoundError: murshid_backend |
ZIP غير مرفوع | ارفعي murshid_backend_for_drive.zip إلى Drive |
ERR_NGROK_4018 |
ngrok يحتاج حساباً | استخدمي Cloudflare Tunnel (خلية 9) |
Cannot connect to backend |
CORS مغلق | allow_origins=["*"] في main.py |
| Server يستغرق > 15 دقيقة | تنزيل LLaMA بطيء | في الجلسة الثانية التنزيل من Cache |
InconsistentVersionWarning |
sklearn إصدار مختلف | تأكدي من scikit-learn==1.6.1 |
7. الـ Endpoints المتاحة بعد التشغيل
| Method | Endpoint | الوصف |
|---|---|---|
GET |
/health |
حالة الخادم والنماذج |
GET |
/api/stats |
إحصائيات Dashboard |
GET |
/api/db/summary |
عدد الصفوف في الجداول |
GET |
/api/db/rules |
جميع القواعد في DB |
GET |
/api/db/mappings |
جميع المطابقات |
GET |
/api/db/techniques |
تقنيات MITRE المخزّنة |
GET |
/api/db/templates |
قوالب WQL |
POST |
/api/db/import-excel |
استيراد Excel |
POST |
/rules/analyze |
تحليل قاعدة XML (FULL pipeline) |
GET |
/results/{rule_id} |
نتائج تقنية قاعدة محددة |
GET |
/queries/{technique_id} |
استعلامات WQL لتقنية |
POST |
/admin/templates |
إضافة قالب WQL |
PATCH |
/admin/templates/{id} |
تعديل قالب |
GET |
/docs |
Swagger UI التفاعلي |
8. ملاحظات للعرض التقديمي
- شغّلي الخلايا قبل العرض بـ 15 دقيقة (وقت تحميل LLaMA)
- انسخي رابط Cloudflare وتحققي منه في المتصفح
- الفرونت يُحدَّث تلقائياً بالرابط الجديد في خلية 9
- كل جلسة Colab جديدة = رابط Cloudflare جديد — كرّري الخطوات
- DB فارغة في كل جلسة — حلّلي القواعد عبر Admin Panel أو خلية اختبار
تاريخ الإنشاء: 8 أبريل 2026 | مشروع مُرشِد — CCIS, PNU