الرئيسيةمن أناالدوراتالمدونةسوق الأوامرالمناهج والباقاتالشركاء

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • المناهج والباقات
  • سوق الأوامر
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالمناهجالمدونةالدخول
DevOps بالعربي

ليه تشغيل حاوية Docker كـ root خطر، وإزاي تشغّلها كمستخدم عادي

مبتدئ5 أغسطس 20264 دقائق قراءة
ليه تشغيل حاوية Docker كـ root خطر، وإزاي تشغّلها كمستخدم عادي

المستوى: مبتدئ. الكلام ده موجّه لأي حد بيبني صورة Docker بنفسه وينشرها، حتى لو لسه في أول الطريق مع الحاويات.

لو الحاوية بتاعتك بتشتغل كـ root — وده الوضع الافتراضي في أغلب الصور — يبقي ثغرة واحدة في تطبيقك ممكن تتحوّل لسيطرة على السيرفر كله. سطرين في الـ Dockerfile بيقفلوا الباب ده. تعال نشوف إزاي.

صفوف خوادم في مركز بيانات ترمز لتشغيل الحاويات بأقل صلاحية على المضيف

المشكلة باختصار

لما تكتب Dockerfile عادي وتبنيه، العملية جوّه الحاوية بتشتغل بصلاحية root (المستخدم رقم صفر) طول ما إنت مقلتش غير كده. الافتراض الشائع إن الحاوية "معزولة" فمفيش مشكلة. الافتراض ده ناقص.

الحاوية مش جهاز افتراضي منفصل. هي عملية بتشتغل على نواة (kernel) المضيف نفسه. يعني root جوّه الحاوية هو نفس root بتاع النواة بتاعت السيرفر، والفرق بينهم مجرد طبقة عزل رفيعة ممكن تتخرق.

مثال يقرّب الفكرة

تخيّل إن الحاوية شقة في عمارة. لو الساكن ماسك مفتاح العمارة الرئيسي (root)، فأي حرامي يقدر يضحك عليه هيقدر يفتح كل الشقق ومكتب البواب كمان. لكن لو الساكن ماسك مفتاح شقته هو بس (مستخدم عادي)، الحرامي هيفضل محبوس جوّه الشقة، مش هيوصل لباقي العمارة.

علميًا: لو مهاجم استغل ثغرة في تطبيقك وهو شغّال كـ root، بيبقى معاه صلاحية كاملة جوّه الحاوية، وبقى محتاج بس ثغرة "هروب" واحدة من الحاوية عشان يبقى root على المضيف. ده مش كلام نظري: ثغرة runc الشهيرة CVE-2019-5736 سمحت لحاوية شغّالة كـ root بالكتابة فوق ملف runc على المضيف والسيطرة عليه. لو الحاوية كانت شغّالة كمستخدم عادي، الهجوم ده كان بيفشل.

حاويات شحن معدنية متراصة كتشبيه لعزل حاويات Docker وحصر صلاحياتها

الحل: سطرين في الـ Dockerfile

المبدأ اسمه الأقل امتيازًا (Least Privilege): أعطِ العملية أقل صلاحية تكفي لشغلها بس. تطبيقه في Docker حرفيًا سطرين.

Dockerfile
FROM node:20-slim

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .

# 1) اعمل مستخدم عادي بدون صلاحيات
RUN useradd --system --uid 1000 appuser

# 2) خلّي ده هو المستخدم الافتراضي للحاوية
USER appuser

EXPOSE 8080
CMD ["node", "server.js"]

ملاحظة عملية: أغلب الصور الرسمية (زي node) بتيجي أصلاً بمستخدم غير جذري جاهز اسمه node بالرقم 1000، فتقدر تكتب USER node على طول بدون ما تعمل مستخدم جديد.

وفي Kubernetes كمان

حتى لو الصورة نفسها فيها USER، فرض القاعدة على مستوى الكلاستر بيمنع أي صورة تتزحلق كـ root:

YAML
spec:
  securityContext:
    runAsNonRoot: true     # ارفض تشغيل الحاوية لو هتشتغل كـ root
    runAsUser: 1000
    runAsGroup: 1000
  containers:
    - name: web
      image: myapp:1.0
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop: ["ALL"]    # اشيل كل الصلاحيات الزيادة

التحقق إنه شغّال

أمر واحد بيقولك المستخدم الحقيقي جوّه الحاوية:

Bash
# اطبع هوية المستخدم داخل الحاوية
docker run --rm myapp:1.0 id

# المطلوب:  uid=1000(appuser) gid=1000(appuser)
# الخطر:    uid=0(root)   ← لو طلعت كده، لسه شغّال كـ root

لو رقم الـ uid مش صفر، يبقي إنت قفلت الباب فعلاً.

الـ trade-offs وحاجات تنتبه لها

القرار ده مش ببلاش، بس ثمنه رخيص:

  • الأداء: الفرق في السرعة بين root ومستخدم عادي = صفر تقريبًا. مبتخسرش أداء.
  • المنافذ أقل من 1024: المستخدم العادي مش هيقدر يبايند مباشرة على منفذ زي 80 أو 443. الحل: خلّي تطبيقك يسمع على 8080، وسيب الـ reverse proxy (زي NGINX) أو الـ Service ياخد المنفذ 80.
  • ملكية الملفات: لو التطبيق بيكتب في مجلد أو volume، لازم يكون مملوك للـ UID 1000، وإلا هتاخد خطأ Permission denied. اضبط الملكية بـ chown في مرحلة البناء.

الخلاصة: بتكسب عزل أمني حقيقي وحصر لأي اختراق، مقابل ضبط بسيط للمنافذ والملكية مرة واحدة.

متى ما تستخدمش الطريقة دي

في حالات نادرة العملية محتاجة صلاحية جذر فعلية: زي حاوية بتعمل مراقبة على مستوى النواة، أو أداة شبكات محتاجة capabilities معيّنة، أو صورة أساس قديمة بتكسر لو غيّرت المستخدم. هنا متشغّلش كـ root وخلاص، لكن أعطِ الصلاحية المحددة اللي محتاجها بس عبر capabilities.add، وسيب باقي الصلاحيات مقفولة.

الخطوة التالية

افتح أحدث Dockerfile عندك دلوقتي، وشوف فيه سطر USER ولا لأ. لو مش موجود، ضيف USER 1000 قبل الـ CMD، اعِد البناء، وشغّل docker run --rm your-image id. لو طلع uid=0 لسه، يبقي فيه سطر تاني بيرجّعك لـ root — دوّر عليه وشيله.

المصادر

  • Docker Docs — تعليمة USER في الـ Dockerfile: docs.docker.com/reference/dockerfile/#user
  • Docker Docs — أفضل ممارسات بناء الصور: docs.docker.com/build/building/best-practices
  • Kubernetes Docs — ضبط Security Context (runAsNonRoot / runAsUser): kubernetes.io/docs/tasks/configure-pod-container/security-context
  • NVD — CVE-2019-5736 (هروب من حاوية عبر runc): nvd.nist.gov/vuln/detail/CVE-2019-5736
  • NIST SP 800-190 — دليل أمن الحاويات: csrc.nist.gov/pubs/sp/800/190/final
  • OWASP — Docker Security Cheat Sheet: cheatsheetseries.owasp.org

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة