בדף הזה נסביר איך להחיל אמצעי אבטחה מוגדרים מראש ברמת ה-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 לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מוודאים שיש לכם אשכול GKE Autopilot או Standard בגרסה 1.23 ואילך.
- באשכולות במצב Autopilot, נרשמים לערוץ הפצה שבו גרסת ברירת המחדל היא 1.23 ואילך.
- באשכולות רגילים, נרשמים לערוץ הפצה או משדרגים את האשכול לגרסה ספציפית.
דרישות
אמצעי אישור הבקשות 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 שמאפשר העלאת הרשאות.
שומרים את קובץ המניפסט הבא בשם
psa-workload.yaml:apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: trueמחילים את המניפסט על מרחב השמות
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מאפשרת לפוד לפרוס במרחב השמות.מוודאים שה-Pod נפרס בהצלחה:
kubectl get pods --namespace=baseline-ns -l=app=nginxמחילים את המניפסט על מרחב השמות
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 מסוף.
נכנסים לדף Logs Explorer במסוף Cloud de Confiance .
בשדה 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")לוחצים על Run query.
בקטע תוצאות השאילתה, מרחיבים את רשומת היומן
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" }מרחיבים את
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.
המאמרים הבאים
- מידע נוסף על תקני אבטחה של Pod
- מידע נוסף על
PodSecurityבקרת הכניסה - העברה מ-PodSecurityPolicy אל
PodSecurityבקרת הגישה.