מידע על seccomp ב-GKE

במאמר הזה מתואר מצב האבטחה של מחשוב (seccomp) ב-Linux ב-Google Kubernetes Engine‏ (GKE). במסמך הזה אנחנו מניחים שאתם יודעים את הפרטים הבאים:

המידע במסמך הזה יעזור לכם להבין אילו פעולות האפליקציות בקונטיינרים יכולות לבצע במכונה הווירטואלית (VM) המארחת שמגבה את הצמתים.

המסמך הזה מיועד למומחי אבטחה שמשתמשים ב-seccomp כחלק מאסטרטגיית האבטחה של הארגון שלהם, ורוצים להבין איך GKE פועל עם פרופילי seccomp. מידע נוסף על תפקידים נפוצים ועל משימות לדוגמה שאנחנו מתייחסים אליהן ב Cloud de Confiance by S3NS תוכן, זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE.

מה זה seccomp?

מצב מחשוב מאובטח, או seccomp, הוא יכולת אבטחה ב-Linux שמאפשרת להגביל את קריאות המערכת (syscalls) שתהליך יכול לבצע לליבת Linux.

כברירת מחדל, צמתי GKE משתמשים במערכת הפעלה שמותאמת לקונטיינרים עם זמן ריצה של קונטיינרים מסוג containerd. כדי להגן על ליבת Linux,‏ containerd מגביל את היכולות המותרות של Linux לרשימת ברירת מחדל, ואפשר להגביל עוד יותר את קריאות המערכת המותרות באמצעות פרופיל seccomp. יש ל-containerd פרופיל seccomp שזמין כברירת מחדל. האם GKE יחיל בשבילכם את פרופיל ברירת המחדל של seccomp? התשובה תלויה במצב האשכול שבו אתם משתמשים, באופן הבא:

  • Autopilot (מומלץ): GKE מחיל את פרופיל ברירת המחדל של containerd seccomp על כל עומסי העבודה באופן אוטומטי.
  • Standard: ‫GKE לא מחיל באופן אוטומטי את פרופיל ברירת המחדל של containerd seccomp על כל עומסי העבודה. מומלץ להחיל על עומסי העבודה את פרופיל ברירת המחדל של seccomp או פרופיל seccomp מותאם אישית.

פרופיל ברירת המחדל של containerd seccomp מספק אבטחה בסיסית תוך שמירה על תאימות לרוב עומסי העבודה. ההגדרה המלאה של פרופיל seccomp עבור containerd זמינה ב-GitHub.

יכולות וקריאות מערכת ב-Linux

תהליכים בלי הרשאות root שפועלים במערכות Linux עשויים לדרוש הרשאות ספציפיות כדי לבצע פעולות בתור משתמש root. ב-Linux נעשה שימוש ביכולות כדי לחלק את ההרשאות הזמינות לקבוצות, כך שתהליך שאינו root יכול לבצע פעולה ספציפית בלי לקבל את כל ההרשאות. כדי שתהליך יוכל לבצע קריאת מערכת ספציפית בהצלחה, התהליך צריך לקבל הרשאות מתאימות באמצעות יכולת.

רשימה של כל היכולות של Linux מופיעה במאמר בנושא יכולות.

נדחות קריאות מערכת בפרופיל ברירת המחדל של GKE seccomp

פרופיל ברירת המחדל של containerd seccomp חוסם את כל קריאות המערכת (syscalls) ואז מאפשר באופן סלקטיבי קריאות מערכת ספציפיות, שחלקן תלויות בארכיטקטורת ה-CPU של מכונת ה-VM של הצומת ובגרסת הליבה. המשתנה syscalls בפונקציה DefaultProfile מפרט את קריאות המערכת המותרות לכל הארכיטקטורות.

פרופיל seccomp שמוגדר כברירת מחדל חוסם קריאות למערכת (syscalls) שאפשר להשתמש בהן כדי לעקוף את גבולות הבידוד של הקונטיינר ולאפשר גישה מורשית לצומת או לקונטיינרים אחרים. בטבלה הבאה מתוארות כמה קריאות מערכת משמעותיות שפרופיל ברירת המחדל של seccomp דוחה:

קריאות מערכת שנדחו
mount, umount, umount2, fsmount, mount_setattr

הגבלת הגישה של תהליכים למערכת הקבצים של הצומת או לשינוי שלה מחוץ לגבולות של הקונטיינר.

הבקשה נדחתה גם כי היכולת CAP_SYS_ADMIN הוסרה.

bpf

הגבלת תהליכים מיצירת תוכניות eBPF בליבה (kernel), מה שעלול להוביל להסלמת הרשאות (privilege escalation) בצומת. לדוגמה, CVE-2021-3490 השתמש ב-syscall‏ bpf. הבקשה נדחתה גם כי היכולת CAP_SYS_ADMIN הוסרה.

clone, clone3, unshare

הגבלת תהליכים כך שלא יוכלו ליצור תהליכים חדשים במרחבי שמות חדשים שעשויים להיות מחוץ למרחב השמות המוגבל של הקונטיינר. יכול להיות שלתהליכים החדשים האלה יש הרשאות ויכולות מתקדמות. לדוגמה, ב-CVE-2022-0185 נעשה שימוש ב-syscall‏ unshare. הבקשה נדחתה גם כי היכולת CAP_SYS_ADMIN הוסרה.

reboot

הגבלת תהליכים מהפעלה מחדש של הצומת.

הגישה נדחתה כי היכולת CAP_SYS_BOOT הוסרה.

open_by_handle_at, name_to_handle_at

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

איך משתמשים ב-seccomp ב-GKE

באשכולות Autopilot, ‏ GKE מחיל באופן אוטומטי את פרופיל ברירת המחדל של containerd seccomp על כל עומסי העבודה. לא נדרשת פעולה נוספת. ניסיונות לבצע קריאות מערכת מוגבלות נכשלים. ב-Autopilot אי אפשר להשתמש בפרופילים מותאמים אישית של seccomp כי GKE מנהל את הצמתים.

באשכולות רגילים, צריך להחיל פרופיל seccomp באופן ידני. ‫GKE לא מחיל פרופיל בשבילכם.

הפעלת seccomp באשכולות רגילים

כדי להחיל פרופיל seccomp באופן ידני, מגדירים את הקשר האבטחה של ה-Pod או של הקונטיינר באמצעות השדה spec.securityContext.seccompProfile במפרט ה-Pod, כמו בדוגמה הבאה. מומלץ מאוד להשתמש בפרופיל seccomp לעומסי העבודה, אלא אם תרחיש השימוש מחייב שימוש בקריאות מערכת מוגבלות. אלה שני הסוגים הנתמכים של seccompProfile:

במניפסט לדוגמה הבא, פרופיל ה-seccomp מוגדר לפרופיל ברירת המחדל של זמן הריצה:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  labels:
    app: default-pod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: default-pod
  template:
    metadata:
      labels:
        app: default-pod
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: seccomp-test
        image: nginx

כשפורסים את המניפסט הזה, אם קונטיינר ב-Pod מנסה לבצע קריאת מערכת (syscall) שמפרה את פרופיל ברירת המחדל של seccomp בזמן הריצה, יכול להיות שיהיו ב-Pod או בעומס העבודה התנהגויות לא צפויות. לדוגמה, אם Pod מבצע קריאת מערכת מוגבלת במהלך ההפעלה, ההפעלה תיכשל. אם אפליקציה מנסה לבצע קריאת מערכת מוגבלת בזמן שה-Pod פועל, יכול להיות שתבחינו בשגיאות בקונטיינר. רמת החומרה של קריאת מערכת שנכשלה תלויה באופן שבו האפליקציה מטפלת בשגיאות.

שימוש בפרופיל seccomp מותאם אישית באשכולות רגילים

אם פרופיל ברירת המחדל של seccomp בזמן הריצה מגביל מדי את האפליקציה שלכם (או לא מגביל מספיק), אתם יכולים להחיל פרופיל seccomp מותאם אישית על Pods באשכולות רגילים. התהליך הזה דורש גישה למערכת הקבצים בצומת. הדרכה על טעינה ושימוש בפרופילי seccomp בהתאמה אישית זמינה במאמר הגבלת קריאות המערכת של קונטיינר באמצעות seccomp.

המאמרים הבאים