שיטות מומלצות ל-GKE RBAC

במסמך הזה מוסברות שיטות מומלצות לתכנון מדיניות בקרת גישה מבוססת-תפקידים (RBAC) ב-Google Kubernetes Engine‏ (GKE). במסמך הזה אנחנו יוצאים מנקודת הנחה שאתם מכירים את הנושאים הבאים:

RBAC היא תכונת אבטחה מרכזית ב-Kubernetes שמאפשרת ליצור הרשאות מפורטות כדי לנהל את הפעולות שמשתמשים ועומסי עבודה יכולים לבצע במשאבים באשכולות. אתם יוצרים תפקידים של RBAC ומקשרים את התפקידים האלה לנושאים, שהם משתמשים מאומתים כמו חשבונות שירות או קבוצות Google.

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

לרשימת משימות של ההנחיות במסמך הזה, אפשר לעיין בסיכום רשימת המשימות.

סקירה מרוכזת של כל השיטות המומלצות ל-GKE זמינה במאמר שיטות מומלצות ל-GKE.

במאמר הגדרת בקרת גישה מבוססת-תפקידים מוסבר איך להטמיע RBAC ב-Google Kubernetes Engine ‏ (GKE).

איך RBAC עובד

‫RBAC תומך בסוגים הבאים של תפקידים וקישורים:

  • ClusterRole: קבוצת הרשאות שאפשר להחיל על כל מרחב שמות או על כל האשכול.
  • תפקיד: קבוצה של הרשאות שמוגבלת למרחב שמות יחיד.
  • ClusterRoleBinding: קשירת ClusterRole למשתמש או לקבוצה בכל מרחבי השמות באשכול.
  • RoleBinding: קשירת Role או ClusterRole למשתמש או לקבוצה במרחב שמות ספציפי.

מגדירים הרשאות כ-rules ב-Role או ב-ClusterRole. כל rulesשדה בתפקיד מורכב מקבוצת API, ממשאבי ה-API בתוך קבוצת ה-API הזו ומהפעלים (פעולות) שמותרים במשאבים האלה. אפשר גם להגדיר את היקף הפעולות לפעולות שמתבצעות על מופעים בעלי שם של משאבי API באמצעות השדה resourceNames. דוגמה מופיעה במאמר בנושא הגבלת הגישה למופעים ספציפיים של משאבים.

אחרי שמגדירים תפקיד, משתמשים ב-RoleBinding או ב-ClusterRoleBinding כדי לקשר את התפקיד לנושא. בוחרים את סוג הקישור בהתאם לרצון להעניק הרשאות במרחב שמות יחיד או בכמה מרחבי שמות.

עיצוב תפקידי RBAC

שימוש בעיקרון של הרשאות מינימליות

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

כשמתכננים את התפקידים, חשוב לשים לב לסיכונים נפוצים של הרחבת הרשאות, כמו פעלים escalate או bind, גישת create ל-PersistentVolumes או גישת create ל-Certificate Signing Requests. רשימת הסיכונים זמינה במאמר בנושא Kubernetes RBAC – סיכונים של הסלמת הרשאות.

לא למחוק תפקידים וקישורים של RBAC במערכת

‫Kubernetes יוצר כמה משאבי RBAC עם התחילית system:, כמו system:basic-user,‏ system:discovery ו-system:public-info-viewer ClusterRoleBindings. המשאבים האלה נדרשים כדי שהאשכול יפעל בצורה תקינה. מומלץ להימנע ממחיקה של תפקידים וקשרים במערכת, כי זה עלול לגרום לחוסר יציבות באשכול. שרת ה-API של Kubernetes מנסה לבצע באופן אוטומטי גישור בין המשאבים האלה בהפעלה, אבל אם הגישור נכשל, יכול להיות שלא תהיה לכם גישה לאשכול.

כדי לוודא שתפקידים וקישורים במערכת לא נמחקים או משתנים, כדאי לבדוק את מדיניות ה-RBAC ולוודא שלסובייקטים אין הרשאות delete או update ב-RoleBindings וב-ClusterRoleBindings עם קידומות system:.

לא כדאי להשתמש בתפקידים ובקבוצות שמוגדרים כברירת מחדל

‫Kubernetes יוצרת קבוצה של ClusterRoles ו-ClusterRoleBindings שמוגדרים כברירת מחדל, שאפשר להשתמש בהם כדי לגלות את ה-API וכדי להפעיל את הפונקציונליות של רכיבים מנוהלים. ההרשאות שניתנות על ידי התפקידים האלה שמוגדרים כברירת מחדל יכולות להיות נרחבות, בהתאם לתפקיד. ב-Kubernetes יש גם קבוצה של משתמשים וקבוצות משתמשים שמוגדרים כברירת מחדל, ומזוהים על ידי התחילית system:. כברירת מחדל, Kubernetes ו-GKE מקשרים את התפקידים האלה באופן אוטומטי לקבוצות ברירת המחדל ולנושאים שונים. רשימה מלאה של תפקידי ברירת המחדל והקישורים שנוצרים ב-Kubernetes מופיעה במאמר תפקידי ברירת מחדל וקישורי תפקידים.

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

שם סוג תיאור
cluster-admin ClusterRole מעניקה לנושא הרשאה לעשות כל דבר בכל משאב באשכול.
system:anonymous משתמש

מערכת Kubernetes מקצה את המשתמש הזה לבקשות של שרת API שלא סופק להן מידע אימות.

קישור תפקיד למשתמש הזה מעניק לכל משתמש לא מאומת את ההרשאות שמוענקות על ידי התפקיד הזה.

system:unauthenticated קבוצה

‫Kubernetes מקצה את הקבוצה הזו לבקשות לשרת ה-API שלא סופק להן מידע אימות.

קישור תפקיד לקבוצה הזו מעניק לכל משתמש לא מאומת את ההרשאות שניתנות על ידי התפקיד הזה.

system:authenticated קבוצה

‫GKE מקצה את הקבוצה הזו לבקשות של שרת API שמוגשות על ידי כל משתמש שמחובר לחשבון Google, כולל כל חשבונות Gmail. בפועל, אין הבדל משמעותי בין system:unauthenticated לבין system:unauthenticated, כי כל אחד יכול ליצור חשבון Google.

קישור תפקיד לקבוצה הזו מעניק לכל משתמש עם חשבון Google, כולל כל חשבונות Gmail, את ההרשאות שמוענקות על ידי התפקיד הזה.

system:masters קבוצה

כברירת מחדל, Kubernetes מקצה את cluster-admin ClusterRole לקבוצה הזו כדי לאפשר פונקציונליות של המערכת.

אם מוסיפים נושאים משלכם לקבוצה הזו, הנושאים האלה מקבלים גישה לביצוע כל פעולה בכל משאב באשכול.

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

  • קישור ברירת המחדל של cluster-admin ClusterRole לקבוצה system:unauthenticated מעניק לכל המשתמשים שלא עברו אימות גישה לכל המשאבים באשכול (כולל סודות). התקשרויות כאלה עם הרשאות גבוהות הן מטרה פעילה להתקפות כמו קמפיינים של תוכנות זדוניות בהיקף נרחב.
  • קישור של תפקיד בהתאמה אישית לקבוצה system:unauthenticated מעניק למשתמשים לא מאומתים את ההרשאות שמוענקות על ידי התפקיד הזה.

במידת האפשר, כדאי לפעול לפי ההנחיות הבאות:

  • אל תוסיפו נושאים משלכם לקבוצה system:masters.
  • אל תקשרו את הקבוצה system:unauthenticated לאף תפקיד RBAC.
  • אל תקשרו את הקבוצה system:authenticated לאף תפקיד RBAC.
  • לא מקשרים את המשתמש system:anonymous לתפקידים כלשהם ב-RBAC.
  • אל תקשרו את cluster-admin ClusterRole לנושאים שלכם או למשתמשים ולקבוצות שמוגדרים כברירת מחדל. אם האפליקציה שלכם דורשת הרשאות רבות, כדאי לקבוע אילו הרשאות בדיוק נדרשות וליצור תפקיד ספציפי למטרה הזו.
  • לפני שמקשרים נושאים, כדאי לבדוק את ההרשאות שניתנות על ידי תפקידי ברירת מחדל אחרים.
  • כדאי לבדוק את התפקידים שמשויכים לקבוצות ברירת המחדל לפני שמשנים את חברי הקבוצות האלה.

מניעת שימוש בקבוצות ברירת מחדל

אפשר להשתמש ב-CLI של gcloud כדי להשבית קישורי RBAC שאינם ברירת מחדל באשכול שמפנים לקבוצות system:unauthenticated ו-system:authenticated או למשתמש system:anonymous. משתמשים באחד מהדגלים הבאים או בשניהם כשיוצרים אשכול GKE חדש או מעדכנים אשכול קיים. השימוש בהתראות האלה לא משבית את הקישורים של Kubernetes שמוגדרים כברירת מחדל ומפנים לקבוצות האלה. כדי להשתמש בדגלים האלה, צריך GKE בגרסה 1.30.1-gke.1283000 ואילך.

זיהוי והסרה של שימוש בתפקידים ובקבוצות שמוגדרים כברירת מחדל

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

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

ClusterRoleBindings
  1. מציגים את השמות של כל ClusterRoleBindings עם הנושא system:anonymous,‏ system:unauthenticated או system:authenticated:

    kubectl get clusterrolebindings -o json \
      | jq -r '["Name"], ["-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
    

    הפלט צריך לכלול רק את ה-ClusterRoleBindings הבאים:

    Name
    ----
    "system:basic-user"
    "system:discovery"
    "system:public-info-viewer"
    

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

  2. מציגים את ההרשאות של התפקיד שמשויך לקישור:

    kubectl get clusterrolebinding CLUSTER_ROLE_BINDING_NAME -o json \
        | jq ' .roleRef.name +" " + .roleRef.kind' \
        | sed -e 's/"//g' \
        | xargs -l bash -c 'kubectl get $1 $0 -o yaml'
    

    מחליפים את CLUSTER_ROLE_BINDING_NAME בשם של ClusterRoleBinding שאינו ברירת המחדל.

    הפלט אמור להיראות כך:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    ...
    rules:
    - apiGroups:
      - ""
      resources:
      - secrets
      verbs:
      - get
      - watch
      - list
    

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

  3. מחיקת קישור לא בטוח מהאשכול:

    kubectl delete clusterrolebinding CLUSTER_ROLE_BINDING_NAME
    

    מחליפים את CLUSTER_ROLE_BINDING_NAME בשם של ClusterRoleBinding שרוצים למחוק.

RoleBindings
  1. מציגים את מרחב השמות ואת השם של כל RoleBinding עם הנושא system:anonymous,‏ system:unauthenticated או system:authenticated:

    kubectl get rolebindings -A -o json \
      | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
    

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

    אם אתם יודעים רק את השם של RoleBinding, אתם יכולים להשתמש בפקודה הבאה כדי למצוא RoleBinding תואם בכל מרחבי השמות:

    kubectl get rolebindings -A -o json \
      | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(.metadata.name == "ROLE_BINDING_NAME") | [.metadata.namespace, .metadata.name]) | @tsv'
    

    מחליפים את ROLE_BINDING_NAME בשם של RoleBinding שאינו ברירת המחדל.

  2. מציגים את ההרשאות של התפקיד שמשויך לקישור:

    kubectl get rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE -o json \
        | jq ' .roleRef.name +" " + .roleRef.kind' \
        | sed -e 's/"//g' \
        | xargs -l bash -c 'kubectl get $1 $0 -o yaml --namespace ROLE_BINDING_NAMESPACE'
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ROLE_BINDING_NAME: השם של RoleBinding שאינו ברירת המחדל.
    • ROLE_BINDING_NAMESPACE: מרחב השמות של RoleBinding שאינו ברירת המחדל.

    הפלט אמור להיראות כך:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
    ...
    rules:
    - apiGroups:
      - ""
      resources:
      - secrets
      verbs:
      - get
      - watch
      - list
    

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

  3. מחיקת קישור לא בטוח מהאשכול:

    kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ROLE_BINDING_NAME: השם של RoleBinding שרוצים למחוק.
    • ROLE_BINDING_NAMESPACE: מרחב השמות של ה-RoleBinding שרוצים למחוק.

הגדרת הרשאות ברמת מרחב השמות

אפשר להשתמש בקישורים ובתפקידים באופן הבא, בהתאם לצרכים של עומס העבודה או המשתמש:

  • כדי להעניק גישה למשאבים במרחב שמות אחד, משתמשים ב-Role עם RoleBinding.
  • כדי להעניק גישה למשאבים ביותר ממרחב שמות אחד, צריך להשתמש ב-ClusterRole עם RoleBinding לכל מרחב שמות.
  • כדי להעניק גישה למשאבים בכל מרחב שמות , משתמשים ב-ClusterRole עם ClusterRoleBinding.

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

לא להשתמש בתווים כלליים

התו * הוא תו כללי לחיפוש שחל על הכול. מומלץ להימנע משימוש בתווים כלליים בכללים. מציינים במפורש קבוצות, משאבים ופעלים של API בכללי RBAC. לדוגמה, אם מציינים * בשדה verbs, מקבלים את ההרשאות get, ‏ list, ‏ watch, ‏ patch, ‏ update, ‏ deletecollection ו-delete למשאבים. בטבלה הבאה מוצגות דוגמאות לכללים שבהם לא נעשה שימוש בתווים כלליים:

מומלץ לא מומלץ
- rules:
    apiGroups: ["apps","extensions"]
    resources: ["deployments"]
    verbs: ["get","list","watch"]

ההרשאות get,‏ list ו-watch מוענקות באופן ספציפי לקבוצות של ממשקי API‏ apps ו-extensions.

- rules:
    apiGroups: ["*"]
    resources: ["deployments"]
    verbs: ["get","list","watch"]

נותן את הפעלים ל-deployments בכל קבוצת API.

- rules:
    apiGroups: ["apps", "extensions"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch"]

ההרשאות שניתנות הן רק לפעלים get, list ו-watch לפריסות בקבוצות של ממשקי API‏ apps ו-extensions.

- rules:
    apiGroups: ["apps", "extensions"]
    resources: ["deployments"]
    verbs: ["*"]

נותן את כל הפעלים, כולל patch או delete.

שימוש בכללים נפרדים כדי להעניק גישה עם הרשאות מינימליות למשאבים ספציפיים

כשמתכננים את הכללים, כדאי לנסות את השלבים הבאים כדי ליצור כללים יעילים יותר של הרשאות מינימליות בכל תפקיד:

  1. יוצרים כללי RBAC נפרדים לכל פועל בכל משאב שנושא צריך לגשת אליו.
  2. אחרי שכותבים את הכללים, צריך לנתח אותם כדי לבדוק אם יש כמה כללים עם אותה verbs רשימה. לשלב את הכללים האלה לכלל אחד.
  3. חשוב להקפיד שכל הכללים הנותרים יהיו נפרדים זה מזה.

הגישה הזו מאפשרת ליצור כללים בצורה מאורגנת יותר, שבה כללים שמעניקים את אותם הפעלים למספר משאבים משולבים, וכללים שמעניקים פעלים שונים למשאבים מופרדים.

לדוגמה, אם לעומס העבודה שלכם נדרשות הרשאות למשאב deployments, אבל נדרשות לו גם list ו-watch במשאבים daemonsets, כדאי להשתמש בכללים נפרדים כשיוצרים תפקיד. כשמקשרים את תפקיד ה-RBAC לעומס העבודה, אי אפשר להשתמש ב-watch ב-deployments.

דוגמה נוספת: אם עומס העבודה שלכם צריך get ו-watch גם במשאב pods וגם במשאב daemonsets, אתם יכולים לשלב אותם בכלל אחד, כי עומס העבודה צריך את אותם הפעלים בשני המשאבים.

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

מומלץ לא מומלץ
- rules:
    apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get"]
- rules:
    apiGroups: ["apps"]
    resources: ["daemonsets"]
    verbs: ["list", "watch"]

התפקיד הזה מעניק ל-get גישה לפריסות ול-watch ול-list גישה ל-DaemonSets. אי אפשר להציג רשימה של פריסות בנושאים.

- rules:
    apiGroups: ["apps"]
    resources: ["deployments", "daemonsets"]
    verbs: ["get","list","watch"]

ההרשאות ניתנות גם ל-Deployments וגם ל-DaemonSets. נושא שלא צריך גישת list לאובייקטים של deployments עדיין יקבל את הגישה הזו.

- rules:
    apiGroups: ["apps"]
    resources: ["daemonsets", "deployments"]
    verbs: ["list", "watch"]

שילוב של שני כללים כי הנושא צריך את אותם פעלים גם למשאב daemonsets וגם למשאב deployments.

- rules:
    apiGroups: ["apps"]
    resources: ["daemonsets"]
    verbs: ["list", "watch"]
- rules:
    apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["list", "watch"]

הכללים המפוצלים האלה יניבו את אותה תוצאה כמו הכלל המשולב, אבל הם ייצרו עומס מיותר במניפסט התפקידים

הגבלת הגישה למופעים ספציפיים של משאבים

ב-RBAC אפשר להשתמש בשדה resourceNames בכללים כדי להגביל את הגישה למופע ספציפי של משאב עם שם. לדוגמה, אם אתם כותבים תפקיד RBAC שצריך update את ConfigMap seccomp-high ולא שום דבר אחר, אתם יכולים להשתמש ב-resourceNames כדי לציין רק את ConfigMap הזה. מומלץ להשתמש ב-resourceNames כשאפשר.

מומלץ לא מומלץ
- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["seccomp-high"]
    verbs: ["update"]

מגביל את הנושא לעדכון רק של seccomp-high ConfigMap. הנושא לא יכול לעדכן אף ConfigMap אחר במרחב השמות.

- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["update"]

הנושא יכול לעדכן את seccomp-high ConfigMap ואת כל ConfigMap אחר במרחב השמות.

- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["list"]
- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["seccomp-high"]
    verbs: ["update"]

מעניק list גישה לכל ה-ConfigMap במרחב השמות, כולל seccomp-high. הגבלת הגישה של update רק ל-ConfigMap של seccomp-high. הכללים מפוצלים כי אי אפשר להעניק את ההרשאה list למשאבים עם שם.

- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["update", "list"]

מעניק update גישה לכל ה-ConfigMap, בנוסף לגישת list.

אל תאפשרו לחשבונות שירות לשנות משאבי RBAC

אל תקשרו משאבים של Role או ClusterRole עם הרשאות bind,‏ escalate,‏ create,‏ update או patch בקבוצת ה-API‏ rbac.authorization.k8s.io לחשבונות שירות במרחב שמות כלשהו. escalate ו-bind בפרט יכולים לאפשר לתוקף לעקוף את מנגנוני מניעת ההרשאות המוגברות שמוטמעים ב-RBAC.

הגבלת היכולת של עומסי עבודה לשנות את עצמם

לעומסי עבודה מסוימים של Kubernetes, במיוחד לעומסי עבודה של המערכת, יש הרשאה לבצע שינוי עצמי. לדוגמה, חלק מעומסי העבודה מבצעים שינוי גודל אוטומטי אנכי בעצמם. שינוי עצמי יכול לאפשר לתוקף שכבר פרץ לצומת להרחיב את הגישה שלו באשכול. לדוגמה, תוקף יכול לשנות את מרחב השמות של עומס עבודה כדי להריץ אותו כ-ServiceAccount עם הרשאות גבוהות יותר באותו מרחב שמות.

אלא אם יש צורך בכך, אל תתנו ל-Pods הרשאה לשנות את עצמם. אם חלק מה-Pods צריכים לשנות את עצמם, אפשר להשתמש ב-Policy Controller כדי להגביל את השינויים שעומסי העבודה יכולים לבצע. לדוגמה, אפשר להשתמש בתבנית האילוץ NoUpdateServiceAccount כדי למנוע מ-Pods לשנות את ServiceAccount. כשיוצרים מדיניות, צריך להחריג מהאילוצים את רכיבי ניהול האשכולות, כמו בדוגמה הבאה:

parameters:
  allowedGroups:
  - system:masters
  allowedUsers:
  - system:addon-manager

חשבונות שירות של Kubernetes

יצירת חשבון שירות ב-Kubernetes לכל עומס עבודה

יוצרים חשבון שירות נפרד ב-Kubernetes לכל עומס עבודה. מקשרים Role או ClusterRole עם הרשאות מינימליות לחשבון השירות הזה.

לא להשתמש בחשבון השירות שמוגדר כברירת מחדל

‫Kubernetes יוצר חשבון שירות בשם default בכל מרחב שמות. חשבון השירות default מוקצה אוטומטית ל-Pods שלא מצוין בהם חשבון שירות באופן מפורש במניפסט. לא מומלץ לקשר Role או ClusterRole לחשבון השירות default. יכול להיות שמערכת Kubernetes תקצה את חשבון השירות default לפוד שלא צריך את הגישה שניתנה בתפקידים האלה.

לא להפעיל באופן אוטומטי את אסימוני חשבון השירות

השדה automountServiceAccountToken במפרט של ה-Pod אומר ל-Kubernetes להחדיר אסימון של פרטי כניסה לחשבון שירות של Kubernetes לתוך ה-Pod. ה-Pod יכול להשתמש באסימון הזה כדי לשלוח בקשות מאומתות לשרת Kubernetes API. ערך ברירת המחדל של השדה הזה הוא true.

בכל הגרסאות של GKE, מגדירים את automountServiceAccountToken=false במפרט של ה-Pod אם אין צורך שה-Pods יתקשרו עם שרת ה-API.

עדיף להשתמש בטוקנים זמניים במקום בטוקנים מבוססי-סוד

כברירת מחדל, תהליך kubelet בצומת מאחזר טוקן של חשבון שירות עם תוקף קצר, שמתבצעת לו רוטציה אוטומטית לכל Pod. ‫kubelet מטמיע את האסימון הזה ב-Pod כנפח מוטל, אלא אם מגדירים את השדה automountServiceAccountToken לערך false במפרט של ה-Pod. כל קריאה ל-Kubernetes API מה-Pod משתמשת באסימון הזה כדי לעבור אימות בשרת ה-API.

אם אתם מאחזרים אסימונים של חשבון שירות באופן ידני, אל תשתמשו ב-Kubernetes Secrets כדי לאחסן את האסימון. טוקנים של חשבונות שירות שמבוססים על סודות הם אמצעי אימות מדור קודם שלא פג תוקפם ולא מתבצעת עבורם רוטציה אוטומטית. אם אתם צריכים פרטי כניסה לחשבונות שירות, אתם יכולים להשתמש ב-TokenRequest API כדי לקבל אסימונים לטווח קצר שמסתובבים באופן אוטומטי.

בדיקה מתמשכת של הרשאות RBAC

כדאי לבדוק באופן קבוע את התפקידים והגישה שלכם ב-RBAC כדי לזהות נתיבי הסלמה פוטנציאליים וכללים מיותרים. לדוגמה, נניח שלא מוחקים RoleBinding שמקשר Role עם הרשאות מיוחדות למשתמש שנמחק. אם תוקף יוצר חשבון משתמש במרחב השמות הזה עם אותו שם כמו של המשתמש שנמחק, הוא ישויך ל-Role ויקבל את אותה גישה. בדיקות תקופתיות מצמצמות את הסיכון הזה.

סיכום רשימת המשימות

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