Web アプリケーションの前でリバース プロキシを使用する場合は、元の HTTP ホスト名を保持することをお勧めします。 リバース プロキシでバックエンド アプリケーション サーバーに提供されるホスト名と異なるホスト名を使用すると、Cookie やリダイレクト URL が正しく機能しない可能性があります。 たとえば、セッション状態が失われたり、認証が失敗したり、バックエンド URL が誤ってエンド ユーザーに公開されたりする可能性があります。 これらの問題を回避するには、アプリケーション サーバーに Web ブラウザーと同じドメインが表示されるように、初期要求のホスト名を保持します。
このガイダンスは、特に、
手記
Web API は、通常、ホスト名の不一致によって発生する問題の影響を受けにくいです。 通常、シングルページ アプリとそのバックエンド API間の通信をセキュリティで保護するために Cookie を使用
エンド ツー エンドの TLS/SSL (リバース プロキシとバックエンド サービス間の接続で HTTPS を使用する) が必要な場合、バックエンド サービスには、元のホスト名に一致する TLS 証明書も必要です。 この要件により、証明書を展開および更新するときに運用上の複雑さが増しますが、多くの PaaS サービスでは、フル マネージドの無料 TLS 証明書が提供されます。
文脈
HTTP 要求のホスト
多くの場合、アプリケーション サーバーまたは要求パイプライン内のコンポーネントには、ブラウザーがアクセスするために使用したインターネット ドメイン名が必要です。 これは、要求の ホスト です。 IP アドレスを指定できますが、通常は contoso.com
のような名前です (ブラウザーは DNS を使用して IP アドレスに解決されます)。 ホスト値は通常、要求 URIの
大事な
セキュリティ メカニズムでホストの値を使用しないでください。 値はブラウザーまたはその他のユーザー エージェントによって提供され、エンド ユーザーが簡単に操作できます。
一部のシナリオでは、特に要求チェーンに HTTP リバース プロキシがある場合、元のホスト ヘッダーがアプリケーション サーバーに到達する前に変更される可能性があります。 リバース プロキシは、クライアント ネットワーク セッションを閉じ、バックエンドへの新しい接続を設定します。 この新しいセッションでは、クライアント セッションの元のホスト名を引き継ぐか、新しいホスト名を設定できます。 後者の場合、プロキシは、Forwarded
や X-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 サービスに登録する必要があるため、プラットフォームは要求に応答する必要があるバックエンド サーバーを識別できます。
アプリケーションがホスト名を使用する理由
アプリケーション サーバーがホスト名を必要とする 2 つの一般的な理由は、絶対 URL を構築し、特定のドメインに対して Cookie を発行することです。 たとえば、アプリケーション コードで次の必要がある場合です。
- HTTP 応答で相対 URL ではなく絶対 URL を返します (ただし、一般に、Web サイトでは可能な限り相対リンクがレンダリングされる傾向があります)。
- WEB サイトへのリンクをユーザーに電子メールで送信する場合など、相対 URL を使用できない HTTP 応答の外部で使用する URL を生成します。
- 外部サービスの絶対リダイレクト URL を生成します。 たとえば、Microsoft Entra ID などの認証サービスに対して、認証が成功した後にユーザーを返す場所を示します。
- Cookie の
Domain
属性で定義されているように、特定のホストに制限されている HTTP Cookie を発行します。
必要なホスト名をアプリケーションの構成に追加し、要求の受信ホスト名の代わりに静的に定義された値を使用することで、これらすべての要件を満たすことができます。 ただし、この方法では、アプリケーションの開発とデプロイが複雑になります。 また、アプリケーションを 1 回インストールすると、複数のホストに対応できます。 たとえば、1 つの Web アプリを複数のアプリケーション テナントに対して使用できます。このテナントはすべて、独自の一意のホスト名 (tenant1.contoso.com
や tenant2.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 のデータに簡単にサインインしてアクセスできるようになります。
- 受信ホスト名は、認証が成功した後に ID プロバイダーがユーザーを返す必要があるリダイレクト URL を構築するために使用されます。
- この機能を既定で有効にすると、HTTP から HTTPS へのリダイレクトも有効になります。 ここでも、受信ホスト名はリダイレクトの場所を生成するために使用されます。
ホスト名をオーバーライドする必要がある理由
既定のドメインが 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 へのリダイレクトのサポートなどのプラットフォーム機能によって生成することもできます。 この図は、問題を示しています。
- ブラウザーは、リバース プロキシに
contoso.com
の要求を送信します。 - リバース プロキシは、ホスト名を書き換えて、バックエンド Web アプリケーション (または別のサービスの同様の既定のドメイン) に要求で
contoso.azurewebsites.net
します。 - アプリケーションは、受信
contoso.azurewebsites.net
ホスト名 (たとえば、https://contoso.azurewebsites.net/
) に基づく絶対 URL を生成します。 - ブラウザーはこの URL に従います。この URL は、
contoso.com
のリバース プロキシに戻るのではなく、バックエンド サービスに直接移動します。
リバース プロキシが Web アプリケーション ファイアウォールとしても機能する一般的なケースでは、セキュリティ 上のリスクが生じる可能性もあります。 ユーザーは、バックエンド アプリケーションに直接移動し、リバース プロキシをバイパスする URL を受け取ります。
大事な
このセキュリティ リスクのため、バックエンド Web アプリケーションがリバース プロキシからのネットワーク トラフィックのみを直接受け入れるようにする必要があります (たとえば、App Serviceの
正しくないリダイレクト 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 認証や承認機能などのプラットフォーム機能によって生成。 この図は、問題を示しています。
- ブラウザーは、リバース プロキシに
contoso.com
の要求を送信します。 - リバース プロキシは、要求でバックエンド Web アプリケーション (または別のサービスの場合は同様の既定のドメイン) に
contoso.azurewebsites.net
するようにホスト名を書き換える。 - アプリケーションは、受信
contoso.azurewebsites.net
ホスト名 (たとえば、https://contoso.azurewebsites.net/
) に基づく絶対リダイレクト URL を生成します。 - ブラウザーは ID プロバイダーに移動してユーザーを認証します。 要求には、認証が成功した後にユーザーを返す場所を示す、生成されたリダイレクト URL が含まれています。
- ID プロバイダーでは通常、リダイレクト URL を前もって登録する必要があるため、指定されたリダイレクト URL が登録されていないため、この時点で ID プロバイダーは要求を拒否する必要があります。 (使用するはずはありませんでした。ただし、何らかの理由でリダイレクト URL が登録されている場合、ID プロバイダーはブラウザーを認証要求で指定されたリダイレクト URL にリダイレクトします。 この場合、URL は
https://contoso.azurewebsites.net/
。 - ブラウザーはこの URL に従います。この URL は、リバース プロキシに戻るのではなく、バックエンド サービスに直接移動します。
破損した Cookie
ホスト名の不一致は、アプリケーション サーバーが Cookie を発行し、受信ホスト名を使用して Cookieの
- ブラウザーは、リバース プロキシに
contoso.com
の要求を送信します。 - リバース プロキシは、バックエンド Web アプリケーション (または別のサービスの場合は同様の既定のドメイン) への要求で
contoso.azurewebsites.net
されるようにホスト名を書き換える。 - アプリケーションは、受信
contoso.azurewebsites.net
ホスト名に基づいてドメインを使用する Cookie を生成します。 ブラウザーは、ユーザーが実際に使用しているcontoso.com
ドメインではなく、この特定のドメインの Cookie を格納します。 - cookie の
contoso.azurewebsites.net
ドメインが要求のドメインと一致しないため、ブラウザーはcontoso.com
の後続の要求に Cookie を含めません。 アプリケーションは、以前に発行した Cookie を受け取りません。 その結果、ユーザーは Cookie に含まれているはずの状態を失うか、ARR アフィニティなどの機能が機能しない可能性があります。 残念ながら、これらの問題のいずれもエラーを生成しないか、エンド ユーザーに直接表示されます。 そのため、トラブルシューティングが困難になります。
一般的な Azure サービスの実装ガイダンス
ここで説明する潜在的な問題を回避するには、リバース プロキシとバックエンド アプリケーション サーバーの間の呼び出しで元のホスト名を保持することをお勧めします。
バックエンド構成
多くの Web ホスティング プラットフォームでは、許可される受信ホスト名を明示的に構成する必要があります。 次のセクションでは、最も一般的な Azure サービスに対してこの構成を実装する方法について説明します。 通常、他のプラットフォームでは、カスタム ドメインを構成するための同様の方法が提供されます。
同様に、
Kubernetes 上や仮想マシン上など、forwarded
または X-Forwarded-Host
ヘッダーを尊重する場合を除き、それに依存するアプリケーション内のすべてのコンポーネントに適用されます。
リバース プロキシの構成
リバース プロキシ内でバックエンドを定義する場合でも、バックエンド サービスの既定のドメイン (https://contoso.azurewebsites.net/
など) を使用できます。 この URL は、バックエンド サービスの正しい IP アドレスを解決するためにリバース プロキシによって使用されます。 プラットフォームの既定のドメインを使用する場合、IP アドレスは常に正しいことが保証されます。 リバース プロキシ自体の IP アドレスに解決する必要があるため、通常、contoso.com
などの一般向けドメインを使用することはできません。 (スプリットホライズン DNSなど、より高度な DNS 解決手法
大事な
リバース プロキシと最終的なバックエンドの間に azure Firewall Premium Host
ヘッダーがターゲット IP アドレスに解決されるかどうかを明示的に確認できます。 このような場合、ブラウザーで使用される元のホスト名は、パブリック インターネットからアクセスするときにリバース プロキシの IP アドレスに解決される必要があります。 ただし、ファイアウォールの観点からは、そのホスト名は最終的なバックエンド サービスの IP アドレスに解決される必要があります。 詳細については、「Azure Firewall と Application Gatewayを使用した Web アプリケーションのゼロトラスト ネットワーク」を参照してください。
ほとんどのリバース プロキシでは、バックエンド サービスに渡されるホスト名を構成できます。 次の情報では、最も一般的な Azure サービスで、受信要求の元のホスト名が使用されるようにする方法について説明します。
手記
いずれの場合も、受信要求からホスト名を取得するのではなく、明示的に定義されたカスタム ドメインでホスト名をオーバーライドすることもできます。 アプリケーションで使用するドメインが 1 つだけの場合、その方法は正常に動作する可能性があります。 同じアプリケーション展開で複数のドメインからの要求を受け入れる場合 (マルチテナント シナリオなど)、1 つのドメインを静的に定義することはできません。 受信要求からホスト名を取得する必要があります (アプリケーションが追加の HTTP ヘッダーを考慮するように明示的にコーディングされていない限り)。 そのため、一般的な推奨事項は、ホスト名を上書きしないようにする必要があるということです。 変更されていない受信ホスト名をバックエンドに渡します。
Application Gateway
正常性プローブは受信要求のコンテキストの外部に送信されるため、正しいホスト名を動的に判断することはできません。 代わりに、カスタム正常性プローブを作成し、バックエンド HTTP 設定からホスト名を選択
Azure Front Door
Azure Front Door
API Management
既定では、
次のように、inbound
Set ヘッダー ポリシーを追加することで、API Management で受信要求のホスト名を使用するように強制できます。
<inbound>
<base />
<set-header name="Host" exists-action="override">
<value>@(context.Request.OriginalUrl.Host)</value>
</set-header>
</inbound>
ただし、前述のように、API はホスト名の不一致によって発生する問題の影響を受けにくいため、この構成はそれほど重要ではない可能性があります。
次の手順
- App Service の
- Spring Apps
- Application Gateway の
- Azure Front Door を
する - API Management
関連リソース
- Azure Firewall と Application Gateway を使用した Web アプリケーションのゼロトラスト ネットワークの
- Application Gateway と API Management を使用して API を保護する
- App Services Environment を使用したエンタープライズ展開の