בדף הזה מוסבר איך להחיל אמצעי בקרה מוגדרים מראש לאבטחת פודים באשכולות 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 לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מוודאים שיש לכם אשכול 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 במסוףGoogle Cloud .
נכנסים לדף Logs Explorer במסוף Google Cloud .
בשדה 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" }
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud , צריך למחוק את מרחבי השמות:
kubectl delete ns baseline-ns
kubectl delete ns restricted-ns
חלופות ל-PodSecurity
בנוסף לשימוש בPodSecurityבקרת הכניסה (admission controller) המובנית של Kubernetes כדי להחיל את תקני האבטחה של Pod, אפשר גם להשתמש ב-Gatekeeper, בקרת כניסה שמבוססת על Open Policy Agent (OPA), כדי ליצור ולהחיל אמצעי בקרה מותאמים אישית לאבטחת Pod.
המאמרים הבאים
- מידע נוסף על תקני אבטחה של Pod
- מידע נוסף על
PodSecurityבקרת הכניסה - העברה מ-PodSecurityPolicy אל
PodSecurityadmission controller.