400 Bad request - プレーン HTTP リクエストが HTTPS ポートに送信される

ここに表示されているのは Apigee Edge のドキュメントです。
Go to the Apigee X のドキュメントに移動します
info

症状

クライアント アプリケーションが、メッセージ The plain HTTP request was sent to HTTPS port を含む HTTP 400 Bad Request レスポンスを受け取ります。

エラー メッセージ

クライアント アプリケーションは、次のレスポンス コードを受け取ります。

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>

考えられる原因

原因 説明 トラブルシューティングの実施対象
TLS 構成の仮想ホストへの HTTP リクエスト クライアントが TLS 構成の仮想ホストに HTTP リクエストを送信します。 Edge Public Cloud と Private Cloud のユーザー
TLS 構成のターゲット エンドポイントへの HTTP リクエスト ターゲット エンドポイントの TLS 対応バックエンド サーバーに HTTP リクエストが送信されました。 Edge Public Cloud と Private Cloud のユーザー
ターゲット サーバーの構成が正しくない ターゲット サーバーがセキュア ポート 443 で構成されていますが、SSL が有効になっていません。 Edge Public Cloud と Private Cloud のユーザー

原因: TLS 構成の仮想ホストへの HTTP リクエスト

このエラーは、クライアントが Apigee の API に接続しようとしたときに、言及されている 仮想ホストが SSL を使用するように構成されていて、代わりに HTTP リクエストを受信した場合に発生します。

診断

この問題は Northbound エンドポイントで発生し、API リクエストは クライアント アプリケーションと Router の間のエントリ ポイントのやり取りで失敗するため、これらのエラー メッセージは NGINX ルーター のアクセスログに記録されません。そのため、これらのリクエストは API Monitoring や Trace ツールなどのツールでキャプチャされません。

  1. API リクエストを確認し、セキュア ポート 443 でのみリクエストを受け入れるように構成されているホスト エイリアスに対して HTTP リクエストを行っているかどうかを確認します。その場合は、 それが問題の原因です。

    正しくない 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. 上記のサンプル リクエストでは、セキュア ポート 443 のホスト エイリアス myorg-test.apigee.net に HTTP リクエストが送信されています。これが 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

原因: TLS 構成のターゲット エンドポイントへの HTTP リクエスト

このエラーは、API プロキシのターゲット エンドポイントで TLS 対応バックエンド サーバーへの HTTP リクエストを誤って構成した場合に発生します。

診断

Trace ツールを使用してエラーを診断する手順は次のとおりです。

  1. 影響を受ける API プロキシの Apigee UI で Trace を有効にします。
  2. API プロキシにリクエストを送信します。
  3. 400 レスポンス コードで失敗した API リクエストのいずれかを選択します。
  4. さまざまなフェーズを確認し、どこでエラーが発生したかを確認します。
  5. 通常、バックエンド サーバーから 400 エラー レスポンスが返されます。 つまり、次の図に示すように、[Response received from target server] フェーズに 400 エラー レスポンスが表示されます。

  6. トレースの [AX](Analytics Data Recorded)アイコンをクリックして、リクエストが送信されたターゲット エンドポイントを特定します。

  7. プロトコル、バックエンド サーバーのホスト エイリアス、ポート番号(場合によっては)を含む target.url をメモします。ターゲット URL に使用されるポートは 443 ですが、プロトコルは HTTP です。
  8. ターゲット エンドポイントの定義を確認して、構成を理解します。
  9. バックエンド サーバーのホストが安全で、443 などのセキュア ポートでリッスンしていることを確認します。 <URL> 要素でプロトコルとして http を使用している場合は、これがこの問題の原因です。

    ターゲット エンドポイント構成の例:

    <?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 対応の場合は、次の例に示すように、ターゲット エンドポイントの<URL> 要素でプロトコルとして https を使用していることを確認します。

    ターゲット エンドポイント構成の例:

    <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>

原因: ターゲット サーバーの構成が正しくない

SSL を有効にせずに 443 などのセキュア ポートでターゲット サーバーが構成されている場合、Apigee Edge の Message Processor は HTTP リクエストをセキュアまたは TLS 構成のターゲット サーバーに送信し、この問題が発生します。

診断

Trace ツールを使用してエラーを診断する手順は次のとおりです。

  1. 影響を受ける API プロキシの Apigee UI で Trace を有効にします。
  2. API プロキシにリクエストを送信します。
  3. 400 レスポンス コードで失敗した API リクエストのいずれかを選択します。
  4. さまざまなフェーズを確認し、どこでエラーが発生したかを確認します。
  5. 通常、バックエンド サーバーから 400 エラー レスポンスが返されます。 つまり、次の図に示すように、400 エラー レスポンスが [Response received from target server] フェーズに表示されます。

  6. トレースの [AX](Analytics Data Recorded)アイコンをクリックして、リクエストが送信されたターゲット エンドポイントを特定します。

  7. ターゲット エンドポイント名を表す target.name をメモします。

    上記のトレース ファイルの例では、target.namedefault です。これは、このリクエストに使用されるターゲット エンドポイントがデフォルトであることを示します。

  8. ターゲット エンドポイントの定義を確認して、構成を理解します。

    ターゲット エンドポイント構成の例:

    <?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>

    上記のサンプル ターゲット エンドポイント構成では、ターゲット サーバー named faulty-target. を使用しています。

  9. ターゲット サーバー名を取得したら、次のいずれかの方法で ターゲット サーバーの構成を確認できます:

    • Edge UI
    • Management API

Edge UI

  1. Apigee Edge > [Admin] > [Environments] > [Target Servers] に移動します。
  2. API プロキシから特定された特定のターゲット サーバーを選択し、 [Edit] をクリックします。
  3. ターゲット サーバーに指定されたポートと SSL 情報を確認します。
  4. ターゲット サーバーがセキュア ポート(443 など)で構成されているが、SSL が有効になっていない場合は、これがこの問題の原因です。

    上記のスクリーンショットに示すように、使用されているポートは 443 ですが、ターゲット サーバーの構成でそのポートの SSL が 有効になっていません。これにより、Apigee Edge の Message Processor は HTTP リクエストをセキュア ポート 443 に送信します。そのため、 エラー 400 Bad Request とメッセージ The plain HTTP request was sent to HTTPS port が表示されます。

Management API

  1. Get target server 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"
    

    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 の Message Processor は HTTP リクエストをセキュア ポート 443 に送信します。そのため、エラー 400 Bad Request とメッセージ The plain HTTP request was sent to HTTPS port が表示されます。

解決策

ターゲット サーバーがセキュアまたは TLS 構成の場合は、特定の ターゲット サーバーで SSL を有効にする必要があります。

これを行うには、次のいずれかのオプションを使用します。

  • Edge UI
  • Management API

Edge UI

  1. Edge UI > [Admin] > [Environments] > [Target Servers] でターゲット サーバーに移動します。
  2. 特定のターゲット サーバーを選択し、 [Edit] をクリックします。
  3. ターゲット サーバーがセキュアで、443 などのポートを使用している場合は、[SSL] オプションの横にあるチェックボックスをオンにして SSL を有効にします。
  4. TruststoreCiphersProtocols を構成します。(必要な場合のみ)

Management API

Management API を使用して、ターゲット サーバーの構成を 更新するドキュメントの説明に従ってターゲット サーバーを構成します。

診断情報の収集が必要な場合

上記の手順でも問題が解決しない場合は、次の 診断情報を収集して Apigee Edge サポートにお問い合わせください。

  1. Public Cloud ユーザーの場合は、次の情報を提供してください。
    • 組織名
    • 環境名
    • API プロキシの名前
    • エラーを再現するための完全な curl コマンド
    • Trace ツールの出力(失敗したリクエストをキャプチャできた場合)
  2. Private Cloud ユーザーの場合は、次の情報を提供してください。
    • 確認したエラー メッセージ全文
    • 環境名
    • API プロキシ バンドル
    • ターゲット サーバーの定義(エンドポイントでターゲット サーバーを使用している場合)
    • Trace ツールの出力(失敗したリクエストをキャプチャできた場合)