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

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

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

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

מידע על PodSecurity

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

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

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

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

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

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

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

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

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

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-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 במסוףGoogle Cloud .

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

    כניסה לדף 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"
    }
    

הסרת המשאבים

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

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

חלופות ל-PodSecurity

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

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