הגברת האבטחה של האשכול

במאמר הזה מוסבר איך להקשיח את האבטחה של אשכולות שנוצרו באמצעות תוכנת Distributed Cloud ל-Bare Metal בלבד.

אבטחת הקונטיינרים באמצעות SELinux

כדי לאבטח את הקונטיינרים, אפשר להפעיל את SELinux, שנתמך ב-Red Hat Enterprise Linux ‏ (RHEL). אם המכונות המארחות שלכם מריצות RHEL ואתם רוצים להפעיל SELinux באשכול, אתם צריכים להפעיל SELinux בכל המכונות המארחות. פרטים נוספים מופיעים במאמר בנושא אבטחת קונטיינרים באמצעות SELinux.

שימוש ב-seccomp כדי להגביל קונטיינרים

מצב מחשוב מאובטח (seccomp) זמין בגרסה 1.11 ומעלה של Google Distributed Cloud. הפעלת קונטיינרים עם פרופיל seccomp משפרת את האבטחה של האשכול, כי היא מגבילה את קריאות המערכת שקונטיינרים יכולים לבצע לליבה. כך מצטמצם הסיכוי לניצול לרעה של נקודות חולשה בליבת המערכת.

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

איך משביתים את seccomp ברמת האשכול או בעומסי עבודה מסוימים

אפשר להשבית את seccomp רק במהלך יצירת אשכול או שדרוג אשכול. אי אפשר להשתמש ב-bmctl update כדי להשבית את התכונה הזו. אם רוצים להשבית את seccomp בתוך אשכול, מוסיפים את הקטע clusterSecurity הבא לקובץ התצורה של האשכול:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: example
  namespace: cluster-example
spec:
...
  clusterSecurity:
    enableSeccomp: false
...

במקרה הלא סביר שחלק מעומסי העבודה שלכם יצטרכו להפעיל קריאות למערכת ש-seccomp חוסם כברירת מחדל, לא תצטרכו להשבית את seccomp בכל האשכול. במקום זאת, אפשר לבחור עומסי עבודה ספציפיים להפעלה ב-unconfined mode. הפעלת עומס עבודה ב-unconfined mode משחררת את עומס העבודה מההגבלות שפרופיל seccomp מטיל על שאר האשכול.

כדי להריץ קונטיינר ב-unconfined mode, מוסיפים את הקטע securityContext הבא למניפסט של ה-Pod:

apiVersion: v1
kind: Pod
....
spec:
  securityContext:
    seccompProfile:
      type: Unconfined
....

לא להפעיל קונטיינרים כמשתמש root

כברירת מחדל, תהליכים בקונטיינרים מופעלים כ-root. זה יוצר בעיה פוטנציאלית באבטחה, כי אם תהליך יוצא מהקונטיינר, התהליך הזה פועל בתור root במחשב המארח. לכן מומלץ להריץ את כל עומסי העבודה כמשתמש שאינו Root.

בקטעים הבאים מתוארות שתי דרכים להפעלת קונטיינרים כמשתמשים ללא הרשאות root.

שיטה 1: הוספת ההוראה USER ב-Dockerfile

בשיטה הזו נעשה שימוש בDockerfile כדי לוודא שהמאגדים לא פועלים כמשתמש root ב-Dockerfile, אפשר לציין את המשתמש שהתהליך בתוך קונטיינר צריך לפעול בשמו. בקטע הקוד הבא מתוך Dockerfile אפשר לראות איך עושים את זה:

....

#Add a user with userid 8877 and name nonroot
RUN useradd −u 8877 nonroot

#Run Container as nonroot
USER nonroot
....

בדוגמה הזו, פקודת Linux‏ useradd -u יוצרת משתמש בשם nonroot בתוך הקונטיינר. למשתמש הזה יש מזהה משתמש (UID) ‏8877.

בשורה הבאה בפקודה Dockerfile מופעלת הפקודה USER nonroot. הפקודה הזו מציינת שמעכשיו והלאה בתמונה, הפקודות יופעלו בתור המשתמש nonroot.

נותנים הרשאות ל-UID‏ 8877 כדי שתהליכי מאגר התגים יוכלו לפעול בצורה תקינה עבור nonroot.

שיטה 2: הוספת שדות securityContext בקובץ המניפסט של Kubernetes

השיטה הזו משתמשת בקובץ מניפסט של Kubernetes כדי לוודא שהקונטיינרים לא פועלים כמשתמש root. הגדרות האבטחה מוגדרות עבור Pod, והגדרות האבטחה האלה חלות על כל הקונטיינרים ב-Pod.

בדוגמה הבאה מוצג קטע מקובץ מניפסט של Pod מסוים:

apiVersion: v1
kind: Pod
metadata:
  name: name-of-pod
spec:
  securityContext:
    runAsUser: 8877
    runAsGroup: 8877
....

השדה runAsUser מציין שכל התהליכים בכל מאגרי התגים ב-Pod יפעלו עם מזהה המשתמש 8877. השדה runAsGroup מציין שלתהליכים האלה יש מזהה קבוצה (GID) ראשי של 8877. חשוב לזכור להעניק את ההרשאות הנדרשות והמספיקות למזהה המשתמש 8877 כדי שתהליכי מאגר התגים יוכלו להתבצע בצורה תקינה.

כך מוודאים שהתהליכים בתוך קונטיינר יפעלו בתור UID 8877, שיש לו פחות הרשאות מאשר root.

קונטיינרים של מערכת בתוכנת Distributed Cloud עוזרים רק להתקין ולנהל אשכולות. אפשר לשלוט ב-UID וב-GID שמשמשים את הקונטיינרים האלה באמצעות השדה startUIDRangeRootlessContainers במפרט האשכול. ‫startUIDRangeRootlessContainers הוא שדה אופציונלי, ואם לא מציינים אותו, הערך שלו הוא 2000. הערכים המותרים של startUIDRangeRootlessContainers הם 1000-57000. אפשר לשנות את הערך של startUIDRangeRootlessContainers רק במהלך שדרוגים. קונטיינרים של המערכת משתמשים במזהי המשתמש (UID) ובמזהי הקבוצה (GID) בטווח startUIDRangeRootlessContainers עד startUIDRangeRootlessContainers + 2999.

בדוגמה הבאה מוצג קטע מקובץ מניפסט של משאב Cluster:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: name-of-cluster
spec:
 clusterSecurity:
    startUIDRangeRootlessContainers: 5000
...

בוחרים את הערך של startUIDRangeRootlessContainers כך שמרחבי ה-UID וה-GID שמשמשים את קובצי המערכת לא יחפפו לאלה שהוקצו לעומסי עבודה של משתמשים.

איך משביתים את מצב Rootless

החל מגרסה 1.10 של Google Distributed Cloud, קונטיינרים של מישור הבקרה של Kubernetes וקונטיינרים של המערכת פועלים כמשתמשים לא-ראשיים כברירת מחדל. מערכת Google Distributed Cloud מקצה למשתמשים האלה UID ו-GID בטווח 2000-4999. עם זאת, ההקצאה הזו עלולה לגרום לבעיות אם ה-UID וה-GID האלה כבר הוקצו לתהליכים שפועלים בסביבה שלכם.

החל מגרסה 1.11, אפשר להשבית את מצב rootless כשמשדרגים את האשכול. כשמשביתים את מצב rootless, קונטיינרים של מישור הבקרה של Kubernetes וקונטיינרים של המערכת פועלים כמשתמש root.

כדי להשבית את מצב rootless:

  1. מוסיפים את הקטע clusterSecurity הבא לקובץ התצורה של האשכול:

    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: example
      namespace: cluster-example
    spec:
    ...
      clusterSecurity:
        enableRootlessContainers: false
    ...
    
  2. משדרגים את האשכול. פרטים נוספים זמינים במאמר בנושא שדרוג אשכולות.

הגבלת היכולת של עומסי עבודה לשנות את עצמם

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

הכי טוב לא לתת לעומסי עבודה הרשאה לשנות את עצמם מלכתחילה. כשנדרש שינוי עצמי, אפשר להגביל את ההרשאות באמצעות החלת אילוצים של Gatekeeper או Policy Controller, כמו NoUpdateServiceAccount מספריית Gatekeeper בקוד פתוח, שמספקת כמה כללי מדיניות שימושיים לאבטחה.

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

parameters:
  allowedGroups:
  - system:masters
  allowedUsers: []

השבתה של יציאת kubelet לקריאה בלבד

החל מגרסה 1.15.0, ב-Google Distributed Cloud מושבתת כברירת מחדל יציאת 10255, יציאת הקריאה-בלבד של kubelet. כל עומסי העבודה של הלקוחות שמוגדרים לקרוא נתונים מיציאת kubelet הלא מאובטחת 10255 צריכים לעבור לשימוש ביציאת kubelet המאובטחת 10250.

רק באשכולות שנוצרו עם גרסה 1.15.0 ומעלה, היציאה הזו מושבתת כברירת מחדל. היציאה לקריאה בלבד של kubelet‏ 10255 נשארת נגישה לאשכולות שנוצרו עם גרסה נמוכה מ-1.15.0, גם אחרי שדרוג האשכול לגרסה 1.15.0 ומעלה.

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

מומלץ להשבית את יציאת ה-kubelet לקריאה בלבד לפי CIS Kubernetes Benchmark.

תחזוקה

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

מעקב אחרי עדכוני אבטחה דחופים

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

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

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

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

במאמר תיקון פרצות אבטחה מוסבר איך Google מטפלת בנקודות חולשה באבטחה ובתיקונים ל-GKE.

שדרוג אשכולות

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

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

אחד היתרונות הרבים של שדרוג אשכול הוא שהשדרוג מרענן אוטומטית את קובץ ה-kubeconfig של האשכול. קובץ kubeconfig מאמת משתמש באשכול. קובץ ה-kubeconfig מתווסף לספריית האשכול כשיוצרים אשכול באמצעות bmctl. השם והנתיב שמוגדרים כברירת מחדל הם bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig. כשמשדרגים אשכול, קובץ ה-kubeconfig של האשכול הזה מתחדש אוטומטית. אחרת, תוקף קובץ ה-kubeconfig פג שנה אחרי שהוא נוצר.

מידע על שדרוג האשכולות זמין במאמר בנושא שדרוג האשכולות.

שימוש ב-VPC Service Controls עם Cloud Interconnect או Cloud VPN

‫Cloud Interconnect מספק חיבורים עם זמן אחזור קצר וזמינות גבוהה, שמאפשרים להעביר נתונים בצורה אמינה בין מכונות Bare Metal מקומיות לביןGoogle Cloud רשתות ענן וירטואלי פרטי (VPC). מידע נוסף על Cloud Interconnect זמין במאמר סקירה כללית על הקצאת Dedicated Interconnect.

שירות Cloud VPN מחבר באופן מאובטח את הרשת השכנה לרשת של הענן הווירטואלי הפרטי (VPC) באמצעות חיבור IPsec VPN. מידע נוסף על Cloud VPN זמין בסקירה הכללית על Cloud VPN.

‫VPC Service Controls פועל עם Cloud Interconnect או עם Cloud VPN כדי לספק אבטחה נוספת לאשכולות. ‫VPC Service Controls עוזר לצמצם את הסיכון לזליגת נתונים. בעזרת VPC Service Controls אפשר להוסיף פרויקטים לגבולות גזרה לשירות שמגינים על המשאבים והשירותים מפני בקשות שמקורן מחוץ לגבולות הגזרה. מידע נוסף על גבולות גזרה לשירות זמין במאמר פרטים והגדרה של גבולות גזרה לשירות.

כדי להגן באופן מלא על האשכולות שנוצרו באמצעות Google Distributed Cloud, צריך להשתמש ב-VIP מוגבל ולהוסיף את ממשקי ה-API הבאים לגבולות הגזרה לשירות:

  • ‫Artifact Registry API‏ (artifactregistry.googleapis.com)
  • ‫מנהל המשאבים API‏ (cloudresourcemanager.googleapis.com)
  • ‫Compute Engine API ‏ (compute.googleapis.com)
  • ‫Connect gateway API ‏ (connectgateway.googleapis.com)
  • ‫Google Container Registry API‏ (containerregistry.googleapis.com)
  • GKE Connect API ‏ (gkeconnect.googleapis.com)
  • ‫GKE Hub API ‏ (gkehub.googleapis.com)
  • ‫GKE On-Prem API ‏ (gkeonprem.googleapis.com)
  • ‫API של ניהול זהויות והרשאות גישה (IAM) (iam.googleapis.com)
  • Cloud Logging API (logging.googleapis.com)
  • Cloud Monitoring API‏ (monitoring.googleapis.com)
  • ‫Config Monitoring for Ops API‏ (opsconfigmonitoring.googleapis.com)
  • ‫Service Control API ‏ (servicecontrol.googleapis.com)
  • Cloud Storage API (storage.googleapis.com)