400 Bad Request - SSL 証明書エラー

症状

クライアント アプリケーションが HTTP 400 - Bad request レスポンスと "The SSL certificate error" というメッセージを受信します。このエラーは通常、Apigee Edge との受信接続で双方向 TLS が有効になっている Edge Router から送信されます。

エラー メッセージ

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

HTTP/1.1 400 Bad Request

この後に次の HTML エラーページが表示されます。

<html>
      <head>
        <title>400 The SSL certificate error</title>
      </head>
      <body bgcolor="white">
        <center> <h1>400 Bad Request</h1>
        </center>
        <center>The SSL certificate error</center>
        <hr>
        <center>nginx</center>
      </body>
    </html>

考えられる原因

この問題には、次の原因が考えられます。

原因 説明 トラブルシューティング手順の適用対象
クライアント証明書が期限切れ クライアントから送信された証明書が期限切れです。 Edge Private Cloud と Public Cloud のユーザー
間違った証明書が送信された クライアント アプリケーションから送信された証明書が Edge Router のトラストストアに保存されている証明書に一致しない場合、このエラーが発生します。 Edge Private Cloud と Public Cloud のユーザー
クライアント証明書が Edge Router に読み込まれていない トラストストアにアップロードされたクライアント証明書が Router に読み込まれていない場合、このエラーが発生します。 Edge Private Cloud ユーザー

原因: クライアント証明書が期限切れ

この問題は通常、双方向 TLS でクライアントから送信された証明書が期限切れになっているときに発生します。双方向 TLS では、クライアントとサーバーの両方が公開証明書を交換して handshake を行います。クライアントがサーバー証明書を検証し、サーバーがクライアント証明書を検証します。

Edge では、仮想ホストに双方向 TLS が実装されます。サーバー証明書はキーストアに追加され、クライアント証明書はトラストストアに追加されます。

TLS handshake で期限切れのクライアント証明書が見つかると、サーバーが 400 - Bad request と "The SSL certificate error" メッセージを送信します。

診断

  1. Edge UI にログインして、API リクエストが行われる仮想ホストの構成を表示します([Environment Configuration] -> [Virtual Hosts] の順に移動)。または、Get Virtual Host 管理 API を使用して、仮想ホストの定義を取得します。

    通常、双方向 TLS 通信の仮想ホストは次のようになります。

    <VirtualHost name="myTLSVHost">
            <HostAliases>
                <HostAlias>api.myCompany.com</HostAlias>
            </HostAliases>
            <Port>443</Port>
            <SSLInfo>
                <Enabled>true</Enabled>
                <ClientAuthEnabled>true</ClientAuthEnabled>
                <KeyStore>ref://myKeystoreRef</KeyStore>
                <KeyAlias>myKeyAlias</KeyAlias>
                <TrustStore>ref://myTruststoreRef</TrustStore>
            </SSLInfo>
        </VirtualHost>
        
  2. 仮想ホストで使用されているトラストストアの参照を特定します。上の例では、myTruststoreRef がトラストストアの参照名です。

  3. トラストストア参照で指定されているトラストストアを特定します。
    1. Edge UI で、[APIs] -> [Environment Configurations] の順に移動します。
    2. [References] タブを選択して、トラストストアの参照名を検索します。
    3. 目的のトラストストア参照の [Reference] 列にある名前をメモします。これがトラストストアの名前になります。

      上の例では、myTruststoreRefmyTruststore を参照しているので、myTruststore がトラストストア名になります。

  4. Edge UI で [APIs] -> [Environment Configurations] の順に選択して [TLS Keystores] に移動し、手順 3 で確認したトラストストアを探します。
  5. 目的のトラストストア(上の手順 3 で特定)で証明書を選択します。

    上の例では、client-cert-markw というエイリアスの証明書が期限切れになっています。

  6. トラストストアの証明書エイリアスで証明書が期限切れかどうか確認します。
  7. 証明書が期限切れでない場合は、他の原因に対する共通の診断手順に進みます。

解決策

新しい証明書を取得してアップロードします。

  1. 新しいトラストストアを作成します。例: myNewTruststore
  2. この証明書を新しいトラストストアにアップロードします。
  3. 新しいトラストストアを参照するように、参照の変更の手順に沿って、仮想ホストに使用されているトラストストアの参照を変更します。

    上の例では、myTruststoreRef が myNewTruststore を参照しています。

他の原因に対する共通の診断手順

  1. この問題を調査するには、tcpdump ツールを使用して TCP/IP パケットをキャプチャする必要があります。
    1. Private Cloud を利用している場合は、クライアント アプリケーションまたは Router で TCP/IP パケットをキャプチャできます。
    2. Public Cloud を利用している場合は、クライアント アプリケーションで TCP/IP パケットをキャプチャします。
    3. TCP/IP パケットをキャプチャする場所が決まったら、tcpdump コマンドを実行して TCP/IP パケットをキャプチャします。

      tcpdump -i any -s 0 host <IP address> -w <File name>

      注: Router で TCP/IP パケットを収集する場合は、tcpdump コマンドでクライアント アプリケーションのパブリック IP アドレスを使用してください。

      クライアント アプリケーションで TCP/IP パケットを収集する場合は、仮想ホストで使用されているホスト名のパブリック IP アドレスを tcpdump コマンドで使用してください。

      このツールの使い方とこのコマンドのバリアントについては、tcpdump をご覧ください。

  2. Wireshark ツールまたは使い慣れた類似のツールを使用して、収集した TCP/IP パケットを分析します。

Wireshark ツールでサンプルの TCP/IP パケットデータを分析してみましょう。

  1. tcpdump のパケット 30(下の画像)は、クライアント アプリケーション(送信元)が "Client Hello" メッセージを Router(宛先)に送信したことを表しています。
  2. パケット 34 は、Router がクライアント アプリケーションからの Client Hello メッセージに確認応答したことを表しています。
  3. Router は、パケット 35 で "Server Hello" を送信し、パケット 38 でクライアント アプリケーションに証明書の送信をリクエストしています。
  4. Router が "Certificate Request" パケットを送信したパケット 38 で、"Distinguished Names" セクションを確認します。このセクションで、Router(サーバー)が受信したクライアント証明書、チェーン、証明書認証局の詳細が提供されています。
  5. クライアント アプリケーションがパケット 41 で証明書を送信しています。パケット 41 の Certificate Verify セクションを確認し、クライアント アプリケーションが送信した証明書を特定します。

  6. クライアント アプリケーションが送信した証明書のサブジェクトと発行元、チェーン(パケット 41)が、Router からの証明書とチェーン(パケット 38)に一致しているかどうか確認します。一致していない場合、これがエラーの原因です。このため、Router(サーバー)は暗号化されたアラート(パケット 57)と FIN, ACK(パケット 58)をクライアント アプリケーションに送信し、結果的に接続が終了しています。
  7. 以降のセクションでは、証明書とそのチェーンの不一致が原因となっている場合について説明します。

原因: クライアントから間違った証明書が送信されている

この問題は通常、クライアント アプリケーションから送信された証明書 / チェーンのサブジェクト / 発行元が、Router(サーバー)のトラストストアに保存されている証明書 / チェーンと一致していない場合に発生します。

診断

  1. Edge UI にログインして、API リクエストが行われる仮想ホストの構成を表示します([Environment Configuration] -> [Virtual Hosts] の順に移動)。または、Get Virtual Host 管理 API を使用して、仮想ホストの定義を取得します。

    通常、双方向 TLS 通信の仮想ホストは次のようになります。

        <VirtualHost name="myTLSVHost">
                <HostAliases>
                    <HostAlias>api.myCompany.com</HostAlias>
                </HostAliases>
                <Port>443</Port>
                <SSLInfo>
                    <Enabled>true</Enabled>
                    <ClientAuthEnabled>true</ClientAuthEnabled>
                    <KeyStore>ref://myKeystoreRef</KeyStore>
                    <KeyAlias>myKeyAlias</KeyAlias>
                        <TrustStore>ref://myCompanyTruststoreRef</TrustStore>
                </SSLInfo>
            </VirtualHost>
        
  2. 仮想ホストで使用されているトラストストアの参照を特定します。

    上の例では、myCompanyTruststoreRef がトラストストアの参照名です。

  3. トラストストアの参照で指定されているトラストストアを特定します。
    1. Edge UI で、[APIs] -> [Environment Configurations] の順に移動します。
    2. [References] タブを選択して、トラストストアの参照名を検索します。
    3. 目的のトラストストア参照の [Reference] 列にある名前をメモします。これがトラストストアの名前になります。

      alt_text

      上の例では、myCompanyTruststoreRef が myCompanyTruststore を参照しているので、myCompanyTruststore がトラストストアの名前になります。

  4. 次の API を使用して、前の手順で特定したトラストストアに保存されている証明書を取得します。
    1. キーストアまたはトラストストアの証明書をすべて取得します

      この API により、目的のトラストストアの証明書の一覧が出力されます。

    2. キーストアまたはトラストストアから証明書の詳細を取得します

      この API により、目的のトラストストアに保存されている特定の証明書の詳細が返されます。

  5. myCompanyTruststore に保存される証明書の発行元 / サブジェクトとチェーンが、TCP/IP パケット(前述のパケット 38)の証明書とチェーンと一致しているかどうか確認します。不一致がある場合、トラストストアにアップロードされた証明書が Edge Router に読み込まれていません。原因: クライアント証明書が Edge Router に読み込まれていないに進みます。
  6. 手順 5 で不一致がない場合、クライアント アプリケーションが正しい証明書とチェーンを送信していません。

解決策

クライアント アプリケーションから Edge に正しい証明書とチェーンを送信するようにします。

原因: クライアント証明書が Edge Router に読み込まれていない

  1. Public Cloud をご利用の場合は、Apigee サポートに問い合わせください。
  2. Private Cloud を利用の場合は、各 Router で次の操作を行います。
    1. 目的の仮想ホストにファイル /opt/nginx/conf.d/OrgName_envName_vhostName-client.pem が存在しているかどうか確認します。ファイルが存在しない場合、下の解決策に進みます。
    2. ファイルが存在する場合は、次の openssl コマンドを使用して、Edge Route で使用可能な証明書の詳細を取得します。
      openssl -in <OrgName_envName_vhostName-client.pem> -text -noout
    3. 証明書の発行元、サブジェクト、有効期限を確認します。Edge UI または管理 API で確認したトラストストアの内容と不一致がある場合、これがエラーの原因です。
    4. Router が更新後の証明書を読み込んでない可能性があります。

    解決策

    以下の手順で Router を再起動し、最新の証明書を読み込みます。

    apigee-service edge-router restart

    API を再度実行して結果を確認します。問題が解決しない場合は、診断情報の収集に進みます。

    診断情報の収集

    上記の手順でも問題が解決されない場合は、次の診断情報を収集する必要があります。Apigee サポートに連絡して、収集した情報を提供してください。

    1. Public Cloud をご利用の場合は、次の情報を提供してください。
      1. 組織名
      2. 環境名
      3. API プロキシ名
      4. 仮想ホスト名
      5. ホスト エイリアス名
      6. エラーを再現する完全な curl コマンド
      7. クライアント アプリケーションでキャプチャされた TCP/IP パケット
    2. Private Cloud をご利用の場合は、次の情報を提供してください。
      1. Get Virtual Host 管理 API で取得した仮想ホスト名とその定義
      2. ホスト エイリアス名
      3. 確認したエラー メッセージの全文
      4. クライアント アプリケーションまたは Router でキャプチャされた TCP/IP パケット
      5. キーストアに格納されている証明書を一覧表示する API の出力と、この管理 API を使用して取得した各証明書の詳細
    3. このプレイブックで試したセクションや詳しい分析情報を提供していただけると、迅速な問題解決に役立ちます。