تمرين 2 – إدارة مواقع ويب متعددة باستخدام reverse proxy (وكيل عكسي) في بيئة Linux
جدول المحتويات
- السياق
- أهداف الاختبار
- التعليمات العامة
- الجزء 1 – تثبيت وتكوين Wiki.js
- الجزء 2 – تكوين reverse proxy NGINX
- الجزء 3 – التحقق، استكشاف الأخطاء وإصلاحها والتحليل
- الجزء 4 – سؤال التحليل المعماري
- جدول التقييم
- الوحدة الإضافية 1 – مستخدمو النظام مقابل المستخدمين العاديين
السياق
أنت مسؤول نظام في شركة خدمات رقمية. مهمتك هي تكوين بيئة محلية تستضيف ثلاثة مثيلات مستقلة من Wiki.js، كل منها يمثل بيئة تطوير برمجيات كلاسيكية:
- بيئة التطوير (
dev.site1.local) - بيئة الاختبار (
test.site1.local) - بيئة الإنتاج (
prod.site1.local)
يجب تثبيت كل مثيل من Wiki.js يدويًا على جهاز واحد يعمل بنظام Ubuntu Server 24.04 LTS، متصل بقاعدة بيانات MariaDB الخاصة به ومكشوف عبر reverse proxy NGINX.
أهداف الاختبار
- إتقان التثبيت اليدوي لمحرك wiki قائم على Node.js
- إدارة قواعد بيانات SQL منفصلة بشكل صحيح
- أتمتة بدء الخدمات عبر
systemd - تكوين reverse proxy HTTP مع نطاقات فرعية داخلية
- تشخيص أخطاء النشر الشائعة
- تطبيق أفضل الممارسات في مجال عزل الخدمة
التعليمات العامة
- تعمل على جهاز افتراضي واحد يعمل بنظام Ubuntu 24.04
- يجب أن تكون جميع المثيلات مستقلة، بدون تعارض في المنافذ
- لا يجب أن يكون أي خادم مكشوفًا مباشرة: فقط الوكيل NGINX يستمع على المنفذ 80
- يجب أن تعمل العناوين
*.site1.localعبر/etc/hosts - يجب عليك اتباع نهج احترافي، مع هيكلية ووضوح ودقة
الجزء 1 – تثبيت وتكوين WIKI.JS (40 نقطة)
-
أنشئ ثلاثة مستخدمين مخصصين في Linux:
wikijs_dev,wikijs_test,wikijs_prod -
أنشئ ثلاث قواعد بيانات منفصلة تحت MariaDB:
wikidb_dev,wikidb_test,wikidb_prod
-
قم بتثبيت Wiki.js يدويًا في:
/var/www/dev.site1/var/www/test.site1/var/www/prod.site1
-
عدل ملف
config.ymlلكل مثيل:- منفذ مختلف (
3000,3001,3002) bindIP: 127.0.0.1- معلومات اتصال صحيحة بقاعدة البيانات
- منفذ مختلف (
-
أنشئ وفعّل خدمات systemd:
wikijs-dev.service,wikijs-test.service,wikijs-prod.service
الجزء 2 – تكوين REVERSE PROXY NGINX (30 نقطة)
- قم بتكوين NGINX لخدمة النطاقات الفرعية التالية:
| اسم المضيف | المنفذ الداخلي | المسار المحلي |
|---|---|---|
| dev.site1.local | 3000 | /var/www/dev.site1 |
| test.site1.local | 3001 | /var/www/test.site1 |
| prod.site1.local | 3002 | /var/www/prod.site1 |
-
عدل
/etc/hostsلتوجيه هذه النطاقات إلى127.0.0.1 -
اختبر الوصول إلى المواقع باستخدام متصفح أو
curl
الجزء 3 – التحقق، استكشاف الأخطاء وإصلاحها والتحليل (30 نقطة)
-
صحح الأخطاء التالية إذا ظهرت:
- سوء تنسيق YAML
- مشاكل اتصال MariaDB
- منفذ مشغول بالفعل
- حقوق ملفات غير كافية
-
برر القرارات التالية:
- لماذا تستخدم مستخدمين مختلفين لكل Wiki.js؟
- لماذا تفضل reverse proxy بدلاً من التعرض المباشر؟
- ما هي مخاطر الأمان إذا تم كشف المنافذ بدون NGINX؟
-
اقترح طريقة لتأمين التثبيت باستخدام HTTPS:
- استخدام
certbot - تكوين
bindIP - دور DNS العام
- استخدام
الجزء 4 – سؤال التحليل المعماري (10 نقاط)
البيان
هناك نهجان ممكنان لكشف عدة بيئات:
النهج A :
نطاقات فرعية
→ http://dev.site1.local, http://test.site1.local, http://prod.site1.local
النهج B :
مسارات داخلية
→ http://site1.local/dev, http://site1.local/test, http://site1.local/prod
السؤال
-
قارن بين النهجين:
a) الآثار التقنية الرئيسية (4 نقاط) b) حالات الاستخدام حيث يكون النهج B مقبولًا، ومتى يكون غير مستحسن (3 نقاط) c) أي نهج توصي به ولماذا؟ (3 نقاط)
جدول التقييم
| المعايير | النقاط |
|---|---|
| Wiki.js (x3) مثبت ويعمل | 15 |
| قواعد بيانات منفصلة | 10 |
تكوين config.yml صحيح | 10 |
خدمات systemd تعمل | 5 |
| تم تكوين NGINX reverse proxy | 15 |
/etc/hosts محرر بشكل صحيح | 5 |
| تشخيص وحل الأخطاء | 10 |
| تبرير تقني | 10 |
| اقتراح HTTPS مدعوم | 10 |
| المجموع | 90 |
| تحليل الهيكلية | النقاط |
|---|---|
| عرض الفروقات | 2 |
| حالات الاستخدام لكل نهج | 2 |
| تحليل المخاطر والتوافق | 2 |
| توصية واضحة ومدعومة | 4 |
| المجموع الفرعي | 10 |
الوحدة الإضافية 1 – مستخدمو النظام مقابل المستخدمين العاديين (البشريين) على Linux
اتفاقية UID على Linux
في معظم توزيعات Linux الحديثة، يتم تصنيف المستخدمين وفقًا لـ UID (معرف المستخدم):
| نطاق UID | نوع الحساب | أمثلة |
|---|---|---|
| 0 | المستخدم الجذر | root |
| 1 – 999 | حسابات النظام / الخدمات | daemon, www-data, sshd, systemd-*, apache |
| ≥ 1000 | مستخدمون عاديون (بشريون) | alice, bob, etudiant |
يتم تحديد هذا النطاق في ملف /etc/login.defs لتوزيعتك. ليست قاعدة عالمية، ولكنها اتفاقية معتمدة على نطاق واسع (Debian, Ubuntu, RHEL, Fedora, إلخ).
كيفية التحقق من النطاقات على جهازك
# عرض نطاقات UID المحددة على توزيعتك
grep -E '^(UID_MIN|UID_MAX|SYS_UID_MIN|SYS_UID_MAX)' /etc/login.defs
نتيجة نموذجية على Ubuntu:
SYS_UID_MIN 100
SYS_UID_MAX 999
UID_MIN 1000
UID_MAX 60000
حسابات النظام (UID < 1000) – الخصائص
تم إنشاء حسابات النظام لتشغيل الخدمات/الشياطين، وليس للاتصالات البشرية.
المؤشرات النموذجية لحساب النظام:
- UID منخفض (< 1000)
- Shell =
/usr/sbin/nologinأو/bin/false(لا يوجد اتصال تفاعلي) - لا يوجد مجلد home حقيقي للمستخدم (أو home "تقني")
- تم إنشاؤه باستخدام
useradd -r(علامة حساب النظام)
أمثلة شائعة:
| الحساب | الخدمة | UID نموذجي | Shell |
|---|---|---|---|
root | المستخدم الجذر | 0 | /bin/bash |
www-data | Apache / Nginx (Debian/Ubuntu) | 33 | /usr/sbin/nologin |
apache | Apache (RHEL/CentOS) | 48 | /sbin/nologin |
sshd | خادم SSH | 105 | /usr/sbin/nologin |
mysql | MariaDB / MySQL | 27 | /bin/false |
تحقق سريع:
# عرض UID و shell لـ www-data
id www-data
getent passwd www-data
# النتيجة: uid=33(www-data) gid=33(www-data) groups=33(www-data)
حسابات عادية / بشرية (UID ≥ 1000) – الخصائص
تم إنشاء الحسابات البشرية للأشخاص الذين يتصلون بالنظام.
المؤشرات النموذجية لحساب بشري:
- UID ≥ 1000
- Shell =
/bin/bashأو/bin/sh - مجلد home في
/home/<username> - تم إنشاؤه باستخدام
useradd(بدون العلم-r) أوadduser
أوامر مفيدة لقائمة وتمييز أنواع المستخدمين
قائمة المستخدمين البشريين (UID ≥ 1000):
UID_MIN=$(awk '/^UID_MIN/{print $2}' /etc/login.defs)
awk -F: -v m="$UID_MIN" '$3>=m {print $1" (uid="$3")"}' /etc/passwd | sort -t'=' -k2 -n
قائمة المستخدمين النظاميين (UID < 1000):
UID_MIN=$(awk '/^UID_MIN/{print $2}' /etc/login.defs)
awk -F: -v m="$UID_MIN" '$3<m {print $1" (uid="$3")"}' /etc/passwd | sort -t'=' -k2 -n
قائمة الحسابات بدون تسجيل دخول (عادةً للخدمات):
awk -F: '($7 ~ /(nologin|false)$/) {print $1" -> "$7}' /etc/passwd
قائمة الحسابات "البشرية المحتملة" (home في /home + shell bash/sh):
awk -F: '($6 ~ /^\/home\//) && ($7 ~ /(bash|sh)$/) {print $1" home="$6" shell="$7}' /etc/passwd
الرابط مع التمرين: لماذا wikijs_dev, wikijs_test, wikijs_prod هي حسابات نظام؟
في هذا التمرين، تم إنشاء مستخدمي Wiki.js باستخدام الأمر:
sudo useradd -r -m -s /bin/bash wikijs_dev
sudo useradd -r -m -s /bin/bash wikijs_test
sudo useradd -r -m -s /bin/bash wikijs_prod
| الخيار | الدور |
|---|---|
-r | ينشئ حساب نظام → UID مخصص في النطاق النظامي (< 1000) |
-m | ينشئ دليل home (مفيد لملفات التكوين) |
-s /bin/bash | يحدد shell (هنا bash لتسهيل التصحيح في التمرين) |
إنه العلم -r الذي يحدث الفرق! بدون -r، سيكون الحساب مستخدمًا عاديًا (UID ≥ 1000). العلم -s يحدد فقط shell، ولا يجعل الحساب "نظاميًا".
هذه الحسابات هي "حسابات خدمة": هي مسؤولة عن تشغيل خدمات Wiki.js، كما هو محدد في ملفات systemd:
[Service]
User=wikijs_dev # ← الخدمة تعمل تحت هذا الحساب النظامي
تحقق:
# عرض UID المخصص (يجب أن يكون < 1000)
id wikijs_dev
id wikijs_test
id wikijs_prod
# عرض المستخدم الذي يشغل كل عملية Wiki.js
ps -eo user,pid,cmd | grep '[n]ode'
# تحقق من حالة الخدمة
systemctl status wikijs-dev
توصية في الإنتاج
في الإنتاج، من الأفضل عدم إعطاء shell تفاعلي لحسابات الخدمة:
# أفضل ممارسة (shell nologin)
sudo useradd -r -m -s /usr/sbin/nologin wikijs_dev
sudo useradd -r -m -s /usr/sbin/nologin wikijs_test
sudo useradd -r -m -s /usr/sbin/nologin wikijs_prod
مع /usr/sbin/nologin، لا يمكن لأحد فتح جلسة تفاعلية مع هذا الحساب، ولكن systemd و sudo -u wikijs_dev <command> يعملان بشكل طبيعي. هذا هو مبدأ الأقل امتيازًا.
useradd -r→ حساب نظام (UID < 1000، مخصص لخدمة)useradd(بدون-r) → حساب بشري (UID ≥ 1000، مخصص لشخص)-s→ يحدد shell، لا يغير نوع الحساب- حسابات
wikijs_*في هذا التمرين هي حسابات نظام مسؤولة عن تشغيل خدمة Wiki.js - في الإنتاج: استخدم دائمًا
-s /usr/sbin/nologinلحسابات الخدمة
تم إنشاء التمرين في: ديسمبر 2024