שגיאה 400 - בקשת HTTP פשוטה נשלחה ליציאת HTTPS

מוצג המסמך של Apigee Edge.
עוברים אל מסמכי תיעוד של Apigee X.
מידע

תיאור הבעיה

אפליקציית הלקוח מקבלת את התשובה HTTP 400 Bad Request עם ההודעה The plain HTTP request was sent to HTTPS port.

הודעת שגיאה

אפליקציית הלקוח מקבלת את קוד התגובה הבא:

HTTP/1.1 400 Bad Request

אחריו מופיע דף שגיאת ה-HTML הבא:

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>

גורמים אפשריים

סיבה תיאור הוראות לפתרון בעיות עבור
בקשת HTTP למארח וירטואלי שהוגדר ל-TLS הלקוח שולח בקשת HTTP למארח וירטואלי שהוגדר ל-TLS משתמשי Edge בענן הציבורי והפרטי
בקשת HTTP לנקודת קצה (endpoint) שהוגדרה ל-TLS נשלחה בקשת HTTP לשרת עורפי שתומך ב-TLS בנקודת הקצה של היעד. משתמשי Edge בענן הציבורי והפרטי
הגדרה שגויה של שרת היעד שרת היעד מוגדר עם יציאה מאובטחת 443, אבל SSL לא מופעל. משתמשי Edge בענן הציבורי והפרטי

הסיבה: בקשת HTTP למארח וירטואלי שהוגדר ל-TLS

השגיאה הזו מתרחשת כשלקוח מנסה להתחבר ל-API ב-Apigee המארח הווירטואלי מוגדר לשימוש ב-SSL ומקבל בקשת HTTP במקום זאת.

אבחון

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

  1. צריך לאמת את בקשת ה-API ולבדוק אם נשלחת בקשת HTTP לכינוי מארח מוגדר לקבל בקשות רק ביציאה המאובטחת 443. אם כן, אז זה הגורם לבעיה.

    דוגמה לבקשת API שגויה:

    curl http://org-test.apigee.net:443/400-demo
    
    <html>
    <head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
    <body>
    <center><h1>400 Bad Request</h1></center>
    <center>The plain HTTP request was sent to HTTPS port</center>
    <hr><center>server</center>
    </body>
    </html>
    
  2. בבקשה לדוגמה שלמעלה, שימו לב שנשלחת בקשת HTTP אל הכינוי של המארח myorg-test.apigee.net ביציאה המאובטחת 443. זאת הסיבה שגיאה אחת (400 Bad Request).

רזולוציה

צריך לוודא שהלקוח משתמש ב-HTTP ולא ב-HTTP ולשלוח את הבקשה הנכונה בתור מוצגת למטה:

בקשת API לדוגמה:

curl https://org-test.apigee.net:443/400-demo

או

curl https://org-test.apigee.net/400-demo
< HTTP/1.1 200 OK
< Date: Thu, 25 Feb 2021 13:01:43 GMT
< Content-Type: text/xml;charset=UTF-8
< Content-Length: 403
< Connection: keep-alive
< Server: gunicorn/19.9.0
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true

הסיבה: בקשת HTTP לנקודת קצה (endpoint) מוגדרת ל-TLS (אבטחת שכבת התעבורה)

שגיאה זו מתרחשת אם הגדרת באופן שגוי בקשות HTTP לקצה עורפי התומך ב-TLS בנקודת הקצה (endpoint) של היעד של שרת Proxy ל-API.

אבחון

צריך לבצע את השלבים הבאים כדי לאבחן את השגיאה באמצעות כלי המעקב:

  1. מפעילים את האפשרות Trace בממשק המשתמש של Apigee לשרת ה-proxy ל-API שהושפע.
  2. מעבירים בקשות ל-proxy ל-API.
  3. צריך לבחור אחת מבקשות ה-API שנכשלו עם קוד התגובה 400.
  4. מנווטים בין השלבים השונים ומציינים איפה התרחש הכשל.
  5. בדרך כלל אמורה להופיע תגובת השגיאה 400 שמגיעה משרת הקצה העורפי. כלומר, תראו את תגובת השגיאה 400 בשלב התגובה התקבלה משרת היעד כפי שמוצג כאן:

  6. כדי לקבוע מהי נקודת הקצה (endpoint) של היעד שעבורה נשלחה הבקשה, לוחצים על AX. (נתוני Analytics נרשמו) במעקב.

  7. חשוב לשים לב ל-target.url, שמכיל את הפרוטוקול, את הכינוי של המארח של שרת הקצה העורפי, ולפעמים את מספר היציאה. היציאה שבה נעשה שימוש עבור כתובת ה-URL של היעד היא 443 אבל הפרוטוקול הוא HTTP.
  8. כדאי לבדוק את ההגדרה של נקודת הקצה (endpoint) של היעד כדי להבין את ההגדרה.
  9. צריך לוודא שמארח שרת הקצה העורפי מאובטח ומאזינים ביציאה מאובטחת כמו 443. אם נעשה שימוש בפרוטוקול כ-http ברכיב <URL>, אז: זו הסיבה לבעיה.

    הגדרה לדוגמה של נקודת קצה (endpoint) של יעד:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <TargetEndpoint name="default">
        <Description/>
        <FaultRules/>
        <PreFlow name="PreFlow">
            <Request/>
            <Response/>
        </PreFlow>
        <PostFlow name="PostFlow">
            <Request/>
            <Response/>
        </PostFlow>
        <Flows/>
        <HTTPTargetConnection>
            <Properties/>
            <URL>http://somehost.org:443/get</URL>
        </HTTPTargetConnection>
    </TargetEndpoint>
    

    הדוגמה שלמעלה מראה שאתם משתמשים בפרוטוקול HTTP, אבל היציאה שבה נעשה שימוש מאובטחת יציאה 443. הדבר גורם לשרת העורפי להגיב עם 400 Bad Request והודעת השגיאה The plain HTTP request was sent to HTTPS port.

רזולוציה

  1. אם שרת הקצה העורפי מאובטח/תומך ב-TLS, עליכם לוודא שאתם משתמשים בפרוטוקול בתור https ברכיב <URL> של נקודת הקצה של היעד כפי שמוצג לדוגמה:

    הגדרה לדוגמה של נקודת קצה (endpoint) של יעד:

    <HTTPTargetConnection>
        <Properties/>
        <URL>https://somehost.org:443/get</URL>
    </HTTPTargetConnection>
    
  2. אם שרת הקצה העורפי לא מאובטח, אז:

    • אין לציין את מספר היציאה המאובטחת, כמו 443.
    • אין צורך לציין את מספר היציאה בכלל, אם שרת הקצה העורפי שלכם מאזין יציאה רגילה לא מאובטחת
    • צריך לציין את מספר היציאה אם משתמשים ביציאה לא מאובטחת אחרת, לדוגמה: 9080

    הגדרה לדוגמה של נקודת קצה (endpoint) של יעד:

    <HTTPTargetConnection>
        <Properties/>
        <URL>http://somehost.org/get</URL>
    </HTTPTargetConnection>
    
    or
    
    <HTTPTargetConnection>
        <Properties/>
        <URL>http://somehost.org:9080/get</URL>
    </HTTPTargetConnection>
    

הסיבה: הגדרה שגויה של שרת היעד

אם שרת היעד הוגדר עם יציאה מאובטחת, כמו 443 בלי להפעיל SSL, ואז הוא גורם למעבד ההודעות של Apigee Edge לשלוח בקשות HTTP שרת יעד בהגדרת TLS שמוביל לבעיה הזו.

אבחון

צריך לבצע את השלבים הבאים כדי לאבחן את השגיאה באמצעות כלי המעקב:

  1. מפעילים את האפשרות Trace בממשק המשתמש של Apigee לשרת ה-proxy ל-API שהושפע.
  2. מעבירים בקשות ל-proxy ל-API.
  3. צריך לבחור אחת מבקשות ה-API שנכשלו עם קוד התגובה 400.
  4. מנווטים בין השלבים השונים ומציינים איפה התרחש הכשל.
  5. בדרך כלל תופיע 400 תגובת השגיאה שמגיעה משרת הקצה העורפי. כלומר, תראו את תגובת השגיאה 400 בשלב התגובה התקבלה משרת היעד כפי שמוצג כאן:

  6. כדי לקבוע מהי נקודת הקצה (endpoint) של היעד שעבורה נשלחה הבקשה, לוחצים על AX. (נתוני Analytics נרשמו) במעקב.

  7. שימו לב ל-target.name, שמייצג את השם של נקודת הקצה כיעד.

    בקובץ המעקב לדוגמה שלמעלה, target.name הוא ברירת המחדל. המשמעות היא שנקודת הקצה (endpoint) היעד של הבקשה הזו היא ברירת המחדל.

  8. כדאי לבדוק את ההגדרה של נקודת הקצה (endpoint) של היעד כדי להבין את ההגדרה.

    הגדרה לדוגמה של נקודת קצה (endpoint) של יעד:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <TargetEndpoint name="default">
        <Description/>
        <FaultRules/>
        <PreFlow name="PreFlow">
            <Request/>
            <Response/>
        </PreFlow>
        <PostFlow name="PostFlow">
            <Request/>
            <Response/>
        </PostFlow>
        <Flows/>
        <HTTPTargetConnection>
            <Properties/>
            <LoadBalancer>
            <Server name="faulty-target"/>
            </LoadBalancer>
        </HTTPTargetConnection>
    </TargetEndpoint>
    

    הדוגמה שלמעלה בהגדרה של נקודת הקצה של היעד מראה שנעשה שימוש בשרת יעד בשם faulty-target.

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

    • ממשק המשתמש של Edge
    • Management API

ממשק המשתמש של Edge

  1. עוברים אל Apigee Edge > אדמין > סביבות > שרתי היעד.
  2. בוחרים את שרת היעד הספציפי שזוהה מ-proxy ל-API ולוחצים על עריכה.
  3. אימות היציאה שצוינה עבור שרת היעד ופרטי ה-SSL.
  4. אם בשרת היעד מוגדר יציאה מאובטחת (לדוגמה: 443), אבל SSL לא מופעל, אז זו הסיבה לבעיה.

    כמו שאפשר לראות בצילום המסך שלמעלה, היציאה שבה נעשה שימוש היא 443 אבל SSL לא מופעל עבור היציאה הזו בתצורה של שרת היעד. זה יגרום להודעה של Apigee Edge מעבד לשלוח בקשות HTTP ליציאה המאובטחת 443. לכן, מקבלים שגיאה 400 Bad Request עם ההודעה The plain HTTP request was sent to HTTPS port.

Management API

  1. להפעיל את אחזור API של שרת יעד כדי לקבל את הפרטים לגבי ההגדרה הספציפית של שרת היעד כפי שמוצג בהמשך:

    משתמש ב-Public Cloud:

    curl -v 'https://api.enterprise.apigee.com/v1/organizations/ORG_NAME/environments/ENV_NAME>/targetservers/TARGET_SERVER_NAME' \
    -H "Content-Type:application/xml" \
    -H "Authorization:Bearer $TOKEN"
    

    משתמש בענן פרטי:

    curl -v 'http://MANAGEMENT_IP:8080/v1/organizations/ORG_NAME/environments/ENV_NAME/targetservers/TARGET_SERVER_NAME' \
    -H "Content-Type:application/xml" \
    -H "Authorization:Bearer $TOKEN"
    
  2. אימות היציאה שצוינה עבור שרת היעד ופרטי ה-SSL.
  3. אם שרת היעד מוגדר עם יציאה מאובטחת (לדוגמה: 443), אבל הקטע SSLInfo לא מוגדר או לא מופעל, אז זו הסיבה בבעיה הזו.

    דוגמה להגדרה של שרת יעד:

    {
      "host" : "somehost.org",
      "isEnabled" : true,
      "name" : "faulty-target",
      "port" : 443
    }
    

    בפלט לדוגמה שלמעלה, אפשר לראות שהיציאה שמשמשת לחיבור היעד היא 443, אבל אין בלוק הגדרה של SSLInfo.

    זה גורם למעבד ההודעות של Apigee Edge לשלוח בקשות HTTP ליציאה המאובטחת 443 לכן, מופיעה השגיאה 400 Bad Request עם ההודעה The plain HTTP request was sent to HTTPS port.

רזולוציה

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

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

  • ממשק המשתמש של Edge
  • Management API

ממשק המשתמש של Edge

  1. עוברים לשרת היעד ב-Edge UI > אדמין > סביבות > שרתי היעד.
  2. בוחרים את שרת היעד הספציפי ולוחצים על Edit.
  3. אם שרת היעד מאובטח ומשתמש ביציאה כמו 443, מפעילים SSL באמצעות בחירה בתיבת הסימון לצד האפשרות SSL.
  4. מגדירים את Truststore, Ciphers ו-Protocols. (רק אם יש צורך)

Management API

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

חובה לאסוף פרטי אבחון

אם הבעיה נמשכת גם לאחר ביצוע ההוראות שלמעלה, יש לאסוף את הפריטים הבאים את פרטי האבחון ולאחר מכן פונים לתמיכה ב-Apigee Edge.

  1. אם אתם משתמשים ב-Public Cloud, עליכם לספק את הפרטים הבאים:
    • שם הארגון
    • שם הסביבה
    • שם ה-Proxy ל-API
    • צריך להשלים את פקודת ה-curl כדי לשחזר את השגיאה
    • הפלט של כלי המעקב (אם הצלחתם לתעד את הבקשה שנכשלה)
  2. אם אתם משתמשים בענן פרטי, עליכם לספק את הפרטים הבאים:
    • זוהתה הודעת שגיאה מלאה
    • שם הסביבה
    • חבילת proxy ל-API
    • הגדרת שרת היעד (אם משתמשים בשרת יעד בנקודת הקצה)
    • הפלט של כלי המעקב (אם הצלחתם לתעד את הבקשה שנכשלה)