# تقرير تقني: آلية عمل 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 قبل البدء. ```python 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 والتحقق من وجود جميع الملفات المطلوبة. ```python 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. **محتوى الملف المُولَّد:** ```env 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. ```bash 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 ```python import bitsandbytes as bnb print(f'✅ bitsandbytes {bnb.__version__}') ``` > إذا فشل: يُوقف التشغيل فوراً مع رسالة واضحة. #### 8.2 تشغيل uvicorn ```bash 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 الانتظار الذكي ```python for i in range(180): # 15 دقيقة كحد أقصى time.sleep(5) # فحص /health كل 5 ثوانٍ # عرض اللوج كل 30 ثانية # كشف مبكر للأخطاء (ERROR, ImportError) ``` #### 8.5 Cloudflare Tunnel ```bash wget cloudflared-linux-amd64 → /usr/local/bin/cloudflared cloudflared tunnel --url http://localhost:8000 ``` - لا يحتاج حساباً أو توكناً - يُنتج رابطاً مثل: `https://xxxx.trycloudflare.com` - صالح طوال جلسة Colab --- ### الخلية 9: ربط الفرونت تلقائياً **الهدف:** تحديث `index.html` بالرابط الجديد من Cloudflare تلقائياً. ```python # استخراج الرابط 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 ) ``` **النتيجة:** ```javascript // قبل const BASE = 'http://127.0.0.1:8000'; // بعد const BASE = 'https://xxxx.trycloudflare.com'; ``` --- ### الخلية 10: اختبار الـ API **الهدف:** التحقق من عمل كل مكون. #### 10.1 Health Check ```python urllib.request.urlopen('http://localhost:8000/health') ``` **المخرج المتوقع (FULL mode):** ```json { "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 تحليل قاعدة اختبار ```python rule_xml = '...' 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 لاستخدامها لاحقاً على الجهاز المحلي. ```python export_path = f'{NEEDED_PATH}/murshid_full_results.json' json.dump(export_results, f, ensure_ascii=False, indent=2) ``` **الاستخدام:** يُمكِّن استيراد نتائج FULL mode في الباكند المحلي بدون GPU. --- ### الخلية 12: إيقاف الخادم ```python 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*