אבטחת שער

בדף הזה מוסבר איך אפשר לאבטח שער באמצעות תכונות אבטחה שונות:

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

  • אישורים לאבטחת התנועה מלקוח לשער ומשער לשרתי קצה באמצעות TLS

  • מדיניות אבטחה של Google Cloud Armor להגנה על שירותים מפני מתקפות DDoS

  • שרת proxy לאימות זהויות (IAP) כדי לספק שכבת אימות והרשאה לפני שמאפשרים גישה לשירות

מידע נוסף על אבטחת שערים זמין במאמר אבטחת שערים.

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

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

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.

דרישות של GKE Gateway Controller

  • ‫Gateway API נתמך רק באשכולות VPC-native.
  • אם אתם משתמשים ב-GatewayClasses אזוריים או חוצי-אזורים, אתם צריכים להפעיל רשת משנה ל-proxy בלבד.
  • צריך להפעיל את התוסף HttpLoadBalancing באשכול.
  • אם אתם משתמשים ב-Istio, אתם צריכים לשדרג את Istio לאחת מהגרסאות הבאות:
    • גרסה 1.15.2 ואילך
    • ‫1.14.5 ואילך
    • ‫1.13.9 ואילך.
  • אם משתמשים ב-VPC משותף, צריך להקצות את התפקיד Compute Network User לחשבון השירות של GKE בפרויקט המארח של פרויקט השירות.

  • מוודאים שיש לכם אשכול קיים במצב Autopilot או במצב Standard. אם אתם צריכים כזה, צריך ליצור אשכול Autopilot.

הגבלות ומגבלות

בנוסף להגבלות ולמגבלות של בקר GKE Gateway, ההגבלות הבאות חלות באופן ספציפי על אבטחת Gateway:

  • גרסה GKE 1.28.4-gke.1083000 לא תומכת בהגדרות TLS באמצעות אישור SSL או Certificate Manager בשערי כניסה. כפתרון זמני לגרסת GKE הזו, אפשר להשתמש בסוד של Kubernetes.

  • אי אפשר להשתמש בהערה networking.gke.io/certmap עם tls.certificateRefs באותו משאב של שער. אם מפנים אל CertificateMap ב-Gateway, ‏ GKE יתייחס לזה כשגיאה.

  • Certificate Manager תומך באישורים בניהול עצמי ובאישורים בניהול Google. אישורים שמנוהלים על ידי Google תואמים לשערי אזוריים ולשערים גלובליים.

  • כשמשתמשים באישורי SSL שמנוהלים על ידי Google, צריך ליצור את אישורי ה-SSL מחוץ ל-GKE לפני שמצרפים אותם ל-Gateway.

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

  • בבקר Gateway אין תמיכה במשאב ManagedCertificate.

  • בבקר של שער הכניסה אין תמיכה בהערה networking.gke.io/managed-certificates.

  • אם מגדירים את Cloud CDN עם GKE Gateway, אי אפשר להפעיל גם IAP וגם Cloud CDN עם אותו Gateway, כולל מסלולים נפרדים עם Cloud CDN. אם אתם צריכים להפעיל את Cloud CDN עבור מסלול שמשתמש במשאב GCPHTTPFilter, אתם צריכים קודם להסיר כל GCPBackendPolicy קיים שמגדיר IAP עבור השער הזה.

  • המכסה של TrustConfig מידע על הגודל הכולל של כל משאבי TrustConfig בכל מיקום זמין במאמר מכסות ומגבלות של משאבים.

  • התאמה למיקום. משאב TrustConfig שאליו יש הפניה חייב להיות באותו מיקום (גלובלי או אזור ספציפי) כמו שער (Gateway) שמשתמש בשירות.

  • הגבלת מרחב שמות. משאב ה-BackendTLSPolicy ומשאב היעד שלו חייבים להיות באותו מרחב שמות.

רשימה של השדות הנתמכים ב-Gateway API והיכולות של משאבי GatewayClass שזמינים ב-GKE מופיעה במאמר יכולות GatewayClass.

אבטחת שער באמצעות סוד של Kubernetes

בדוגמה הזו, מגדירים Gateway באמצעות Kubernetes Secret.

אחסון אישור ב-Kubernetes Secret

אתם יכולים להשתמש באישור שהונפק ואומת על ידי רשות האישורים (CA) שלכם, או ליצור אישור עם חתימה עצמית. השלבים הבאים מתבססים על אישור בחתימה עצמית.

  1. יוצרים מפתח פרטי:

    openssl genrsa -out PRIVATE_KEY_FILE 2048
    

    מחליפים את PRIVATE_KEY_FILE בשם של קובץ המפתח הפרטי, כמו private-key.pem. מידע נוסף זמין במאמר בנושא בחירה או יצירה של מפתח פרטי.

  2. יוצרים קובץ תצורה של Open SSL:

    cat <<EOF >CONFIG_FILE
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    
    [dn_requirements]
    0.organizationName        = example
    commonName                = store.example.com
    
    [sans_list]
    DNS.1                     = store.example.com
    EOF
    

    מחליפים את CONFIG_FILE בשם של קובץ ההגדרות החדש, למשל config-file.cnf.

  3. יוצרים קובץ של בקשת חתימה על אישור (CSR):

    openssl req -new -key PRIVATE_KEY_FILE \
        -out CSR_FILE \
        -config CONFIG_FILE
    

    מחליפים את CSR_FILE בשם של קובץ ה-CSR החדש, כמו cert.pem. מידע נוסף זמין במאמר בנושא יצירת CSR.

  4. חתימה על ה-CSR:

    openssl x509 -req \
        -signkey PRIVATE_KEY_FILE \
        -in CSR_FILE \
        -out CERTIFICATE_FILE \
        -extfile CONFIG_FILE \
        -extensions extension_requirements \
        -days 30
    

    מחליפים את CERTIFICATE_FILE בנתיב ובשם של הקובץ שהפקודה יוצרת, כמו cert-file.pem. מידע נוסף זמין במאמר בנושא חתימה על בקשת אישור (CSR).

  5. יוצרים סוד TLS של Kubernetes באמצעות המפתח וקובץ האישור שיצרתם:

    kubectl create secret tls store-example-com \
        --cert=CERTIFICATE_FILE \
        --key=PRIVATE_KEY_FILE
    

    ‫GKE שומר את האישור והמפתח כמשאב Kubernetes שאפשר לצרף ל-Gateway.

יצירת שער ו-HTTPRoute

  1. שומרים את קובץ המניפסט הבא בשם external-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
          certificateRefs: # Directly reference the Kubernetes Secret containing the TLS certificate and private key.
          - name: store-example-com # The name of the TLS secret.
    

    במניפסט הזה מתואר שער עם המאפיינים הבאים:

    • gatewayClassName: gke-l7-global-external-managed: פריסה של מאזן עומסים גלובלי חיצוני של אפליקציות (ALB).
    • protocol: HTTPS ו-port: 443: נדרש להפעלת TLS.
    • tls: הפניה אל Kubernetes Secret שנוצר בשלב הקודם.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f external-gateway.yaml
    
  3. שומרים את קובץ המניפסט הבא בשם store-external-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http # Link this route to the 'external-http' Gateway.
      hostnames:
      - "store.example.com" # Match traffic for this hostname.
      rules:
      - backendRefs: # Define where to forward the traffic.
        - name: store-v1
          port: 8080
    

    קובץ המניפסט הזה מתאר HTTPRoute שתואם לתנועה אל store.example.com ושולח אותה לשירות store-v1.

  4. מחילים את המניפסט על האשכול:

    kubectl apply -f store-external-route.yaml
    

אימות השער

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

  1. מקבלים את כתובת ה-IP של השער:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

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

    203.0.113.12
    

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

  2. ניגשים לדומיין של השער באמצעות curl:

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
    

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

    • GATEWAY_IP_ADDRESS: כתובת ה-IP של מאזן העומסים של שער.
    • CERTIFICATE_FILE: קובץ האישור שיצרתם. צריך לשמור את הקובץ הזה במחשב שבו משתמשים כדי להתחבר לשער. האישור נדרש כדי לאמת את ה-Gateway כי הוא משתמש באישור עם חתימה עצמית.

    האפשרות --resolve פותרת את שם הדומיין לכתובת ה-IP של השער, וזה נדרש כי ה-DNS לא מוגדר לדומיין הזה.

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

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    # This block shows the certificate details presented by the Gateway.
    # The value of the 'common name' field matches the requested hostname.
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08"
      # Several lines of output omitted here.
    }
    

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

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

בדוגמה הזו, מגדירים שער עם אישור SSL בניהול Google.

יצירת אישור SSL

  1. יוצרים משאב גלובלי SslCertificate בניהול Google:

    gcloud compute ssl-certificates create store-example-com \
        --domains=store.example.com \
        --global
    

יצירת שער ו-HTTPRoute

  1. שומרים את קובץ המניפסט הבא בשם external-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate # Terminate TLS using your SSL certificate.
          options:
            networking.gke.io/pre-shared-certs: store-example-com # Specify the Google Cloud SSL certificate resource name.
    

    במניפסט הזה מתואר שער עם המאפיינים הבאים:

    • gatewayClassName: gke-l7-global-external-managed: פריסה של מאזן עומסים גלובלי חיצוני של אפליקציות (ALB).
    • protocol:HTTPS ו-port:443: נדרש להפעלת TLS.
    • tls.mode:Terminate: מסיימת את TLS באמצעות אישור ה-SSL שלכם.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f external-gateway.yaml
    
  3. שומרים את מניפסט ה-HTTPRoute הבא כ-store-external-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-v1
          port: 8080
    
  4. פורסים את ה-HTTPRoute באשכול:

    kubectl apply -f store-external-route.yaml
    

    יכול להיות שיחלפו כמה דקות עד ש-GKE יפרוס את ה-Gateway.

אימות השער

  1. מקבלים את כתובת ה-IP של השער:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

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

    203.0.113.12
    

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

  2. מעדכנים רשומת A או רשומת AAAA כדי להפנות את הדומיין לכתובת ה-IP של השער.

    השלב הזה נדרש רק אם אתם מגדירים אישור SSL שמנוהל על ידי Google. אם אתם מגדירים אישור בניהול עצמי, אתם יכולים לדלג על השלב הזה.

    אחרי העדכון של רשומות ה-DNS, יכולות לעבור עד 10 דקות עד שמאזן העומסים יתחיל להשתמש באישור שמנוהל על ידי Google.

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

    curl https://store.example.com -v
    

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

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

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

אבטחת שער באמצעות Certificate Manager

בדוגמה הזו, מגדירים Gateway באמצעות Certificate Manager.

יצירת Certificate

Global Gateway

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

  1. כדי ליצור אישור, קודם צריך ליצור מפתח פרטי וקובץ אישור.

  2. יוצרים משאב Certificate על ידי טעינת האישור והמפתח שמנוהלים באופן עצמאי:

    gcloud certificate-manager certificates create store-example-com-cert \
        --certificate-file="cert.pem" \
        --private-key-file="PRIVATE_KEY_FILE"
    
  3. יצירת CertificateMap:

    gcloud certificate-manager maps create store-example-com-map
    
  4. יוצרים CertificateMapEntry שמקצה את האישור ל-CertificateMap:

    gcloud certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

Regional Gateway

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

  1. יוצרים קובץ של מפתח פרטי ואישור.

  2. יוצרים משאב Certificate על ידי העלאת קובץ האישור והמפתח:

gcloud certificate-manager certificates create "CERTIFICATE_NAME" \
    --certificate-file="CERTIFICATE_FILE" \
    --private-key-file="PRIVATE_KEY_FILE" \
    --location="REGION"

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

  • CERTIFICATE_NAME: השם של האישור, לדוגמה store-example-com-cert.
  • CERTIFICATE_FILE: השם של קובץ האישור, לדוגמה, cert.pem.
  • PRIVATE_KEY_FILE: השם של קובץ המפתח הפרטי, למשל private-key.pem. מידע נוסף זמין במאמר בנושא בחירה או יצירה של מפתח פרטי.
  • REGION: שם האזור שבו מגדירים את שער הגישה, לדוגמה us-central1.

יצירת שער ו-HTTPRoute

Global Gateway

כדי ליצור שער גלובלי:

  1. שומרים את קובץ המניפסט הבא בשם cert-map-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
      # No TLS section is included here because TLS is handled by the certmap annotation.
    

    במניפסט הזה מתואר שער עם המאפיינים הבאים:

    • gatewayClassName: gke-l7-global-external-managed: פריסה של מאזן עומסים גלובלי חיצוני של אפליקציות (ALB).
    • protocol: HTTPS ו-port: 443: נדרש להפעלת TLS.

    אין קטע TLS כי TLS מוגדר באמצעות Certificate Manager באמצעות ההערה networking.gke.io/certmap.

  2. מחילים את המניפסט על האשכול:

    kubectl apply -f cert-map-gateway.yaml
    

    יכול להיות שיחלפו כמה דקות עד ש-GKE יפרוס את ה-Gateway.

  3. כדי ליצור HTTPRoute, שומרים את המניפסט הבא כ-cert-map-http-route.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: foo
      namespace: default
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - foo.example.com
      rules:
      - matches:
        - path:
            value: /
        backendRefs:
        - name: foo-v1
          port: 8080
    
  4. מחילים את המניפסט על האשכול:

    kubectl apply -f cert-map-http-route.yaml
    

Regional Gateway

כשיוצרים שער אזורי, אפשר לציין אישורים שמנוהלים על ידי Certificate Manager ואישורים שמנוהלים על ידי Compute Engine.

  1. כדי ליצור שער חיצוני אזורי, שומרים את המניפסט הבא בתור external-gateway.yaml:

       kind: Gateway
       apiVersion: gateway.networking.k8s.io/v1
       metadata:
         name: gateway
         namespace: corp
       spec:
         gatewayClassName: gke-l7-regional-external-managed
         listeners:
         - name: gateway-pre-shared-certmap
           protocol: HTTPS
           port: 443
           tls:
             mode: Terminate # TLS is terminated at the Gateway.
             options: # Specifies a comma-separated list of Certificate Manager certificates to use for TLS termination.
               networking.gke.io/cert-manager-certs: store-example-com-cert1, store-example-com-cert2 # These certificates are directly managed by Certificate Manager.
           allowedRoutes:
             kinds:
             - kind: HTTPRoute
             namespaces:
               from: All
    

    במניפסט הזה מתואר שער עם המאפיינים הבאים:

    • gatewayClassName: gke-l7-regional-external-managed: פריסה של מאזן עומסים חיצוני אזורי של אפליקציות (ALB).
    • protocol: HTTPS ו-port: 443: נדרש להפעלת TLS.
    • options:
      • networking.gke.io/cert-manager-certs : אישורים שמנוהלים על ידי Certificate Manager.

    כדי ליצור שער פנימי אזורי, בדוגמה הקודמת, משנים את הערך של gatewayClassName ל-gke-l7-rilb. התבנית הזו פורסת מאזן עומסים פנימי של אפליקציות (ALB).

  2. מחילים את המניפסט על האשכול:

    kubectl apply -f external-gateway.yaml
    
  3. כדי ליצור HTTPRoute, שומרים את המניפסט הבא כ-store-external-route.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
        backendRefs:
        - name: store-v1
          port: 8080
    

    קובץ המניפסט הזה מתאר HTTPRoute שתואם לתנועה של store.example.com ומעביר את התנועה לשירות store-v1.

  4. מחילים את המניפסט על האשכול:

    kubectl apply -f store-external-route.yaml
    

אימות השער

  1. מקבלים את כתובת ה-IP של השער:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

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

    203.0.113.12
    

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

  2. מעדכנים רשומת A או רשומת AAAA כדי להפנות את הדומיין לכתובת ה-IP של השער.

    השלב הזה נדרש רק אם אתם מגדירים אישור SSL שמנוהל על ידי Google. אם אתם מגדירים אישור בניהול עצמי, אתם יכולים לדלג על השלב הזה.

    אחרי העדכון של רשומות ה-DNS, יכולות לעבור עד 10 דקות עד שמאזן העומסים יתחיל להשתמש באישור שמנוהל על ידי Google.

  3. ניגשים לדומיין של השער באמצעות curl:

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
    

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

    • GATEWAY_IP_ADDRESS: כתובת ה-IP של מאזן העומסים של שער.
    • CERTIFICATE_FILE: קובץ האישור שיצרתם. צריך לשמור את הקובץ הזה במחשב שבו משתמשים כדי להתחבר לשער. האישור נדרש כדי לאמת את ה-Gateway כי הוא משתמש באישור עם חתימה עצמית.

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

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

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

הגדרת mTLS בקצה הקדמי של שער

אתם יכולים להגדיר אימות של אישורי לקוח, שנקרא גם mTLS בחזית, עבור שער GKE. ‫mTLS של Frontend נתמך ב-GatewayClasses‏ gke-l7-global-external-managed, ‏ gke-l7-regional-external-managed ו-gke-l7-rilb, ומאפשר לשער לאמת את האישורים שהלקוחות מציגים. הגדרת mTLS בחלק הקדמי תקפה למאזיני HTTPS שמשתמשים במצב Terminate.

אפשר להגדיר mTLS בקצה הקדמי באחת מהדרכים הבאות:

  • שימוש בהגדרת Gateway API (מומלץ).
  • שימוש בהערה TrustConfig בניהול עצמי בשער (מתקדם).

הגדרת mTLS בקצה הקדמי באמצעות הגדרת Gateway API (מומלץ)

הדרך המומלצת להגדיר אימות של אישורי לקוח היא באמצעות Gateway API. בשיטה הזו, מקורות מהימנים מאוחסנים ב-ConfigMap של Kubernetes, ומתבצעת הפניה אל ה-ConfigMap הזה במפרט של שער.

  1. יצירת מקורות מהימנים.

    מקורות מהימנים קובעים ומאמתים את בסיס המהימנות של אישורי לקוח שמוצגים למאזן העומסים. ‫GKE Gateway תומך במקורות מהימנים שמבוססים על אישורי בסיס.

    הוראות ליצירת אישורים מופיעות במאמר יצירת אישורי הבסיס והביניים.

  2. יוצרים ConfigMap.

    אחסון מקורות האמון ב-Kubernetes ConfigMap. כל מפתח ב-ConfigMap חייב להכיל אישור CA אחד בלבד בפורמט x509 תקין עם קידוד PEM. צריך ליצור את ה-ConfigMap הזה באותו מרחב שמות כמו משאב ה-Gateway, אלא אם משתמשים ב-ReferenceGrant. כדי להפנות אל ConfigMap במרחב שמות אחר, אפשר לעיין במאמר בנושא ReferenceGrant.

    ממקמים את נתוני האישור מתחת למפתח ca.crt:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-cert
    data:
      ca.crt: |
        -----BEGIN CERTIFICATE-----
        <PEM_DATA>
        -----END CERTIFICATE-----
    

    כדי ליצור ConfigMap עם האישורים שלכם, מריצים את הפקודה הבאה:

    kubectl create configmap my-config \
        --from-file=ca.crt=ROOT_CERT_PATH
    

    מחליפים את ROOT_CERT_PATH בנתיב לקובץ האישור. קובץ ConfigMap יכול להכיל רק אישור אחד.

  3. מגדירים את השער.

    כדי לצרף את ה-ConfigMap ל-Gateway, מוסיפים את הקטע tls שמכיל את השדה frontendValidation למפרט של ה-Gateway. ההגדרה default היא חובה והיא חלה על כל מאזיני ה-HTTPS שמשתמשים במצב Terminate, אלא אם מציינים הגדרה לכל יציאה. בדוגמה הבאה מוצגת הגדרה של Gateway מקצה לקצה שכוללת גם אישור שרת (באמצעות ההערה certmap) וגם אימות של אישור לקוח (באמצעות השדה tls.frontendValidation):

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-example
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      tls:
        frontendValidation:
          default:
            caCertificateRefs:
            - kind: ConfigMap
              group: ""
              name: my-config
      listeners:
      - name: foo-https
        protocol: HTTPS
        port: 443
        hostname: foo.example.com
        tls:
          mode: Terminate
          # No certificateRefs needed when using the certmap annotation
    
  4. ביטול ההגדרה לכל יציאה.

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

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-port-override
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      tls:
        frontendValidation:
          default:
            caCertificateRefs:
            - kind: ConfigMap
              group: ""
              name: global-ca-config
          perPort:
          - port: 8443
            tls:
              validation:
                caCertificateRefs:
                - kind: ConfigMap
                  group: ""
                  name: port-specific-ca-config
      listeners:
      - name: https-default
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
      - name: https-override
        protocol: HTTPS
        port: 8443
        tls:
          mode: Terminate
    
  5. אופציונלי: הגדרת מצב אימות הלקוח.

    כברירת מחדל, שערים של GKE אוכפים אימות קפדני של אישורי לקוח (AllowValidOnly). כדי לאפשר אישורי לקוח לא תקינים או חסרים, בהגדרות של frontendValidation.default, צריך להגדיר את הערך של המפתח mode ל-AllowInsecureFallback:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-example
      annotations:
        networking.gke.io/certmap: store-example-com-map # Add this annotation
    spec:
      gatewayClassName: gke-l7-global-external-managed
      tls:
        frontendValidation:
          default:
            caCertificateRefs:
            - kind: ConfigMap
              group: ""
              name: my-config
            mode: AllowInsecureFallback
      listeners:
      - name: foo-https
        protocol: HTTPS
        port: 443
        hostname: foo.example.com
        tls:
          mode: Terminate
          # No certificateRefs needed when using the certmap annotation
    

שימוש ב-TrustConfig בניהול עצמי (מתקדם)

אפשר גם להגדיר אימות של אישור לקוח באמצעות הוספת הערה ל-Gateway עם משאב TrustConfig. משתמשים בשיטה הזו לניהול עצמי אם נדרשת גמישות נוספת או אם ההגדרה חורגת מהמגבלות הרגילות של Gateway API. השיטה הזו לא יכולה לפעול במקביל לשיטת ההגדרה של Gateway API, והיא חלה על כל מאזיני ה-HTTPS ב-Gateway (לא אפשרי לבצע שינויים מברירת המחדל לכל יציאה).

  1. יוצרים משאב TrustConfig. הוראות מפורטות מופיעות במאמר יצירת משאב של הגדרת הרשאות שיתוף.

    כשיוצרים את משאב TrustConfig, צריך לציין global עבור שערים גלובליים (gke-l7-global-external-managed) או את האזור המתאים (לדוגמה, us-central1) עבור שערים אזוריים (gke-l7-regional-external-managed ו-gke-l7-rilb).

  2. מצרפים את TrustConfig ל-Gateway באמצעות ההערה networking.gke.io/frontend-trust-config.

    בדוגמה הבאה מוצגת הגדרה של Gateway מקצה לקצה שכוללת גם אישור שרת (באמצעות ההערה certmap) וגם אימות של אישור לקוח (באמצעות ההערה TrustConfig):

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-example
      annotations:
        networking.gke.io/frontend-trust-config: my-trust-config
        networking.gke.io/certmap: store-example-com-map # Add this annotation
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: foo-https
        protocol: HTTPS
        port: 443
        hostname: foo.example.com
        tls:
          mode: Terminate
          # Remove certificateRefs and replace with the comment
          # No certificateRefs needed when using the certmap annotation
    
  3. אופציונלי: הגדרת מצב אימות הלקוח.

    כברירת מחדל, שערים של GKE אוכפים אימות קפדני של אישורי לקוח (REJECT_INVALID). כדי לאפשר אישורי לקוח לא תקינים או חסרים, צריך להגדיר את ההערה networking.gke.io/allow-invalid-or-missing-client-cert לערך true.

הגדרת TLS בקצה העורפי של שער

ה-TLS בקצה העורפי מאפשר למאזן העומסים של GKE Gateway לאמת את הזהות של הקצוות העורפיים שהוא מתחבר אליהם. ב-TLS בקצה העורפי, נוסף שלב אימות מפורש במהלך לחיצת היד של TLS בין שער הכניסה לבין ה-Pod בקצה העורפי. השער פועל כלקוח TLS, ומאמת את האישור של שרת הקצה האחורי מול קבוצה של רשויות אישורים (CA) מהימנות שאתם מגדירים. האימות הזה מתבצע כשנוצר חיבור חדש, כדי לוודא ששער הגישה מתקשר רק עם מערכות קצה מהימנות וכדי לשפר את האבטחה הכוללת.

אתם יכולים להגדיר TLS מאומת של קצה עורפי באמצעות משאב BackendTLSPolicy שמצורף ל-Service,‏ InferencePool,‏ ServiceImport או GCPInferencePoolImport. ה-BackendTLSPolicy צריך להיות באותו מרחב שמות כמו משאב היעד.

יש תמיכה ב-TLS בשרת העורפי עבור GatewayClasses הבאים:

  • gke-l7-global-external-managed
  • gke-l7-regional-external-managed
  • gke-l7-rilb

שימוש ב-ConfigMap של Kubernetes (רגיל)

בשיטה הזו, מספקים את אישור ה-CA ישירות ב-ConfigMap של Kubernetes.

  1. יוצרים משאב ConfigMap שמכיל את אישורי ה-CA בקידוד PEM. מידע נוסף זמין במאמר בנושא דרישות האישורים. כל ConfigMap צריך להכיל רק אישור CA אחד. צריך ליצור את ה-ConfigMap הזה באותו מרחב שמות כמו משאב ה-BackendTLSPolicy. ‫BackendTLSPolicy לא תומך בהפניות חוצות למרחבי שמות למשאבי ConfigMap.

    נתוני האישור צריכים להיות מתחת למפתח ca.crt:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-backend-ca
    data:
      ca.crt: |
        -----BEGIN CERTIFICATE-----
        PEM_DATA
        -----END CERTIFICATE-----
    

    מחליפים את PEM_DATA בתוכן של אישור ה-CA בפורמט PEM ובקידוד Base64.

  2. הגדרת יעד לשירות, ל-InferencePool, ל-ServiceImport או ל-GCPInferencePoolImport באמצעות BackendTLSPolicy שמפנה אל ConfigMap:

    שירות

    במניפסט הבא מוצגת מדיניות BackendTLSPolicy שמטרגטת שירות:

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy
    spec:
      targetRefs:
      - group: "" # empty group means Core API.
        kind: Service
        name: my-service-name
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

    InferencePool

    במניפסט הבא מוצגת BackendTLSPolicy שמטרגטת InferencePool:

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy-inferencepool
    spec:
      targetRefs:
      - group: "inference.networking.k8s.io" # For InferencePool
        kind: InferencePool
        name: my-inference-pool
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

    ServiceImport

    במניפסט הבא מוצגת מדיניות BackendTLSPolicy שמטרגטת ServiceImport:

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy-serviceimport
    spec:
      targetRefs:
      - group: "net.gke.io" # For ServiceImport
        kind: ServiceImport
        name: my-service-import
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

    GCPInferencePoolImport

    במניפסט הבא מוצגת מדיניות BackendTLSPolicy שמטרגטת GCPInferencePoolImport:

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy-gcpinferencepoolimport
    spec:
      targetRefs:
      - group: "networking.gke.io" # For GCPInferencePoolImport
        kind: GCPInferencePoolImport
        name: my-gcp-inference-pool-import
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

שימוש ב-TrustConfig בניהול עצמי (מתקדם)

בשיטה הזו אפשר להפנות למשאב TrustConfig שמנוהל בנפרד ב Google CloudCertificate Manager.

  1. יוצרים משאב TrustConfig ב-Certificate Manager. צריך ליצור את TrustConfig באותו פרויקט ובאותו מיקום שבהם נוצר ה-Gateway.

    • בשערי גלובליים או מרובי-אשכולות (כולל מרובי-אשכולות אזוריים) ובשערי חוצי-אזורים, משתמשים במיקום global.
    • בשערים אזוריים עם אשכול יחיד, משתמשים באותו אזור כמו השער.
    • אם השירות שלכם נמצא בשימוש של כמה שערים במיקומים שונים, אתם צריכים ליצור משאב TrustConfig עם אותו שם בכל אחד מהמיקומים האלה.
  2. טרגוט של שירות באמצעות BackendTLSPolicy שמפנה למשאב TrustConfig חיצוני דרך השדה options:

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy
    spec:
      targetRefs:
      - group: "" # empty group means Core API.
        kind: Service
        name: my-service-name
      validation:
        wellKnownCACertificates: "System"
        hostname: "backend.example.com"
        options:
          networking.gke.io/backend-trust-config: "my-trust-config-name"
    

הפניה לשדה BackendTLSPolicy

בטבלה הבאה מתוארים שדות המפתח במשאב BackendTLSPolicy:

שדה תיאור
targetRefs המשאבים בעורף שאליהם המדיניות הזו חלה. תומך ב-Service ‏ (group: ""), ב-InferencePool ‏ (group: "inference.networking.k8s.io"), ב-ServiceImport ‏ (group: "net.gke.io") או ב-GCPInferencePoolImport ‏ (group: "networking.gke.io"). הערה: עבור ‏gke-l7-global-external-managed ו-gke-l7-global-external-managed-mc GatewayClasses, נתמכים רק קצה עורפי של Service ו-ServiceImport.
validation.hostname שם המארח (SNI) שמשמש את שער הכניסה במהלך לחיצת היד של TLS עם פודים של קצה העורפי.
validation.subjectAltNames זה שינוי אופציונלי. מגדיר שם נושא חלופי אחד או יותר (SAN) כדי לאמת את האישור של ה-Backend. תמיכה ב-Hostname וב-URI (למשל, מזהי SPIFFE).
validation.caCertificateRefs שיטה רגילה. הפניה לרשימה של משאבי ConfigMap (עד שמונה) באותו מרחב שמות. כל ConfigMap צריך להכיל אישור CA אחד בקידוד PEM, מתחת למפתח ca.crt. אין תמיכה בהפניות בין מרחבי שמות.
validation.wellKnownCACertificates שיטה מתקדמת. מגדירים את הערך ל-System כשמשתמשים ב-TrustConfig בניהול עצמי.
options מפה של אפשרויות ספציפיות ל-GKE. משתמשים בהגדרה networking.gke.io/backend-trust-config כדי להפנות למשאב TrustConfig חיצוני.

אימות ההגדרות של TLS בשרת העורפי

אחרי שמחילים את BackendTLSPolicy, בודקים את סטטוס המדיניות כדי לוודא שבקר ה-Gateway קיבל את ההגדרה:

kubectl describe backendtlspolicy POLICY_NAME

מחליפים את POLICY_NAME בשם המדיניות.

מדיניות מוחלת בהצלחה אם היא מכילה תנאים Accepted ו-ResolvedRefs עם Status: "True" בקטע Status.Ancestors:

Status:
  Ancestors:
  - Ancestor Ref:
      Group: gateway.networking.k8s.io
      Kind: Gateway
      Name: my-gateway-name
      Namespace: default
    Conditions:
    - Last Transition Time: "2026-02-17T15:19:26Z"
      Message: ""
      Reason: Accepted
      Status: "True"
      Type: Accepted
    - Last Transition Time: "2026-02-17T15:19:26Z"
      Message: ""
      Reason: ResolvedRefs
      Status: "True"
      Type: ResolvedRefs
    Controller Name: networking.gke.io/gateway

אם הערך של Status הוא False עבור אחד מהתנאים האלה, המשמעות היא שהמדיניות לא הוחלה. פרטים נוספים זמינים בשדות Reason ו-Message. שגיאות נפוצות כוללות הפניה אל ConfigMap ב-caCertificateRefs שלא קיים או שחסר בו המפתח ca.crt.

הסטטוס הזה מאשר שהשער אימת בהצלחה את המדיניות והחיל את הגדרות ה-TLS על ה-backends של שירות היעד או של InferencePool. משאב BackendTLSPolicy צריך להיות באותו מרחב שמות כמו משאב היעד.

איך מאבטחים את מאזן העומסים לתעבורת נתונים של אפליקציות באמצעות TLS

אתם יכולים להצפין את התנועה ממאזן העומסים אל ה-Pods של הבק-אנד באמצעות השדה ports[].appProtocol. השדות הנתמכים עבור appProtocol הם: HTTP,‏ HTTPS,‏ HTTP2 ו-kubernetes.io/h2c.

במניפסט הבא מתואר שירות שמציין שמאזן העומסים חייב להשתמש בתנועת HTTPS כדי לתקשר עם ה-Pods של הקצה העורפי:

apiVersion: v1
kind: Service
metadata:
  name: store-v2
spec:
  selector:
    app: store
    version: v2
  ports:
  - port: 8080
    targetPort: 8080
    appProtocol: HTTPS

מאזן העומסים לא מאמת את האישור שמשמש את ה-Pods של הקצה העורפי. באחריותכם לוודא שהאישור שבו נעשה שימוש ב-Pods של קצה עורפי תקף.

אבטחת התנועה מלקוח למאזן העומסים באמצעות כללי מדיניות SSL

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

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

הגנה על השרתים העורפיים באמצעות Google Cloud Armor

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

במאמר הגדרת כללי מדיניות האבטחה של Google Cloud Armor כדי לאבטח את שירותי ה-Backend מוסבר איך מגדירים מדיניות של Google Cloud Armor באמצעות Gateway.

אימות בקשות לשרתי קצה עורפיים באמצעות שרת proxy לאימות זהויות (IAP)

שרת proxy לאימות זהויות (IAP) עוזר להגן על הקצה העורפי מפני תנועה לא רצויה על ידי אימות לקוחות ששולחים בקשות לאפליקציות ואכיפת הרשאות תנועה מבוססות-תפקידים. אחרי שמפעילים את שרת ה-proxy לאימות זהויות (IAP) ב-GKE, אפשר להפנות לפרטי הכניסה של OAuth ב-GCPBackendPolicy שמוחל על שירותי Kubernetes.

כדי להגדיר שרת proxy לאימות זהויות (IAP) עם Gateway, ראו הגדרת שרת proxy לאימות זהויות (IAP).

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