החלת כללי מדיניות אבטחה מוגדרים מראש ברמת ה-Pod באמצעות PodSecurity

בדף הזה נסביר איך להחיל אמצעי אבטחה מוגדרים מראש ברמת ה-Pod באשכולות Google Kubernetes Engine‏ (GKE) באמצעות בקרת הכניסה PodSecurity. החלת אמצעי בקרה לאבטחה על ה-Pods יכולה לעזור לכם לעמוד בדרישות האבטחה והתאימות. בדף הזה אנחנו מסבירים על PodSecurity ואיך להשתמש בו ב-Pods.

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

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

מידע על PodSecurity

PodSecurity הוא בקר קבלה (admission controller) של Kubernetes שמאפשר להחיל תקני אבטחה של Pod על Pods שפועלים באשכולות GKE. תקני אבטחה של Pod הם כללי מדיניות אבטחה מוגדרים מראש שמכסים את הצרכים ברמה גבוהה של אבטחת Pod ב-Kubernetes. ההגבלות במדיניות משתנות, החל מהגבלות מתונות ועד להגבלות מחמירות.

אפשר להחיל את תקני האבטחה הבאים של Pod על אשכולות GKE:

  • פריבילגיה: מדיניות לא מוגבלת שמספקת את רמת ההרשאות הרחבה ביותר. מאפשר הסלמת הרשאות ידועה.
  • בסיסית: מדיניות מגבילה באופן מינימלי שמאפשרת את הגדרת ברירת המחדל של ה-Pod, שהיא מינימלית. מונעת הסלמות הרשאות ידועות.
  • מוגבלת: מדיניות מגבילה מאוד שפועלת לפי שיטות מומלצות לחיזוק אבטחת ה-Pod.

אפשר להשתמש בבקר הכניסה PodSecurity כדי להחיל את תקני אבטחת ה-Pod במצבים הבאים:

  • אכיפה: הפרות מדיניות גורמות לדחייה של יצירת ה-Pod. אירוע ביקורת נוסף ליומן הביקורת.
  • ביקורת: הפרות של מדיניות מפעילות הוספה של אירוע ביקורת ליומן הביקורת. אפשר ליצור פודים.
  • אזהרה: הפרות של המדיניות מפעילות אזהרה שמוצגת למשתמש. מותר ליצור פודים.

בקרת הקבלה PodSecurity מטמיעה את המדיניות הזו ב-Kubernetes API.

אם רוצים ליצור ולהחיל מדיניות אבטחה מותאמת אישית ברמת ה-Pod, כדאי להשתמש בבקרת הכניסה Gatekeeper.

לפני שמתחילים

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

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את gcloud CLI. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.

דרישות

אמצעי אישור הבקשות PodSecurity זמין ומופעל כברירת מחדל באשכולות שפועלות בהם הגרסאות הבאות של GKE:

  • גרסה 1.25 ואילך: יציבה
  • גרסה 1.23 וגרסה 1.24: בטא

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

החלת תקני אבטחה של Pod באמצעות PodSecurity

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

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

בגרסאות GKE הבאות, מערכת GKE מתעלמת ממדיניות שמחילים על מרחב השמות kube-system:

  • ‫1.23.6-gke.1900 ואילך
  • ‫1.24.0-gke.1200 ואילך

בגרסאות קודמות של GKE, מומלץ להימנע מאכיפת מדיניות ב-kube-system.

יצירת מרחבי שמות חדשים

יוצרים מרחבי שמות באשכול:

kubectl create ns baseline-ns
kubectl create ns restricted-ns

הפקודה הזו יוצרת את מרחבי השמות הבאים:

  • baseline-ns: לעומסי עבודה עם הרשאות רחבות
  • restricted-ns: לעומסי עבודה עם הגבלות חמורות

שימוש בתוויות להחלת כללי מדיניות אבטחה

החלת תקני אבטחת ה-Pod הבאים:

  • baseline: הפעלה באפליקציה baseline-ns במצב warn
  • restricted: הפעלה באפליקציה restricted-ns במצב enforce
kubectl label --overwrite ns baseline-ns pod-security.kubernetes.io/warn=baseline
kubectl label --overwrite ns restricted-ns pod-security.kubernetes.io/enforce=restricted

הפקודות האלה משיגות את התוצאה הבאה:

  • עומסי עבודה במרחב השמות baseline-ns שמפירים את המדיניות baseline מותרים, ובלקוח מוצגת הודעת אזהרה.
  • עומסי עבודה במרחב השמות restricted-ns שמפירים את המדיניות restricted נדחים, ו-GKE מוסיף רשומה ליומני הביקורת.

מוודאים שהתוויות נוספו:

kubectl get ns --show-labels

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

baseline-ns       Active   74s   kubernetes.io/metadata.name=baseline-ns,pod-security.kubernetes.io/warn=baseline
restricted-ns     Active   18s   kubernetes.io/metadata.name=restricted-ns,pod-security.kubernetes.io/enforce=restricted
default           Active   57m   kubernetes.io/metadata.name=default
kube-public       Active   57m   kubernetes.io/metadata.name=kube-public
kube-system       Active   57m   kubernetes.io/metadata.name=kube-system

בדיקת המדיניות שהוגדרה

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

  1. שומרים את קובץ המניפסט הבא בשם psa-workload.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    
  2. מחילים את המניפסט על מרחב השמות baseline-ns:

    kubectl apply -f psa-workload.yaml --namespace=baseline-ns
    

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

    Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
    

    המדיניות baseline מאפשרת לפוד לפרוס במרחב השמות.

  3. מוודאים שה-Pod נפרס בהצלחה:

    kubectl get pods --namespace=baseline-ns -l=app=nginx
    
  4. מחילים את המניפסט על מרחב השמות restricted-ns:

    kubectl apply -f psa-workload.yaml --namespace=restricted-ns
    

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

    Error from server (Forbidden): error when creating "workload.yaml": pods "nginx"
    is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation
    != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false),
    unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
    runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
    seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
    to "RuntimeDefault" or "Localhost")
    

    ה-Pod לא יופעל במרחב השמות. רשומה של ביקורת נוספת ליומן.

צפייה בהפרות מדיניות ביומני הביקורת

הפרות מדיניות במצבים audit ו-enforce מתועדות ביומני הביקורת של האשכול. אפשר לצפות ביומנים האלה באמצעות Logs Explorer בCloud de Confiance מסוף.

  1. נכנסים לדף Logs Explorer במסוף Cloud de Confiance .

    כניסה לדף Logs Explorer

  2. בשדה Query, מציינים את הפרטים הבאים כדי לאחזר יומני ביקורת של מצב audit ושל מצב enforce:

    resource.type="k8s_cluster"
    protoPayload.resourceName:"/pods/nginx"
    protoPayload.methodName="io.k8s.core.v1.pods.create"
    (labels."pod-security.kubernetes.io/audit-violations":"PodSecurity" OR protoPayload.response.reason="Forbidden")
    
  3. לוחצים על Run query.

  4. בקטע תוצאות השאילתה, מרחיבים את רשומת היומן Forbidden כדי לבדוק את יומני הדחייה של מצב enforce. הפרטים דומים לפרטים הבאים:

    {
      ...
      protoPayload: {
        @type: "type.googleapis.com/google.cloud.audit.AuditLog"
        authenticationInfo: {1}
        authorizationInfo: [1]
        methodName: "io.k8s.core.v1.pods.create"
        request: {6}
        requestMetadata: {2}
        resourceName: "core/v1/namespaces/restricted-ns/pods/nginx"
        response: {
          @type: "core.k8s.io/v1.Status"
          apiVersion: "v1"
          code: 403
          details: {2}
          kind: "Status"
          message: "pods "nginx" is forbidden: violates PodSecurity "restricted:latest": privileged
                  (container "nginx" must not set securityContext.privileged=true),
                  allowPrivilegeEscalation != false (container "nginx" must set
                  securityContext.allowPrivilegeEscalation=false), unrestricted capabilities
                  (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
                  runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
                  seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
                  to "RuntimeDefault" or "Localhost")"
          metadata: {0}
          reason: "Forbidden"
          status: "Failure"
          }
          serviceName: "k8s.io"
          status: {2}
        }
      receiveTimestamp: "2022-02-01T19:19:25.353235326Z"
      resource: {2}
      timestamp: "2022-02-01T19:19:21.469360Z"
    }
    
  5. מרחיבים את audit-violations רשומת היומן כדי לבדוק את היומנים במצב audit. הפרטים אמורים להיראות כך:

    {
      ...
      labels: {
        ...
        pod-security.kubernetes.io/audit-violations: "would violate PodSecurity "baseline:latest": privileged
                                                    (container "nginx" must not set securityContext.privileged=true)"
        pod-security.kubernetes.io/enforce-policy: "privileged:latest"
      }
      operation: {4}
      protoPayload: {10}
      receiveTimestamp: "2023-12-26T05:18:04.533631468Z"
      resource: {2}
      timestamp: "2023-12-26T05:17:36.102387Z"
    }
    

הסרת המשאבים

כדי להימנע מחיובים בחשבון Cloud de Confiance by S3NS , צריך למחוק את מרחבי השמות:

kubectl delete ns baseline-ns
kubectl delete ns restricted-ns

חלופות ל-PodSecurity

בנוסף לשימוש בPodSecurityבקרת הכניסה המובנית של Kubernetes כדי להחיל את תקני האבטחה של Pod, אפשר גם להשתמש ב-Gatekeeper, בקרת כניסה שמבוססת על Open Policy Agent‏ (OPA), כדי ליצור ולהחיל אמצעי בקרה מותאמים אישית לאבטחת Pod.

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