בלוג
הגנה מפני בריחת קונטיינרים: מדריך מעשי לבידוד Docker לאירוח מרובה דיירים
למד כיצד לאבטח קונטיינרים של Docker מפני פגיעויות בריחה וכשלים בבידוד בסביבות מרובות דיירים עם צעדים קונקרטיים ודוגמאות.

סיכום
קונטיינרים של Docker חולקים את ליבת המערכת המארחת, מה שהופך את הבידוד לקריטי—במיוחד באירוח מרובה דיירים שבו בריחת קונטיינר אחת יכולה לפגוע בכל הדיירים. מפתחים רבים מניחים שקונטיינרים הם מכונות וירטואליות מבודדות לחלוטין, אך המציאות שונה. מאמר זה מסביר את תכונות ליבת לינוקס העומדות בבסיס בידוד Docker (מרחבי שמות, cgroups) ואת וקטורי התקיפה המאיימים עליהם. תלמד צעדים מעשיים לחיזוק הגדרות ה-Docker שלך: הגבלת הרשאות, שימוש בסביבת ריצה מאובטחת, סריקת תמונות ויישום פילוח רשת. על ידי מעקב אחר דוגמה מהעולם האמיתי של ספק אירוח WordPress מרובה דיירים, תראה כיצד ליישם הגנות אלו. אנו מכסים גם הסתייגויות כמו פשרות ביצועים ושימוש ב-seccomp/AppArmor. המטרה היא לתת לך אסטרטגיית בידוד חזקה שתמנע בריחות קונטיינרים ותשמור על בטיחות הדיירים שלך.
מבוא
אם אתה מפעיל פלטפורמת אירוח מרובה דיירים—בין אם זה אירוח WordPress משותף, יישום SaaS, או שירות סביבת פיתוח—בריחת קונטיינר היא תרחיש האימה. פגיעות בליבה או תצורה שגויה יכולות לאפשר לדייר אחד לפרוץ מתוך הקונטיינר שלו ולגשת לנתונים של דיירים אחרים או למערכת המארחת עצמה. הבידוד של Docker מסתמך על תכונות ליבת לינוקס כמו מרחבי שמות (namespaces) ו-cgroups, אך תצורות "מחוץ לקופסה" לרוב אינן מספיקות לאבטחה חזקה. מאמר זה ידריך אותך דרך וקטורי התקיפה ויספק צעדים מעשיים לנעילת קונטיינרי ה-Docker שלך, המומחשים באמצעות דוגמת WordPress מרובה דיירים מהעולם האמיתי. למבט רחב יותר על תזמור הפקה, עיין במדריך שלנו על תזמור יישומים מכולות מוכנים להפקה.
הבנת בידוד Docker
קונטיינרים של Docker משתמשים במרחבי שמות של לינוקס כדי לספק בידוד ברמת התהליך: מרחבי שמות PID מבודדים עצי תהליכים, מרחבי שמות רשת מפרידים ממשקי רשת, מרחבי שמות mount מבודדים מערכות קבצים, ומרחבי שמות משתמשים מאפשרים מיפוי של root הקונטיינר למשתמש מארח לא מורשה. קבוצות בקרה (cgroups) מגבילות שימוש במשאבים כמו CPU, זיכרון וקלט/פלט דיסק. תכונות אלו יחד יוצרות "ארגז חול" סביב כל קונטיינר. עם זאת, בניגוד למכונה וירטואלית שמריצה ליבה נפרדת, קונטיינרים חולקים את ליבת המערכת המארחת. זה אומר שפגיעות בליבה (למשל, CVE-2022-0492) ניתנת לניצול כדי לפרוץ מבידוד מרחב השמות של הקונטיינר. בנוסף, תצורות שגויות כמו הרצת קונטיינרים כ-root בתוך הקונטיינר, מתן כל היכולות לקונטיינר, או אי-הפלת יכולות לינוקס מיותרות יכולות להרחיב את משטח התקיפה.
וקטורי תקיפה
וקטורי תקיפה נפוצים כוללים:
- ניצול ליבה: ניצול באג בליבת המערכת המארחת כדי להשיג גישה למארח.
- קונטיינרים מורשים: הרצה עם
--privilegedמעניקה את כל היכולות ועוקפת את רוב הבידוד. - שימוש לרעה ביכולות: גם ללא מצב הרשאה מלא, קונטיינר עם יכולות מסוכנות כמו
CAP_SYS_ADMINאוCAP_NET_ADMINיכול למנט קבצים או לתמרן הגדרות רשת. - שיטות תמונה לא מאובטחות: שימוש בתמונות בסיס עם פגיעויות ידועות או הכללת כלים מיותרים כמו מקמפלים או מפרשי shell.
- מרחבי שמות mount משותפים: מיפוי ספריות מארח לקונטיינרים יכול לאפשר בריחה אם אינם לקריאה בלבד.
צעדים מעשיים לאבטחה
1. הפעל קונטיינרים כמשתמש לא-root
כברירת מחדל, Docker מריץ קונטיינרים כ-root בתוך הקונטיינר. אם תוקף משיג root בתוך הקונטיינר, יש לו יותר מנוף. צור משתמש ב-Dockerfile שלך והשתמש בהוראת USER. כמו כן, הימנע משימוש בדגל --user ב-Docker Compose כדי למפות למשתמש מארח שרירותי אם אפשר.
2. הפל את כל היכולות והוסף רק את הנדרשות
יכולות לינוקס מפרקות הרשאות superuser ליחידות קטנות יותר. ב-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. זה מוסיף שכבת בידוד, מכיוון שאפילו אם 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. פילוח רשת עם רשתות גשר מותאמות אישית
צור רשתות גשר נפרדות לכל דייר או שכבת יישום. זה מגביל תעבורת מזרח-מערב. ב-Docker Compose, הגדר רשתות ובודד שירותים. השתמש ב-internal: true אם שירות אינו זקוק לגישה לאינטרנט יוצאת. כללי חומת אש במארח מגבילים עוד יותר תעבורה בין קונטיינרים.
8. הגבל משאבים עם Cgroups
הגדר מגבלות CPU וזיכרון ב-Docker Compose באמצעות deploy.resources.limits. זה מונע מקונטיינר שנפרץ להשיק התקפת מיצוי משאבים. בנוסף, הגדר kernel_memory ו-memory_reservation לשליטה מדויקת יותר.
דוגמה מהעולם האמיתי: אירוח WordPress מרובה דיירים עם Docker Compose
שקול תרחיש שבו אתה מארח מספר אתרי WordPress עבור לקוחות שונים, כל אחד בקונטיינר Docker משלו. הגדרה לא מאובטחת עשויה להיראות כך:
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 היא לקריאה בלבד למעט mount של tmpfs ונפח uploads.
- פרופילי Seccomp ו-AppArmor מיושמים (תצטרך לספק פרופילים מותאמים אישית).
- רשתות נפרדות מבודדות את ה-web מה-database, כאשר רשת ה-database פנימית.
- מגבלות משאבים מונעות מיצוי משאבים.
לעוד מידע על חיזוק Docker ספציפי ל-WordPress, עיין בDocker עבור WordPress: מדוע קונטיינרים מבודדים משנים הכל.
הסתייגויות
- מיפוי מחדש של מרחב שמות משתמשים: למרות שהוא חזק, הוא שובר מיפוי נפחים מכיוון ש-UID המארח הממופה מחדש אינו זהה ל-UID של הקונטיינר. ייתכן שתצטרך ליצור מראש ספריות עם ההרשאות הנכונות או להשתמש בנפחי Docker עם תמיכה במיפוי מחדש.
- פרופילי Seccomp/AppArmor: פרופילים מותאמים אישית דורשים הבנה של דפוסי קריאות המערכת וגישת הקבצים של האפליקציה שלך. פרופילים מגבילים מדי עלולים לשבור פונקציונליות. בדוק ביסודיות.
- ביצועים: שכבות אבטחה נוספות כמו seccomp ו-AppArmor בעלות תקורה מינימלית, אך מגבלות משאבים ומערכות קבצים לקריאה בלבד עשויות להשפיע על יישומים עתירי כתיבה.
- מורכבות תזמור: בסביבה מרובת דיירים, ניהול קבצי Docker Compose פר-דייר יכול להפוך למסורבל. שקול להשתמש בכלי תזמור ברמה גבוהה יותר כמו Kubernetes, אך זה מציג שיקולי אבטחה משלו.
מסקנה
בריחת קונטיינר היא איום אמיתי באירוח Docker מרובה דיירים, אך ניתן למנוע אותה. על ידי הבנת מנגנוני הבידוד ויישום הגנה בשכבות—הפלת יכולות, הרצה כלא-root, הפעלת מרחבי שמות משתמשים, seccomp, AppArmor, פילוח רשת וסריקת תמונות קבועה—תוכל להפחית באופן דרמטי את הסיכון. זכור שהגדרות ברירת המחדל של Docker אינן מוכנות להפקה עבור עומסי עבודה מרובי דיירים. יישם צעדים אלו היום כדי להגן על הדיירים שלך ועל התשתית שלך. לסקר מקיף של שיטות עבודה מומלצות לאבטחת Docker, עיין באבטחת יישומי הווב שלך עם Docker: מדריך מעשי לבידוד ושיטות עבודה מומלצות.
Sources (5)
- Docker and Container Isolation - Medium
- What is container isolation? Mechanisms, limitations, and secure runtimes | Blog - Northflank
- Container Isolation Explained for Kubernetes and Beyond - Edera
- Docker Security: 5 Risks and 12 Best Practices for Securing Your Containers - Tigera.io
- 9 Security Best Practices for Docker Containers - Kinsta®

