שגיאה 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 Public Cloud וב-Edge Private Cloud
בקשת HTTP לנקודת קצה (endpoint) של יעד שהוגדר עבור TLS בקשת HTTP שמועברת לשרת קצה עורפי עם TLS בנקודת הקצה של היעד. משתמשים ב-Edge Public Cloud וב-Edge Private Cloud
הגדרה שגויה של שרת היעד שרת היעד מוגדר עם יציאה מאובטחת 443 אבל SSL לא מופעל. משתמשים ב-Edge Public Cloud וב-Edge Private Cloud

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

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

אבחון

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

  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 ולא ב-HTTPS, ולשלוח את הבקשה הנכונה כמו שמוצג בהמשך:

בקשת 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 לנקודת קצה יעד שהוגדרה עם TLS

השגיאה הזו מתרחשת אם הגדרתם בצורה שגויה בקשות HTTP לשרת backend עם TLS בנקודת היעד של API Proxy.

אבחון

כדי לאבחן את השגיאה באמצעות הכלי Trace:

  1. מפעילים את Trace בממשק המשתמש של Apigee עבור ה-API Proxy המושפע.
  2. שליחת בקשות ל-API Proxy.
  3. בוחרים אחת מבקשות ה-API שנכשלו עם קוד התגובה 400.
  4. עוברים בין השלבים השונים ומנסים להבין איפה התרחשה השגיאה.
  5. בדרך כלל, תגובת השגיאה 400 מגיעה מהשרת העורפי. כלומר, תגובת השגיאה 400 תוצג בשלב Response received from target server כמו שמוצג בהמשך:

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

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

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

    <?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> של נקודת הקצה של היעד, כמו שמוצג בדוגמה הבאה:

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

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

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

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

    <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, וזה יוביל לבעיה הזו.

אבחון

כדי לאבחן את השגיאה באמצעות הכלי Trace:

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

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

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

    בדוגמה של קובץ המעקב שלמעלה, target.name הוא default. הערך הזה מציין שנקודת הקצה של היעד שבה נעשה שימוש בבקשה הזו היא ברירת המחדל.

  8. כדי להבין את ההגדרה, בודקים את ההגדרה של נקודת הקצה (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 > Admin > Environments > Target Servers.
  2. בוחרים את שרת היעד הספציפי שזוהה מתוך ה-API proxy ולוחצים על עריכה.
  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‏ Get target server כדי לקבל את הפרטים על ההגדרה של שרת היעד הספציפי, כמו שמוצג בהמשך:

    משתמש בענן ציבורי:

    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"
    

    משתמש ב-Private Cloud:

    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 > Admin > Environments > Target Servers.
  2. בוחרים את שרת היעד הספציפי ולוחצים על עריכה.
  3. אם שרת היעד מאובטח ומשתמש ביציאה כמו 443, צריך להפעיל SSL על ידי סימון התיבה שליד האפשרות SSL.
  4. מגדירים את מאגר האישורים, את הצפנות ואת הפרוטוקולים. (רק אם נדרש)

Management API

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

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

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

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