編集

次の方法で共有


リバース プロキシとそのバックエンド Web アプリケーションの間で元の HTTP ホスト名を保持する

Azure API Management
Azure App Service
Azure Application Gateway
Azure Front Door
Azure Spring Apps

Web アプリケーションの前でリバース プロキシを使用する場合は、元の HTTP ホスト名を保持することをお勧めします。 リバース プロキシでバックエンド アプリケーション サーバーに提供されるホスト名と異なるホスト名を使用すると、Cookie やリダイレクト URL が正しく機能しない可能性があります。 たとえば、セッション状態が失われたり、認証が失敗したり、バックエンド URL が誤ってエンド ユーザーに公開されたりする可能性があります。 これらの問題を回避するには、アプリケーション サーバーに Web ブラウザーと同じドメインが表示されるように、初期要求のホスト名を保持します。

このガイダンスは、特に、Azure App Service や Azure Spring Appsなどの PaaS (サービスとしてのプラットフォーム) オファリングでホストされているアプリケーションに適用されます。 この記事では、一般的に使用されるリバース プロキシ サービスである Azure Application GatewayAzure Front DoorAzure API Managementに関する具体的な 実装ガイダンスの について説明します。

手記

Web API は、通常、ホスト名の不一致によって発生する問題の影響を受けにくいです。 通常、シングルページ アプリとそのバックエンド API間の通信をセキュリティで保護するために Cookie を使用 場合を除き、通常は Cookie に依存しません。フロントエンドのバックエンド と呼ばれるパターンなどです。 Web API は多くの場合、Open Data Protocol (OData)HATEOASなど、特定の API スタイルを除き、絶対 URL を返しません。 API の実装が Cookie に依存している場合や絶対 URL が生成される場合は、この記事で説明するガイダンスが適用されます。

エンド ツー エンドの TLS/SSL (リバース プロキシとバックエンド サービス間の接続で HTTPS を使用する) が必要な場合、バックエンド サービスには、元のホスト名に一致する TLS 証明書も必要です。 この要件により、証明書を展開および更新するときに運用上の複雑さが増しますが、多くの PaaS サービスでは、フル マネージドの無料 TLS 証明書が提供されます。

文脈

HTTP 要求のホスト

多くの場合、アプリケーション サーバーまたは要求パイプライン内のコンポーネントには、ブラウザーがアクセスするために使用したインターネット ドメイン名が必要です。 これは、要求の ホスト です。 IP アドレスを指定できますが、通常は contoso.com のような名前です (ブラウザーは DNS を使用して IP アドレスに解決されます)。 ホスト値は通常、要求 URIの ホスト コンポーネントから決定されます。このコンポーネントは、ブラウザーが HTTP ヘッダーとしてアプリケーションに送信

大事な

セキュリティ メカニズムでホストの値を使用しないでください。 値はブラウザーまたはその他のユーザー エージェントによって提供され、エンド ユーザーが簡単に操作できます。

一部のシナリオでは、特に要求チェーンに HTTP リバース プロキシがある場合、元のホスト ヘッダーがアプリケーション サーバーに到達する前に変更される可能性があります。 リバース プロキシは、クライアント ネットワーク セッションを閉じ、バックエンドへの新しい接続を設定します。 この新しいセッションでは、クライアント セッションの元のホスト名を引き継ぐか、新しいホスト名を設定できます。 後者の場合、プロキシは、ForwardedX-Forwarded-Hostなど、他の HTTP ヘッダーで元のホスト値を送信することがよくあります。 この値により、アプリケーションは元のホスト名を特定できますが、これらのヘッダーを読み取るためにコード化されている場合に限られます。

Web プラットフォームがホスト名を使用する理由

多くの場合、マルチテナント PaaS サービスでは、受信要求を適切なテナントのバックエンド サーバーにルーティングするために、登録済みの検証済みのホスト名が必要になります。 これは、通常、すべてのテナントの受信要求を受け入れるロード バランサーの共有プールがあるためです。 テナントは通常、受信ホスト名を使用して、顧客テナントの正しいバックエンドを検索します。

これらのプラットフォームは、簡単に開始できるように、通常、デプロイされたインスタンスにトラフィックをルーティングするように事前構成された既定のドメインを提供します。 App Service の場合、この既定のドメインは azurewebsites.netです。 作成する各 Web アプリは、独自のサブドメイン (たとえば、contoso.azurewebsites.net) を取得します。 同様に、既定のドメインは Azure Spring Apps 用に azuremicroservices.io され、API Management 用の azure-api.net です。

運用環境のデプロイでは、これらの既定のドメインは使用しません。 代わりに、組織またはアプリケーションのブランドに合わせて独自のドメインを指定します。 たとえば、contoso.com はバックグラウンドで App Service 上の contoso.azurewebsites.net Web アプリに解決できますが、このドメインは、Web サイトにアクセスしているエンド ユーザーには表示されません。 ただし、このカスタム contoso.com ホスト名は PaaS サービスに登録する必要があるため、プラットフォームは要求に応答する必要があるバックエンド サーバーを識別できます。

App Service でのホストベースのルーティングを示す図。

アプリケーションがホスト名を使用する理由

アプリケーション サーバーがホスト名を必要とする 2 つの一般的な理由は、絶対 URL を構築し、特定のドメインに対して Cookie を発行することです。 たとえば、アプリケーション コードで次の必要がある場合です。

  • HTTP 応答で相対 URL ではなく絶対 URL を返します (ただし、一般に、Web サイトでは可能な限り相対リンクがレンダリングされる傾向があります)。
  • WEB サイトへのリンクをユーザーに電子メールで送信する場合など、相対 URL を使用できない HTTP 応答の外部で使用する URL を生成します。
  • 外部サービスの絶対リダイレクト URL を生成します。 たとえば、Microsoft Entra ID などの認証サービスに対して、認証が成功した後にユーザーを返す場所を示します。
  • Cookie の Domain 属性で定義されているように、特定のホストに制限されている HTTP Cookie を発行します。

必要なホスト名をアプリケーションの構成に追加し、要求の受信ホスト名の代わりに静的に定義された値を使用することで、これらすべての要件を満たすことができます。 ただし、この方法では、アプリケーションの開発とデプロイが複雑になります。 また、アプリケーションを 1 回インストールすると、複数のホストに対応できます。 たとえば、1 つの Web アプリを複数のアプリケーション テナントに対して使用できます。このテナントはすべて、独自の一意のホスト名 (tenant1.contoso.comtenant2.contoso.comなど) を持っています。

また、受信ホスト名は、アプリケーション コードの外部のコンポーネントや、完全に制御できないアプリケーション サーバー上のミドルウェアで使用される場合があります。 いくつかの例を次に示します。

  • App Service では、Web アプリに HTTPS を適用 。 これにより、セキュリティで保護されていない HTTP 要求が HTTPS にリダイレクトされます。 この場合、受信ホスト名は、HTTP リダイレクトの Location ヘッダーの絶対 URL を生成するために使用されます。
  • Azure Spring Apps では、同様の機能を使用して、HTTPSを適用 。 また、受信ホストを使用して HTTPS URL を生成します。
  • App Service には、スティッキー セッションを有効にする ARR アフィニティ設定があるため、同じブラウザー インスタンスからの要求は常に同じバックエンド サーバーによって処理されます。 これは、HTTP 応答に Cookie を追加する App Service フロントエンドによって実行されます。 Cookie の Domain は、受信ホストに設定されます。
  • App Service には、認証と承認の機能 が用意されており、ユーザーが API のデータに簡単にサインインしてアクセスできるようになります。

ホスト名をオーバーライドする必要がある理由

既定のドメインが contoso.azurewebsites.netである Web アプリケーションを App Service で作成するとします。 (または、Azure Spring Apps などの別のサービスの場合)。App Service でカスタム ドメインを構成していません。 Application Gateway (または同様のサービス) などのリバース プロキシをこのアプリケーションの前に配置するには、contoso.com の DNS レコードを Application Gateway の IP アドレスに解決するように設定します。 そのため、ブラウザーから contoso.com の要求を受信し、その要求を解決先の IP アドレスに転送するように構成 contoso.azurewebsites.net。これは、要求されたホストの最終的なバックエンド サービスです。 ただし、この場合、App Service は contoso.com カスタム ドメインを認識せず、このホスト名に対するすべての受信要求を拒否します。 要求をルーティングする場所を特定できません。

この構成を簡単に行う方法は、Application Gateway の HTTP 要求の Host ヘッダーをオーバーライドまたは書き換え、contoso.azurewebsites.netの値に設定することです。 その場合、Application Gateway からの送信要求は、元の要求が実際に contoso.comではなく contoso.azurewebsites.net を意図していたように見えます。

ホスト名がオーバーライドされた構成を示す図。

この時点で、App Service はホスト名を認識し、カスタム ドメイン名を構成しなくても要求を受け入れます。 実際、Application Gateway を使用すると、バックエンド プールのホストでホスト ヘッダー を簡単にオーバーライドできます。 Azure Front Door では、既定でも行われます。

ただし、このソリューションの問題は、アプリに元のホスト名が表示されないと、さまざまな問題が発生する可能性があるということです。

潜在的な問題

正しくない絶対 URL

元のホスト名が保持されず、アプリケーション サーバーが受信ホスト名を使用して絶対 URL を生成する場合、バックエンド ドメインがエンド ユーザーに公開される可能性があります。 これらの絶対 URL は、アプリケーション コードによって生成することも、前述のように、App Service と Azure Spring Apps での HTTP から HTTPS へのリダイレクトのサポートなどのプラットフォーム機能によって生成することもできます。 この図は、問題を示しています。

正しくない絶対 URL の問題を示す図。

  1. ブラウザーは、リバース プロキシに contoso.com の要求を送信します。
  2. リバース プロキシは、ホスト名を書き換えて、バックエンド Web アプリケーション (または別のサービスの同様の既定のドメイン) に要求で contoso.azurewebsites.net します。
  3. アプリケーションは、受信 contoso.azurewebsites.net ホスト名 (たとえば、https://contoso.azurewebsites.net/) に基づく絶対 URL を生成します。
  4. ブラウザーはこの URL に従います。この URL は、contoso.comのリバース プロキシに戻るのではなく、バックエンド サービスに直接移動します。

リバース プロキシが Web アプリケーション ファイアウォールとしても機能する一般的なケースでは、セキュリティ 上のリスクが生じる可能性もあります。 ユーザーは、バックエンド アプリケーションに直接移動し、リバース プロキシをバイパスする URL を受け取ります。

大事な

このセキュリティ リスクのため、バックエンド Web アプリケーションがリバース プロキシからのネットワーク トラフィックのみを直接受け入れるようにする必要があります (たとえば、App Serviceの アクセス制限を使用)。 正しくない絶対 URL が生成された場合でも、少なくとも動作せず、悪意のあるユーザーがファイアウォールをバイパスするために使用することはできません。

正しくないリダイレクト URL

前のシナリオの一般的で具体的なケースは、絶対リダイレクト URL が生成されるときに発生します。 これらの URL は、OpenID Connect、Open Authorization (OAuth) 2.0、Security Assertion Markup Language (SAML) 2.0 などのブラウザー ベースの ID プロトコルを使用する場合、Microsoft Entra ID などの ID サービスで必要になります。 これらのリダイレクト URL は、アプリケーション サーバーまたはミドルウェア自体、または前述のように、app service 認証や承認機能などのプラットフォーム機能によって生成。 この図は、問題を示しています。

正しくないリダイレクト URL の問題を示す図。

  1. ブラウザーは、リバース プロキシに contoso.com の要求を送信します。
  2. リバース プロキシは、要求でバックエンド Web アプリケーション (または別のサービスの場合は同様の既定のドメイン) に contoso.azurewebsites.net するようにホスト名を書き換える。
  3. アプリケーションは、受信 contoso.azurewebsites.net ホスト名 (たとえば、https://contoso.azurewebsites.net/) に基づく絶対リダイレクト URL を生成します。
  4. ブラウザーは ID プロバイダーに移動してユーザーを認証します。 要求には、認証が成功した後にユーザーを返す場所を示す、生成されたリダイレクト URL が含まれています。
  5. ID プロバイダーでは通常、リダイレクト URL を前もって登録する必要があるため、指定されたリダイレクト URL が登録されていないため、この時点で ID プロバイダーは要求を拒否する必要があります。 (使用するはずはありませんでした。ただし、何らかの理由でリダイレクト URL が登録されている場合、ID プロバイダーはブラウザーを認証要求で指定されたリダイレクト URL にリダイレクトします。 この場合、URL は https://contoso.azurewebsites.net/
  6. ブラウザーはこの URL に従います。この URL は、リバース プロキシに戻るのではなく、バックエンド サービスに直接移動します。

破損した Cookie

ホスト名の不一致は、アプリケーション サーバーが Cookie を発行し、受信ホスト名を使用して Cookieの 属性を構築するときにも問題が発生する可能性があります。 Domain 属性を使用すると、Cookie はその特定のドメインにのみ使用されます。 これらの Cookie は、アプリケーション コードによって生成することも、前述のように、App Service ARR アフィニティ設定などのプラットフォーム機能によって生成。 この図は、問題を示しています。

正しくない Cookie ドメインを示す図。

  1. ブラウザーは、リバース プロキシに contoso.com の要求を送信します。
  2. リバース プロキシは、バックエンド Web アプリケーション (または別のサービスの場合は同様の既定のドメイン) への要求で contoso.azurewebsites.net されるようにホスト名を書き換える。
  3. アプリケーションは、受信 contoso.azurewebsites.net ホスト名に基づいてドメインを使用する Cookie を生成します。 ブラウザーは、ユーザーが実際に使用している contoso.com ドメインではなく、この特定のドメインの Cookie を格納します。
  4. cookie の contoso.azurewebsites.net ドメインが要求のドメインと一致しないため、ブラウザーは contoso.com の後続の要求に Cookie を含めません。 アプリケーションは、以前に発行した Cookie を受け取りません。 その結果、ユーザーは Cookie に含まれているはずの状態を失うか、ARR アフィニティなどの機能が機能しない可能性があります。 残念ながら、これらの問題のいずれもエラーを生成しないか、エンド ユーザーに直接表示されます。 そのため、トラブルシューティングが困難になります。

一般的な Azure サービスの実装ガイダンス

ここで説明する潜在的な問題を回避するには、リバース プロキシとバックエンド アプリケーション サーバーの間の呼び出しで元のホスト名を保持することをお勧めします。

ホスト名が保持される構成を示す図。

バックエンド構成

多くの Web ホスティング プラットフォームでは、許可される受信ホスト名を明示的に構成する必要があります。 次のセクションでは、最も一般的な Azure サービスに対してこの構成を実装する方法について説明します。 通常、他のプラットフォームでは、カスタム ドメインを構成するための同様の方法が提供されます。

App Serviceで Web アプリケーションをホストする場合は、カスタム ドメイン名を Web アプリ にアタッチ 、バックエンドに既定の ホスト名を使用しないようにすることができます。 カスタム ドメインを Web アプリにアタッチするときに DNS 解決を変更する必要はありません。通常の レコードに影響を与えることなく、 レコード を使用してドメインを確認 。 (これらのレコードは、リバース プロキシの IP アドレスに解決されます)。エンド ツー エンドの TLS/SSL が必要な場合は、Key Vault から既存の証明書をインポート 、またはカスタム ドメインに App Service 証明書 を使用できます。 (この場合、無料の App Service マネージド証明書 は使用できません。ドメインの DNS レコードは、リバース プロキシではなく、App Service に直接解決する必要があるためです)。

同様に、Spring Appsを使用している場合は、アプリ のカスタム ドメインを使用 ホスト名の使用を回避できます。 エンド ツー エンドの TLS/SSL が必要な場合は、既存の証明書または自己署名証明書をインポートできます。

API Management の前にリバース プロキシがある場合 (それ自体はリバース プロキシとしても機能します)、 ホスト名の使用を回避するために、API Management インスタンス にカスタム ドメインを構成 。 エンド ツー エンドの TLS/SSL が必要な場合は、既存または無料のマネージド証明書をインポートできます。 ただし、前述のように、API はホスト名の不一致によって発生する問題の影響を受けにくいため、この構成はそれほど重要ではない可能性があります。

Kubernetes 上や仮想マシン上など、他のプラットフォームでアプリケーションをホストする場合、受信ホスト名に依存する組み込み機能はありません。 アプリケーション サーバー自体でホスト名を使用する方法については、ユーザーが責任を負います。 通常、ホスト名を保持する推奨事項は、アプリケーションがリバース プロキシを認識し、forwarded または X-Forwarded-Host ヘッダーを尊重する場合を除き、それに依存するアプリケーション内のすべてのコンポーネントに適用されます。

リバース プロキシの構成

リバース プロキシ内でバックエンドを定義する場合でも、バックエンド サービスの既定のドメイン (https://contoso.azurewebsites.net/など) を使用できます。 この URL は、バックエンド サービスの正しい IP アドレスを解決するためにリバース プロキシによって使用されます。 プラットフォームの既定のドメインを使用する場合、IP アドレスは常に正しいことが保証されます。 リバース プロキシ自体の IP アドレスに解決する必要があるため、通常、contoso.comなどの一般向けドメインを使用することはできません。 (スプリットホライズン DNSなど、より高度な DNS 解決手法 使用しない限り)。

大事な

リバース プロキシと最終的なバックエンドの間に azure Firewall Premium のような次世代ファイアウォールがある場合は、スプリットホライズン DNS を使用することが必要になる場合があります。 この種類のファイアウォールでは、HTTP Host ヘッダーがターゲット IP アドレスに解決されるかどうかを明示的に確認できます。 このような場合、ブラウザーで使用される元のホスト名は、パブリック インターネットからアクセスするときにリバース プロキシの IP アドレスに解決される必要があります。 ただし、ファイアウォールの観点からは、そのホスト名は最終的なバックエンド サービスの IP アドレスに解決される必要があります。 詳細については、「Azure Firewall と Application Gatewayを使用した Web アプリケーションのゼロトラスト ネットワーク」を参照してください。

ほとんどのリバース プロキシでは、バックエンド サービスに渡されるホスト名を構成できます。 次の情報では、最も一般的な Azure サービスで、受信要求の元のホスト名が使用されるようにする方法について説明します。

手記

いずれの場合も、受信要求からホスト名を取得するのではなく、明示的に定義されたカスタム ドメインでホスト名をオーバーライドすることもできます。 アプリケーションで使用するドメインが 1 つだけの場合、その方法は正常に動作する可能性があります。 同じアプリケーション展開で複数のドメインからの要求を受け入れる場合 (マルチテナント シナリオなど)、1 つのドメインを静的に定義することはできません。 受信要求からホスト名を取得する必要があります (アプリケーションが追加の HTTP ヘッダーを考慮するように明示的にコーディングされていない限り)。 そのため、一般的な推奨事項は、ホスト名を上書きしないようにする必要があるということです。 変更されていない受信ホスト名をバックエンドに渡します。

Application Gateway

Application Gateway をリバース プロキシとして使用する場合は、バックエンドの HTTP 設定で新しいホスト名 でオーバーライド 無効にすることで、元のホスト名を保持できます。 これにより、バックエンド アドレス からホスト名を選択する と、特定のドメイン名でオーバーライドする の両方が無効になります。 (どちらの設定もホスト名をオーバーライドします)。Application Gatewayの Azure Resource Manager プロパティでは、この構成は プロパティを に設定し、に設定する場合に対応します。

正常性プローブは受信要求のコンテキストの外部に送信されるため、正しいホスト名を動的に判断することはできません。 代わりに、カスタム正常性プローブを作成し、バックエンド HTTP 設定からホスト名を選択 無効にし、ホスト名を明示的に指定 必要があります。 このホスト名には、一貫性のために適切なカスタム ドメインも使用する必要があります。 (ただし、正常性プローブは正しくない Cookie を無視したり、応答の URL をリダイレクトしたりするため、ここではホスティング プラットフォームの既定のドメインを使用できます)。

Azure Front Door

Azure Front Door使用する場合は、配信元定義で 配信元ホスト ヘッダー 空白のままにすることで、ホスト名を保持できます。 配信元Resource Manager 定義では、この構成は、に設定する場合に対応します。

API Management

既定では、API Management は、バックエンドに送信されるホスト名を、API の Web サービス URL のホスト コンポーネント (APIの Resource Manager 定義の 値に対応) でオーバーライドします。

次のように、inboundSet ヘッダー ポリシーを追加することで、API Management で受信要求のホスト名を使用するように強制できます。

<inbound>
  <base />
  <set-header name="Host" exists-action="override">
    <value>@(context.Request.OriginalUrl.Host)</value>
  </set-header>
</inbound>

ただし、前述のように、API はホスト名の不一致によって発生する問題の影響を受けにくいため、この構成はそれほど重要ではない可能性があります。

次の手順

  • Azure Firewall と Application Gateway を使用した Web アプリケーションのゼロトラスト ネットワークの
  • Application Gateway と API Management を使用して API を保護する
  • App Services Environment を使用したエンタープライズ展開の