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

תיאור הבעיה

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

הודעות שגיאה

  • יכול להיות שיוצגו הודעות שגיאה מסוג ECONRESET בלקוחות של Postman או Node.js.

  • יכול להיות ש-Curl יציג את השגיאה Connection reset by peer כשמבצעים קריאות HTTPS ישירות לכתובת ה-IP של Apigee Ingress. לדוגמה:

    curl https://1.2.3.4/basepath -H "Host: your.apigee.domain" -kv
    * Connected to 1.2.3.4 (1.2.3.4) port 443
    * (304) (OUT), TLS handshake, Client hello (1):
    * Recv failure: Connection reset by peer
    * Closing connection 
  • יכול להיות שיוצגו שגיאות שונות בלקוחות אחרים. עם זאת, התבנית תהיה זהה: הלקוח לא מצליח ליצור חיבור מלא במהלך לחיצת היד של TLS.

סיבות אפשריות

שער הכניסה (Ingress) של Apigee Hybrid מופעל כברירת מחדל עם Server Name Indication (SNI). הבעיה הזו יכולה לקרות אם הלקוח שלכם לא תומך ב-SNI ולא מוגדר מסלול Apigee עם wildcard כדי לאפשר ללקוחות שלא תומכים ב-SNI. כתוצאה מכך, לא נשלח ללקוח אישור ברירת מחדל של שרת TLS, ומתבצע איפוס של TCP בכניסה של Apigee.

אבחון

  1. בודקים אם הלקוח תומך ב-SNI. אם אתם כבר יודעים ש-SNI לא מופעל, אפשר להמשיך לשלב 4 כדי לאמת את ההגדרה של Apigee Hybrid.

    בודקים את יומני הגישה של Apigee Ingress כדי לזהות סימנים לבקשות לקוח ללא שם שרת SNI, ומוודאים שהמארחים הווירטואליים לא מוגדרים עם אישור ברירת מחדל ללקוחות שאינם SNI.

    • כדי לראות את רשימת ה-pods של apigee-ingressgateway, מריצים את הפקודה הבאה:
      kubectl -n apigee get pods -l app=apigee-ingressgateway

      פלט לדוגמה

      NAME                                                              READY   STATUS    RESTARTS   AGE
      apigee-ingressgateway-ext-ingress-myorg-hyb-8f2c412-dvrcp         2/2     Running   0          46h
      apigee-ingressgateway-ext-ingress-myorg-hyb-8f2c412-wg26k         2/2     Running   0          46h
      
    • קבלת היומנים של פוד apigee-ingressgateway.
      kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
      כאשר APIGEE_INGRESSGATEWAY_POD הוא פוד apigee-ingressgateway שמופיע בפלט הפקודה הקודמת.
    • דוגמה ליומן גישה:
      {
        "request_time": 1,
        "tls_protocol": null,
        "upstream_service_time": null,
        "request_method": null,
        "request_protocol": null,
        "upstream_response_time": null,
        "bytes_sent": 0,
        "start_time": "2025-05-19T04:46:20.117Z",
        "bytes_received": 0,
        "host": null,
        "upstream_cluster": null,
        "upstream_address": null,
        "remote_address": "10.138.0.28:19432",
        "request_path": null,
        "request_id": null,
        "user_agent": null,
        "status_details": "filter_chain_not_found",
        "request": "- - -",
        "status": 0,
        "x_forwarded_for": null,
        "apigee_dynamic_data": null,
        "upstream_response_flags": "NR",
        "sni_host": null
      }
      
    • מניתוח היומן שלמעלה אפשר להסיק את הפרטים הבאים:
      1. "sni_host": null: הלקוח לא תומך ב-SNI כי אין שם מארח SNI. לדוגמה, api-test.mydomain.com משויך לבקשה הזו.
      2. "status_details": "filter_chain_not_found" : אישורי השרת נבחרים על סמך filter chain שמבוסס על sni_host. אם לא קיים sni_host ולא מוגדר ערך ברירת מחדל, לא ניתן למצוא את filter chain. כלומר, לא מוחזר אישור שרת, כפי שאפשר לראות בדוגמה לבקשת לקוח.
      3. "status": 0: אין קוד סטטוס כי החיבור אופס.
  2. במקום לבדוק את היומנים, דרך מדויקת יותר לבדוק אם לקוח מפעיל SNI היא ללכוד מנות לפני Apigee Ingress או ב-Apigee Ingress עצמו. כך אפשר יהיה לקבוע אם הלקוח שולח את כותרת ה-SNI ללחיצת היד של TLS.
    1. כדי להריץ ב-Apigee Ingress ב-Google Kubernetes Engine, צריך SSH לצומת שבו פועל שער הכניסה, ולהתקין את toolbox ואת tcpdump.
      tcpdump -n -i any -s 0 'host IP_Address' -w FILE_NAME

      כאשר FILE_NAME הוא שם הקובץ, כולל הנתיב, שבו רוצים לשמור את הפלט של לכידת המנות.

    2. מנתחים את לכידת המנות באמצעות Wireshark או כלי דומה.
    3. הנה דוגמה לניתוח של לכידת מנות באמצעות Wireshark שבוצעה ב-Apigee Ingress. .
      • בפלט של לכידת המנות, הודעה מספר 83 מציינת שהלקוח (המקור) שלח הודעה מסוג Client Hello אל Apigee Ingress (היעד). client-hello.png
      • כשבוחרים את ההודעה Client Hello ובודקים את Handshake Protocol: Client Hello, רואים שההודעה Extension: server_name חסרה. client-hello-extension.png
      • לדוגמה, לקוח עם SNI מופעל יציג את Extension: server_name בפלט, כמו בדוגמה הבאה. client-hello-extension-sni.png
      • האישור הזה מצביע על כך שהלקוח לא שלח את server_name ל-Apigee Ingress.
      • מכיוון שלא נכלל SNI server_name בהודעה Client Hello, לא מוחזר אישור שרת, ו-Apigee Ingress סוגר את החיבור עם מנתוני RST.
  3. כדי לבדוק אם לקוחות שאינם SNI נתמכים, אפשר לבדוק נקודת קצה של Apigee באמצעות כלי כמו OpenSSL כדי לשלוח בקשות עם או בלי כותרת SNI.al.
    1. בודקים אם לקוחות שאינם SNI מופעלים.
      openssl s_client -connect api-test.mydomain.com:443 -noservername

      פלט לדוגמה

      Connecting to 1.2.3.4
      CONNECTED(00000005)
      write:errno=54
      ---
      no peer certificate available
      ---
      No client certificate CA names sent
      ---
      SSL handshake has read 0 bytes and written 299 bytes
      Verification: OK
      ---
      New, (NONE), Cipher is (NONE)
      This TLS version forbids renegotiation.
      Compression: NONE
      Expansion: NONE
      No ALPN negotiated
      Early data was not sent
      Verify return code: 0 (ok)
      ---
      
      
    2. בתגובה שלמעלה מופיעה ההודעה no peer certificate available, כלומר לקוחות SNI לא מופעלים בנתיב Apigee, כי העברנו את האפשרות ‎-noservername בפקודה. אם אישור עמית הוחזר במהלך השימוש בדגל ‎-noservername, זה מצביע על כך שהוגדר מסלול עם תו כללי.
  4. בודקים את הגדרות המסלול הנוכחיות של Apigee כדי לראות אם מוגדר מסלול עם wildcard במארח הווירטואלי, ואם הוא מופעל.
    1. כדי לראות את רשימת המסלולים המוגדרים ב-Apigee, מריצים את הפקודה הבאה:
      kubectl -n apigee get apigeeroutes 

      פלט לדוגמה

      NAME                                  STATE     AGE
      myorg-hyb-dev-grp-000-33620d0         running   2d1h
      non-sni                               running   17s
      
    2. בודקים כל נתיב ב-Apigee כדי לראות אם יש שמות מארחים שכוללים תו כללי.

      לכל נתיב Apigee, מריצים את הפקודה שסופקה כדי לאחזר מערך JSON של שמות המארחים המוגדרים שלו. מסלול עם תו כללי לחיפוש יסומן בכוכבית (*) בפלט.

      kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME

      דוגמה של מסלול myorg-hyb-dev-grp-000-33620d0:

      kubectl -n apigee get apigeeroute myorg-hyb-dev-grp-000-33620d0 -o jsonpath='{.spec.hostnames}'

      פלט לדוגמה

      ["api-test.mydomain.com"]

      דוגמה של מסלול non-sni:

      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.hostnames}'

      פלט לדוגמה

      ["*"]

      הנתיב non-sni apigeeroute הוא נתיב עם תו כללי לחיפוש כי הוא מכיל (*) כשם מארח.

    3. אם מוגדר נתיב עם תווים כלליים, לקוחות שאינם SNI מופעלים.
    4. במסלול עם התו הכללי, מוודאים שהדגל enableNonSniClient מוגדר כ-true. הפקודה הבאה מופעלת בנתיב של התו הכללי עם לקוח non-sni.
      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.enableNonSniClient}'

      פלט לדוגמה

      true
    5. אם מסלול ה-wildcard קיים והלקוחות שאינם SNI מופעלים, צריך לבדוק את ההגדרה של המארח הווירטואלי בקובץ overrides.yaml כדי לוודא שמסלול ה-wildcard מופיע ב-additionalGateways.
      virtualhosts:
      - name: dev-grp
        selector:
          app: apigee-ingressgateway
          ingress_name: ext-ingress
        sslCertPath: ./certs/keystore_dev-grp.pem
        sslKeyPath: ./certs/keystore_dev-grp.key
        additionalGateways: ["non-sni"]
        
    6. הערך additionalGateways יופיע בנתיב Apigee שמוגדר בהגדרות המארח הווירטואלי. משתמשים בפקודה הבאה כדי לוודא שההגדרה additionalGateway מופיעה בהגדרות של נתיב Apigee.
        kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME -o jsonpath='{.spec.additionalGateways}

      לדוגמה, במסלול myorg-hyb-dev-grp-000-33620d0 צריך להופיע המסלול non-sni כ-additionalGateway.

        kubectl -n apigee get apigeeroute myorg-hyb-dev-grp-000-33620d0 -o jsonpath='{.spec.additionalGateways}'

      פלט לדוגמה

      ["non-sni"]

    רזולוציה

    אם שלבי האבחון מצביעים על כך שהלקוח שלכם הוא לקוח שלא מופעל בו SNI, ולקוחות כאלה לא מופעלים או לא מוגדרים כראוי בהתקנת Apigee Hybrid, צריך לפעול לפי ההוראות במאמר בנושא הפעלת לקוחות שלא מופעל בהם SNI כדי לאפשר תנועה מלקוחות כאלה.

    צריך לאסוף נתוני אבחון

    אם הבעיה נמשכת גם אחרי שמבצעים את ההוראות שלמעלה, צריך לאסוף את נתוני האבחון הבאים ואז לפנות אל Cloud Customer Care:
    • Overrides.yaml
    • פלט של הפקודות הבאות
      • kubectl -n apigee get apigeeroutes
      • לכל אחד מהמסלולים שצוינו, מריצים את הפקודה: kubectl -n apigee describe apigeeroute
    • קבוצות סביבות שבהן הבעיה מתרחשת