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

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

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

רמות ההגבלה

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

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

מגבלות

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

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

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

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את gcloud CLI. אם התקנתם בעבר את ה-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 החיצונית של מכונות וירטואליות של מישורי הבקרה וחסימה של כל תנועת היציאה הלא קריטית משרת ה-API. ‫GKE מונע יצירה של הגדרות חדשות של webhook שמשתמשות בשדה clientConfig.url.
    • VIA_CONTROL_PLANE: שמירה של כתובת ה-IP החיצונית של המכונות הווירטואליות במישור הבקרה והתרת תעבורת נתונים יוצאת משרת ה-API. זה ערך ברירת המחדל.

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

כדי לבדוק אם GKE חוסם תנועת יציאה משרת ה-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 חיצוני.

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