murshid / MurshidBackend_Colab_Report.md
devorbit's picture
Initial deployment - secrets removed
26e1c2e

تقرير تقني: آلية عمل 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"

الخطوات المنفَّذة:

  1. استخراج ZIP (إذا لزم) إلى MyDrive/
  2. نسخ murshid_backend/ إلى /content/murshid_backend/ (بدون pycache وملفات مؤقتة)
  3. إضافة /content/murshid_backend إلى sys.path
  4. تغيير 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. ملاحظات للعرض التقديمي

  1. شغّلي الخلايا قبل العرض بـ 15 دقيقة (وقت تحميل LLaMA)
  2. انسخي رابط Cloudflare وتحققي منه في المتصفح
  3. الفرونت يُحدَّث تلقائياً بالرابط الجديد في خلية 9
  4. كل جلسة Colab جديدة = رابط Cloudflare جديد — كرّري الخطوات
  5. DB فارغة في كل جلسة — حلّلي القواعد عبر Admin Panel أو خلية اختبار

تاريخ الإنشاء: 8 أبريل 2026 | مشروع مُرشِد — CCIS, PNU