מדיניות ביקורת

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

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

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

במאמר מידע על רישום ביומן ביקורת ב-GKE מוסבר איך להפעיל את סוגי יומני הביקורת השונים ולצפות בהם, וגם מהן ההרשאות הנדרשות ב-IAM.

סקירה כללית של מדיניות הביקורת

באשכול GKE, שרת ה-API של Kubernetes כותב רשומות של יומן ביקורת לחלק האחורי שמנוהל על ידי GKE. כש-GKE מקבל רשומות יומן משרת ה-API של Kubernetes, הוא כותב אותן ביומן Admin Activity וביומן Data Access של הפרויקט.

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

  • מדיניות הביקורת של Kubernetes מגדירה כללים לגבי האירועים שיירשמו כרשומות ביומן. הוא גם מציין אילו נתונים צריכים להיכלל ברשומות ביומן.

  • מדיניות הביקורת של GKE קובעת אילו רשומות ייכתבו ביומן פעילות האדמין ואילו ייכתבו ביומן הגישה לנתונים.

יומני הביקורת שנכתבים ביומן Data Access תלויים בהגדרות יומן הביקורת. יומני הגישה לנתונים משתמשים במחירון של Google Cloud Observability. יומני Admin Activity מוצעים ללא תשלום. ‫GKE תומך בסוגים הבאים של יומני גישה לנתונים.

  • ADMIN_READ: פעולות שקוראות מטא-נתונים על משאבי Kubernetes, כמו רשימת Pods.
  • DATA_READ: פעולות שקוראות נתונים במשאבי Kubernetes, כמו קריאת היומנים של Pod.
  • DATA_WRITE: פעולות שכותבות נתונים למשאבי Kubernetes, כמו עדכון סטטוס של Pod.

מידע נוסף זמין במאמר הגדרת יומני ביקורת של גישה לנתונים.

מדיניות ביקורת ב-Kubernetes

שרת ה-API של Kubernetes פועל לפי מדיניות שמוגדרת בדגל --audit-policy-file של הפקודה kube-apiserver.

כש-GKE מפעיל את שרת ה-API של Kubernetes, הוא מספק קובץ מדיניות של ביקורת על ידי הגדרת הערך של הדגל --audit-policy-file. במאגר Kubernetes בקוד פתוח אפשר לראות את הסקריפט configure-helper.sh, שיוצר את קובץ מדיניות הביקורת. אפשר לראות את רוב קובץ מדיניות הביקורת ישירות בסקריפט.

אירועים ושלבים

כשמשתמש או רכיב שולחים בקשה לשרת ה-API של Kubernetes, הבקשה עוברת דרך שלבים אחדים:

שלב תיאור
RequestReceived הבקשה התקבלה על ידי audit handler.
ResponseStarted כותרות התגובה נשלחו, אבל גוף התגובה לא נשלח.
ResponseComplete גוף התגובה הושלם, ולא יישלחו יותר בייטים.
Panic הייתה שגיאת שרת פנימית, והבקשה לא הושלמה.

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

רמות ביקורת

קובץ מדיניות הביקורת של Kubernetes מכיל רשימה של כללים. בקובץ המדיניות, הכלל הראשון שתואם לאירוע קובע את רמת הביקורת של האירוע.

כל כלל יכול לציין אחת מרמות הביקורת הבאות:

רמה תיאור
ללא לא תיצור רשומה ביומן עבור האירוע.
מטא-נתונים יצירת רשומה ביומן. כולל מטא-נתונים, אבל לא כולל את גוף הבקשה או את גוף התגובה.
בקשה יצירת רשומה ביומן. כוללים את המטא-נתונים ואת גוף הבקשה, אבל לא את גוף התגובה.
RequestResponse יצירת רשומה ביומן. כוללים מטא-נתונים, את גוף הבקשה ואת גוף התשובה.

דוגמה לכלל: אם אירוע תואם לכלל, שרת Kubernetes API יוצר רשומה ביומן ברמה Request.

- level: Request
  userGroups: ["system:nodes"]
  verbs: ["update","patch"]
  resources:
    - group: "" # core
      resources: ["nodes/status", "pods/status"]
  omitStages:
    - "RequestReceived"

אירוע תואם לכלל אם כל התנאים הבאים מתקיימים:

  • האירוע לא תואם לאף כלל קודם בקובץ המדיניות.
  • הזהות שמבצעת את השיחה נמצאת בקבוצת המשתמשים system:nodes.
  • השיחה היא בקשת update או בקשת patch.
  • הבקשה היא למשאב nodes/status או למשאב pods/status.
  • האירוע לא מיועד לשלב RequestReceived בשיחה.

מדיניות ביקורת של GKE

כש-GKE מקבל רשומות ביומן משרת ה-API של Kubernetes, הוא מחיל את המדיניות שלו כדי לקבוע אילו רשומות ייכתבו ביומן Admin Activity של הפרויקט ואילו רשומות ייכתבו ביומן Data Access של הפרויקט.

ברוב המקרים, GKE מחיל את הכללים הבאים על רשומות ביומן שמגיעות משרת Kubernetes API:

  • רשומות שמייצגות בקשות מסוג create,‏ delete ו-update נכנסות ליומן Admin Activity.

  • רשומות שמייצגות בקשות של get, list ו-updateStatus נכנסות ליומן Data Access.

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

קובץ מדיניות הביקורת של Kubernetes לאשכולות GKE

באשכולות GKE, קובץ מדיניות הביקורת של Kubernetes מתחיל בכללים שמציינים שאירועים מסוימים לא צריכים להירשם ביומן בכלל. לדוגמה, הכלל הזה אומר שכל בקשת get של kubelet במשאב nodes או במשאב nodes/status לא צריכה להירשם ביומן. חשוב לזכור שרמת None פירושה שאירועים תואמים לא צריכים להירשם ביומן:

- level: None
  users: ["kubelet"] # legacy kubelet identity
  verbs: ["get"]
  resources:
    - group: "" # core
    resources: ["nodes", "nodes/status"]

אחרי רשימת הכללים level: None, בקובץ המדיניות יש רשימה של כללים שהם מקרים מיוחדים. לדוגמה, הנה כלל למקרה מיוחד שמורה לרשום ביומן בקשות מסוימות ברמה Metadata:

- level: Metadata
    resources:
      - group: "" # core
        resources: ["secrets", "configmaps"]
      - group: authentication.k8s.io
        resources: ["tokenreviews"]
    omitStages:
      - "RequestReceived"

אירוע תואם לכלל אם כל התנאים הבאים מתקיימים:

  • האירוע לא תואם לאף כלל קודם בקובץ המדיניות.
  • הבקשה היא לגבי משאב מהסוגים secrets, configmaps או tokenreviews.
  • האירוע לא מיועד לשלב RequestReceived בשיחה.

אחרי רשימת הכללים למקרים מיוחדים, יש בקובץ המדיניות כמה כללים כלליים. כדי לראות את הכללים הכלליים בסקריפט, צריך להחליף את הערך של known_apis בערך ${known_apis}. אחרי ההחלפה, מתקבל כלל כזה:

- level: Request
  verbs: ["get", "list", "watch"]
  resources:
    - group: "" # core
    - group: "admissionregistration.k8s.io"
    - group: "apiextensions.k8s.io"
    - group: "apiregistration.k8s.io"
    - group: "apps"
    - group: "authentication.k8s.io"
    - group: "authorization.k8s.io"
    - group: "autoscaling"
    - group: "batch"
    - group: "certificates.k8s.io"
    - group: "extensions"
    - group: "metrics.k8s.io"
    - group: "networking.k8s.io"
    - group: "policy"
    - group: "rbac.authorization.k8s.io"
    - group: "settings.k8s.io"
    - group: "storage.k8s.io"
  omitStages:
    - "RequestReceived"

הכלל חל על אירועים שלא תואמים לאף כלל קודם בקובץ המדיניות ולא נמצאים בשלב RequestReceived. הכלל קובע שבקשות get, list ו-watch בכל משאב ששייך לאחת מהקבוצות שמופיעות ברשימה צריכות להירשם ברמה Request.

הכלל הבא בקובץ המדיניות נראה כך:

- level: RequestResponse
  resources:
    - group: "" # core
    - group: "admissionregistration.k8s.io"
    - group: "apiextensions.k8s.io"
    - group: "apiregistration.k8s.io"
    - group: "apps"
    - group: "authentication.k8s.io"
    - group: "authorization.k8s.io"
    - group: "autoscaling"
    - group: "batch"
    - group: "certificates.k8s.io"
    - group: "extensions"
    - group: "metrics.k8s.io"
    - group: "networking.k8s.io"
    - group: "policy"
    - group: "rbac.authorization.k8s.io"
    - group: "settings.k8s.io"
    - group: "storage.k8s.io"
  omitStages:
    - "RequestReceived"

הכלל חל על אירועים שלא תואמים לאף כלל קודם בקובץ המדיניות ולא נמצאים בשלב RequestReceived. הכלל לא חל על בקשות הקריאה: get, list ו-watch. במקום זאת, הכלל חל על בקשות כתיבה כמו create, update ו-delete. הכלל קובע שבקשות כתיבה צריכות להירשם ברמה RequestResponse.

סיכום של מדיניות הביקורת של Kubernetes באשכולות GKE

סיכום של מדיניות הביקורת של Kubernetes עבור אשכולות GKE:

  • באופן כללי, בקשות כתיבה כמו create, update ו-delete מתועדות ברמה RequestResponse.

  • באופן כללי, אירועים של get, ‏list ו-watch נרשמים ברמה Metadata.

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

    • בקשות עדכון ובקשות תיקון של kubelet,‏ system:node-problem-detector או system:serviceaccount:kube-system:node-problem-detector במשאב nodes/status או במשאב pods/status מתועדות ברמת הבקשה.

    • בקשות עדכון ותיקון של כל זהות בקבוצה system:nodes במשאב nodes/status או במשאב pods/status מתועדות ברמת הבקשה.

    • בקשות deletecollection של system:serviceaccount:kube-system:namespace-controller מתועדות ברמת הבקשה.

    • בקשות במשאב secrets, במשאב configmaps או במשאב tokenreviews מתועדות ברמת המטא-נתונים.

  • בקשות מסוימות לא מתועדות בכלל. רשימה סופית של בקשות שלא נרשמות ביומן זמינה בכללי level: None המדיניות בסקריפט. הבקשות הבאות לא מתועדות:

    • בקשות של system:kube-proxy לצפייה במשאב endpoints, במשאב services או במשאב services/status.

    • קבלת בקשות מאת system:unsecured במשאב configmaps במרחב השמות kube-system.

    • קבלת בקשות מאת kubelet למשאב nodes או למשאב nodes/status.

    • קבלת בקשות על ידי כל זהות בקבוצה system:nodes במשאב nodes או במשאב nodes/status.

    • קבלת בקשות ועדכון שלהן באמצעות system:kube-controller-manager,‏ system:kube-scheduler או system:serviceaccount:endpoint-controller במשאב endpoints במרחב השמות kube-system.

    • קבלת בקשות מאת system:apiserver במשאב namespaces, במשאב namespaces/status או במשאב namespaces/finalize.

    • בקשות get ו-list לפי system:kube-controller-manager בכל משאב בקבוצה metrics.k8s.io.

    • בקשות לכתובות URL שתואמות ל-/healthz*, ל-/version או ל-/swagger*.

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