הגבלת תעבורת נתונים יוצאת (egress) משרת ה-API

כדי לשפר את האבטחה של רמת הבקרה של Google Kubernetes Engine‏ (GKE), אפשר להשבית את כתובות ה-IP החיצוניות של המכונות הווירטואליות (VM) ברמת הבקרה. במסמך הזה מוסבר למהנדסי אבטחה איך לשלוט בתעבורת נתונים יוצאת (egress) משרת ה-API של Kubernetes, ואיך להימנע משיבושים פוטנציאליים ב-webhooks של בקרת הכניסה.

כדאי להכיר את הנושאים הבאים:

רמות ההגבלה

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

  • אין תעבורת נתונים (NONE): משביתים את כתובת ה-IP החיצונית של כל מופע של מכונה וירטואלית במישור הבקרה ומנתבים את כל תעבורת הנתונים היוצאת של שרת ה-API אל חור שחור. לרמת ההגבלה הזו יש את ההשפעות הבאות:
    • ‫GKE חוסם תעבורת נתונים יוצאת ישירה משרת ה-API אל שרתי ה-webhook של בקרת הכניסה שפועלים מחוץ לאשכול. כל ה-webhooks של בקרת הכניסה שמשתמשים בכתובת URL או בכתובת IP כדי ליצור קשר עם שרת ה-webhook מושפעים.
    • ‫GKE חוסם כל תעבורת נתונים יוצאת ישירה משרת ה-API לשירותים חיצוניים, כולל האינטרנט ושירותיGoogle Cloud . התנועה לאימות GKE ולרכיבי מערכת כמו שרת המטא-נתונים לא מושפעת.
    • סוגים אחרים של תעבורת נתונים יוצאת (egress), כמו תעבורת נתונים קריטית של המערכת או תעבורת נתונים מהצמתים שלכם, לא מושפעים.
    • ‫GKE משתמש ב-ValidatingAdmissionPolicy כדי לדחות את היצירה של ValidatingWebhookConfigurations או MutatingWebhookConfigurations שמשתמשים בשדה clientConfig.url, או עדכונים שלהם.
  • כל התנועה (VIA_CONTROL_PLANE): שמירת כתובת ה-IP החיצונית של כל מופע של מישור הבקרה, ומתן אפשרות לשרת ה-API להשתמש בכתובת ה-IP לתנועת יציאה. האפשרות הזו מוגדרת כברירת מחדל ב-GKE.

מגבלות

אם משביתים את תעבורת הנתונים היוצאת (egress) על ידי הגדרת רמת ההגבלה ל-NONE, אי אפשר להשתמש בכתובות IP ציבוריות לשימוש פרטי (PUPI) באשכול.

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

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

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • מוודאים שיש לכם אשכול GKE Autopilot או Standard שפועלת בו גרסה 1.35.1-gke.1396000 ואילך. אפשר גם ליצור אשכול Autopilot.
  • אם יש לכם שרתי webhook חיצוניים, ודאו שאתם משתמשים בהפניה לשירות כדי ליצור קשר עם השרתים האלה. כשמשביתים את תעבורת הנתונים היוצאת משרת ה-API, כל ה-webhook שמשתמשים בכתובת URL כדי ליצור קשר עם שרת ה-webhook נכשלים. אין השפעה על ווּב-הוּקים שמנוהלים על ידי GKE.

התאמה אישית של תעבורת נתונים יוצאת משרת ה-API

כשיוצרים או מעדכנים אשכול, אפשר להתאים אישית את רמת ההגבלה של תעבורת הנתונים היוצאת משרת ה-API. כדי לעדכן אשכול קיים, משתמשים בדגל --control-plane-egress:

gcloud container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --control-plane-egress=CONTROL_PLANE_EGRESS_MODE

מחליפים את מה שכתוב בשדות הבאים:

  • ‫CLUSTER_NAME: השם של האשכול.
  • ‫CONTROL_PLANE_LOCATION: האזור או האזור של מישור הבקרה של האשכול, למשל us-central1 או us-central1-a.
  • ‫CONTROL_PLANE_EGRESS_MODE: רמת ההגבלה על תנועת נתונים יוצאת משרת ה-API. משתמשים באחד מהערכים הבאים:
    • ‫NONE: השבתה של כתובת ה-IP החיצונית של מופעי ה-VM של מישור הבקרה וחסימה של כל תעבורת הנתונים היוצאת הלא קריטית משרת ה-API. ‫GKE מונע יצירה של הגדרות חדשות של webhook שמשתמשות בשדה clientConfig.url.
    • ‫VIA_CONTROL_PLANE: שמירה על כתובת ה-IP החיצונית של המכונות הווירטואליות במישור הבקרה והתרת תעבורה יוצאת משרת ה-API. זה ערך ברירת המחדל.

אימות ההגבלה על תעבורת נתונים יוצאת

כדי לבדוק אם GKE חוסם תעבורת נתונים יוצאת (egress) משרת ה-API, אפשר להשתמש באחת מהשיטות הבאות:

  • בודקים את הגדרות האשכול:

    gcloud container clusters describe CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --format='value(controlPlaneEgress)'
    

    הפלט הוא אחד מהבאים:

    • ‫NONE: התנועה היוצאת מוגבלת.
    • ‫VIA_CONTROL_PLANE: תנועת היציאה לא מוגבלת.
  • כדי לבדוק את ההשפעה של השינויים על וווב-הוקים חדשים, נסו ליצור הגדרת וווב-הוק שמשתמשת בשדה clientConfig.url:

    cat <<EOF | kubectl apply -f -
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      name: test-webhook-config
    webhooks:
    - name: my-webhook.example.com
      clientConfig:
        url: "https://my-webhook.example.com:9443/my-webhook-path"
    

    הפלט אמור להיראות כך:

    ValidatingAdmissionPolicy 'gke-restrict-webhook-url' denied request: Egress
    traffic from the API server through the control plane is disabled. As a
    result, direct API server calls to external webhook servers are blocked.
    To connect to external webhooks, update any webhook configurations that use
    clientConfig.url to use clientConfig.service instead.
    

    הפלט הזה מציין שמדיניות ValidatingAdmissionPolicy של GKE מונעת מכם ליצור או לעדכן הגדרות של webhook עם השדה clientConfig.url. אם מוחקים את ValidatingAdmissionPolicy, אפשר ליצור או לעדכן את ההגדרה, אבל בקשות הגישה לא יגיעו לשרת ה-webhook.

  • כדי לבדוק את ההשפעה של השינויים על ה-webhook הקיים באשכול, נסו לשלוח בקשה ישירה לכתובת IP מחוץ לאשכול:

    1. מפעילים יומני API_SERVER באשכול.
    2. מוחקים את gke-restrict-webhook-url ValidatingAdmissionPolicy:

      kubectl delete validatingadmissionpolicy gke-restrict-webhook-url
      

      כשמוחקים את ValidatingAdmissionPolicy, אפשר ליצור או לעדכן הגדרות של webhook עם השדה clientConfig.url. האשכול יוצר מחדש באופן אוטומטי את ValidatingAdmissionPolicy, כך שהמעקף הזה הוא זמני.

    3. בשדה clientConfig.url של ValidatingWebhookConfiguration או MutatingWebhookConfiguration, מציינים כתובת IP או כתובת URL לשליחת בקשות. אפשר להשתמש בערך לדוגמה, כמו http://example.com או 203.0.113.100.

    4. בודקים את היומנים של שרת ה-API כדי לראות אם מופיעה הודעת שגיאה כמו זו:

      Error from server (InternalError): error when creating "STDIN":
        Internal error occurred: failed calling webhook
        WEBHOOK_NAME": failed to call
        webhook: Post "WEBHOOK_URL":
        proxyconnect tcp: dial tcp: lookup master-internet-access-unavailable.localhost
        on 169.254.169.254:53: no such host
      

      הפלט הזה מציין שלמרות שמדיניות ValidatingAdmissionPolicy נמחקה, בקשות הגישה לא יכולות להגיע לשרת webhook באמצעות כתובת ה-IP או כתובת ה-URL של השרת.

אחרי שמשביתים את כתובות ה-IP החיצוניות של המכונות הווירטואליות במישור הבקרה, GKE חוסם את התעבורה לכל ה-webhook שמשתמשים בכתובת URL כדי ליצור קשר עם שרתי webhook חיצוניים. כדי להגדיר נתיב חלופי לשימוש בשרת ה-API, צריך להשתמש בשדה clientConfig.service בהגדרת ה-webhook. מידע נוסף זמין במאמר בנושא הגדרה של webhook חיצוני.

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