المدونة

الدفاع ضد هروب الحاويات: دليل عملي لعزل Docker للاستضافة متعددة المستأجرين

تعرف على كيفية تأمين حاويات Docker ضد ثغرات الهروب وفشل العزل في البيئات متعددة المستأجرين بخطوات وأمثلة ملموسة.

ملخص

تتشارك حاويات Docker نواة المضيف، مما يجعل العزل أمرًا بالغ الأهمية - خاصة في الاستضافة متعددة المستأجرين حيث يمكن لهروب حاوية واحدة أن يعرض جميع المستأجرين للخطر. يفترض العديد من المطورين أن الحاويات هي آلات افتراضية معزولة تمامًا، لكن الواقع مختلف. تشرح هذه المقالة ميزات نواة Linux التي تدعم عزل Docker (المساحات الاسمية، مجموعات التحكم) ومتجهات الهجوم التي تهددها. ستتعلم خطوات عملية لتقوية إعداد Docker الخاص بك: تقييد الامتيازات، استخدام وقت تشغيل آمن، فحص الصور، وتنفيذ تجزئة الشبكة. من خلال اتباع مثال واقعي لموفر استضافة WordPress متعدد المستأجرين، سترى كيفية تطبيق هذه الدفاعات. نغطي أيضًا التحذيرات مثل المفاضلات في الأداء واستخدام seccomp/AppArmor. الهدف هو تزويدك باستراتيجية عزل قوية تمنع هروب الحاويات وتحافظ على سلامة المستأجرين.

مقدمة

إذا كنت تدير منصة استضافة متعددة المستأجرين - سواء كانت استضافة WordPress مشتركة، أو تطبيق SaaS، أو خدمة بيئة تطوير - فإن هروب الحاويات هو السيناريو الكابوسي. يمكن لثغرة أمنية في النواة أو تكوين خاطئ أن تسمح لمستأجر واحد بالخروج من حاويته والوصول إلى بيانات مستأجرين آخرين أو المضيف نفسه. يعتمد عزل Docker على ميزات نواة Linux مثل المساحات الاسمية ومجموعات التحكم، ولكن التكوينات الجاهزة غالبًا ما تكون غير كافية للأمان القوي. ستأخذك هذه المقالة عبر متجهات الهجوم وتقدم خطوات قابلة للتنفيذ لتأمين حاويات Docker الخاصة بك، مع توضيحها بمثال واقعي لـ WordPress متعدد المستأجرين. للحصول على نظرة أوسع على تنسيق الإنتاج، راجع دليلنا حول تنسيق التطبيقات المعبأة الجاهزة للإنتاج.

فهم عزل Docker

تستخدم حاويات Docker مساحات أسماء Linux لتوفير عزل على مستوى العمليات: تفصل مساحات أسماء PID أشجار العمليات، وتفصل مساحات أسماء الشبكة واجهات الشبكة، وتعزل مساحات أسماء نظام الملفات نقاط التحميل، وتسمح مساحات أسماء المستخدمين بتعيين جذر الحاوية إلى مستخدم مضيف غير مميز. تحد مجموعات التحكم (cgroups) من استخدام الموارد مثل وحدة المعالجة المركزية والذاكرة وإدخال/إخراج القرص. تخلق هذه الميزات معًا "صندوقًا رمليًا" حول كل حاوية. ومع ذلك، على عكس الجهاز الافتراضي الذي يشغل نواة منفصلة، تتشارك الحاويات نواة المضيف. هذا يعني أن ثغرة أمنية في النواة (مثل CVE-2022-0492) يمكن استغلالها للخروج من عزل مساحة اسم الحاوية. بالإضافة إلى ذلك، فإن التكوينات الخاطئة مثل تشغيل الحاويات كـ root داخل الحاوية، ومنح الحاوية جميع القدرات، أو عدم إسقاط القدرات غير الضرورية في Linux يمكن أن توسع سطح الهجوم.

متجهات الهجوم

تشمل متجهات الهجوم الشائعة:

  • استغلالات النواة: استغلال خطأ في نواة المضيف للحصول على وصول المضيف.
  • الحاويات المميزة: التشغيل مع --privileged يمنح جميع القدرات ويتجاوز معظم العزل.
  • إساءة استخدام القدرات: حتى بدون وضع مميز كامل، يمكن للحاوية ذات القدرات الخطيرة مثل CAP_SYS_ADMIN أو CAP_NET_ADMIN تحميل أنظمة الملفات أو معالجة إعدادات الشبكة.
  • ممارسات الصور غير الآمنة: استخدام صور أساسية بها ثغرات أمنية معروفة أو تضمين أدوات غير ضرورية مثل المترجمات أو مفسرات shell.
  • مساحات أسماء التحميل المشتركة: تحميل أدلة المضيف في الحاويات يمكن أن يسمح بالهروب إذا لم تكن للقراءة فقط.

خطوات الأمان العملية

1. تشغيل الحاويات كمستخدم غير Root

افتراضيًا، يقوم Docker بتشغيل الحاويات كـ root داخل الحاوية. إذا حصل المهاجم على صلاحيات root داخل الحاوية، فلديه المزيد من النفوذ. أنشئ مستخدمًا في Dockerfile الخاص بك واستخدم التوجيه USER. أيضًا، تجنب استخدام علامة --user في Docker Compose لتعيين مستخدم مضيف عشوائي إن أمكن.

2. إسقاط جميع القدرات وإضافة المطلوبة فقط

تقوم قدرات Linux بتقسيم امتيازات المستخدم الخارق إلى وحدات أصغر. في Docker Compose، استخدم cap_drop: ALL ثم cap_add فقط المطلوبة (مثل NET_BIND_SERVICE). تجنب القدرات الخطيرة مثل SYS_ADMIN و NET_ADMIN و SYS_PTRACE.

3. استخدام نظام ملفات Root للقراءة فقط

قم بتعيين read_only: true في تعريف الحاوية الخاص بك. هذا يمنع المهاجمين من الكتابة إلى نظام ملفات الحاوية. إذا كان تطبيقك يحتاج إلى كتابة ملفات مؤقتة، فقم بتحميل وحدة تخزين tmpfs في هذا الموقع.

4. تمكين إعادة تعيين مساحة اسم المستخدم

تقوم إعادة تعيين مساحة اسم المستخدم بتعيين مستخدم root للحاوية إلى مستخدم مضيف غير مميز. هذا يضيف طبقة من العزل، لأنه حتى لو خرج مستخدم root للحاوية، فسيكون لديه امتيازات المستخدم المعاد تعيينه. قم بتمكينه في /etc/docker/daemon.json باستخدام "userns-remap": "default". كن على علم بأن هذا يمكن أن يعقد أذونات وحدة التخزين. لمزيد من التفاصيل، راجع إتقان عزل Docker لاستضافة الويب الآمنة والفعالة.

5. تطبيق Seccomp و AppArmor/ملفات تعريف AppArmor

يقيد Seccomp استدعاءات النظام التي يمكن للحاوية إجراؤها. يوفر Docker ملف تعريف seccomp افتراضيًا يحظر استدعاءات النظام الخطيرة. يمكنك أيضًا إنشاء ملفات تعريف مخصصة. وبالمثل، يوفر AppArmor (أو SELinux) التحكم الإلزامي في الوصول. استخدم AppArmor لحصر حاويتك في الحد الأدنى من العمليات المسموح بها. يمكن تعيين ملف تعريف الأمان عبر security_opt في Docker Compose.

6. استخدام صور أساسية بسيطة وفحص الثغرات الأمنية

اختر صورًا صغيرة مثل Alpine أو Distroless التي لديها سطح هجوم أصغر. قم بفحص الصور بانتظام باستخدام أدوات مثل Docker Scout أو Trivy أو Clair. قم بدمج الفحص في خط أنابيب CI/CD الخاص بك لمنع نشر الصور الضعيفة.

7. تجزئة الشبكة باستخدام شبكات Bridge مخصصة

قم بإنشاء شبكات bridge منفصلة لكل مستأجر أو طبقة تطبيق. هذا يحد من حركة المرور من الشرق إلى الغرب. في Docker Compose، قم بتعريف الشبكات وعزل الخدمات. استخدم internal: true إذا كانت الخدمة لا تحتاج إلى الوصول إلى الإنترنت الصادر. قواعد جدار الحماية على المضيف تقيد حركة المرور بين الحاويات بشكل أكبر.

8. تحديد الموارد باستخدام Cgroups

قم بتعيين حدود وحدة المعالجة المركزية والذاكرة في Docker Compose باستخدام deploy.resources.limits. هذا يمنع الحاوية المخترقة من شن هجوم استنفاد الموارد. بالإضافة إلى ذلك، قم بتعيين kernel_memory و memory_reservation لمزيد من التحكم الدقيق.

مثال واقعي: استضافة WordPress متعددة المستأجرين باستخدام Docker Compose

ضع في اعتبارك سيناريو تستضيف فيه مواقع WordPress متعددة لعملاء مختلفين، كل منها في حاويته الخاصة. قد يبدو الإعداد غير الآمن كما يلي:

version: '3'
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wp-content:/var/www/html/wp-content
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_ROOT_PASSWORD: somewordpress
    volumes:
      - db_data:/var/lib/mysql
volumes:
  db_data:

هذا الإعداد ضعيف: حاوية WordPress تعمل كـ root بالداخل، ولديها جميع القدرات (نظرًا لعدم إسقاط أي منها)، وتقوم بتحميل دليل مضيف مع وصول للكتابة، ولديها وصول غير مقيد للشبكة.

الآن لنقوم بتقويته:

version: '3'
services:
  wordpress:
    image: wordpress:latest
    user: www-data
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    read_only: true
    tmpfs:
      - /var/www/html/wp-content/plugins
    security_opt:
      - seccomp=seccomp-profile.json
      - apparmor=wordpress-profile
    networks:
      - frontend
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wp-uploads:/var/www/html/wp-content/uploads
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M
  db:
    image: mysql:5.7
    user: mysql
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    networks:
      - backend
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_ROOT_PASSWORD: somewordpress
    volumes:
      - db_data:/var/lib/mysql
    deploy:
      resources:
        limits:
          cpus: '0.25'
          memory: 128M
networks:
  frontend:
    driver: bridge
    internal: false
  backend:
    driver: bridge
    internal: true
volumes:
  wp-uploads:
  db_data:

تحسينات رئيسية:

  • كلا الحاويتين تعملان كمستخدمين غير root (www-data و mysql).
  • تم إسقاط جميع القدرات، وتمت إضافة NET_BIND_SERVICE فقط.
  • نظام ملفات WordPress للقراءة فقط باستثناء وحدة تخزين tmpfs ووحدة تخزين uploads.
  • تم تطبيق ملفات تعريف Seccomp و AppArmor (ستحتاج إلى توفير ملفات تعريف مخصصة).
  • شبكات منفصلة تعزل الويب عن قاعدة البيانات، مع كون شبكة قاعدة البيانات داخلية.
  • حدود الموارد تمنع استنفاد الموارد.

لمزيد من المعلومات حول تقوية Docker الخاصة بـ WordPress، راجع Docker لـ WordPress: لماذا تغير الحاويات المعزولة كل شيء.

تحذيرات

  • إعادة تعيين مساحة اسم المستخدم: على الرغم من قوتها، إلا أنها تكسر تحميل وحدات التخزين لأن معرف UID للمضيف المعاد تعيينه ليس هو نفسه معرف UID للحاوية. قد تحتاج إلى إنشاء أدلة مسبقًا بالأذونات الصحيحة أو استخدام وحدات تخزين Docker مع دعم إعادة التعيين.
  • ملفات تعريف Seccomp/AppArmor: تتطلب الملفات التعريف المخصصة فهمًا لاستدعاءات النظام وأنماط الوصول إلى الملفات لتطبيقك. يمكن للملفات التعريف المقيدة بشكل مفرط أن تكسر الوظائف. اختبر بدقة.
  • الأداء: الطبقات الأمنية الإضافية مثل seccomp و AppArmor لها حمل ضئيل، ولكن حدود الموارد وأنظمة الملفات للقراءة فقط قد تؤثر على التطبيقات التي تقوم بالكتابة بكثافة.
  • تعقيد التنسيق: في بيئة متعددة المستأجرين، يمكن أن تصبح إدارة ملفات Docker Compose لكل مستأجر مرهقة. ضع في اعتبارك استخدام أداة تنسيق أعلى مستوى مثل Kubernetes، ولكن هذا يقدم اعتبارات أمنية خاصة به.

خاتمة

هروب الحاويات هو تهديد حقيقي في استضافة Docker متعددة المستأجرين، ولكنه قابل للمنع. من خلال فهم آليات العزل وتطبيق الدفاع المتعمق - إسقاط القدرات، والتشغيل كمستخدم غير root، وتمكين مساحات أسماء المستخدمين، و seccomp، و AppArmor، وتجزئة الشبكة، والفحص المنتظم للصور - يمكنك تقليل المخاطر بشكل كبير. تذكر أن الإعدادات الافتراضية لـ Docker ليست جاهزة للإنتاج للأحمال متعددة المستأجرين. قم بتطبيق هذه الخطوات اليوم لحماية المستأجرين والبنية التحتية الخاصة بك. للحصول على نظرة شاملة على أفضل ممارسات أمان Docker، راجع تأمين تطبيقات الويب الخاصة بك باستخدام Docker: دليل عملي للعزل وأفضل الممارسات.

Sources (5)