After a long time, I am.

日々のメモ

Azure AppService上のサイトへのリバースプロキシで苦しんだ話

以下の構成でサービスを運用している。

クライアント - リバースプロキシ(nginx) - Cloudservices

バックエンドをCloudServices → Azure App Serviceに置き換え、以下のように構成しようとした。

クライアント - リバースプロキシ(nginx) - Azure App Service

CloudServicesと異なる点は、AppServiceでは単一IPで複数のWebサイトをホストしていることだ。 (しようとしている )

IP固定も可能だけど。
AppService plan料金
Isolatedで、月3万円ぐらいかな。

クライアントからのリクエストURLはリバースプロキシのURLで変わらないので、リバプロで AppServiceの各サイトへの振り分けを行ってあげる必要がある。

Azure App Service の リージョンとスタンプ、IP アドレスについて

Azure App Service ではサイト固有の一意のパブリック IP アドレスは割り当てられていません。 したがって、Azure App Service では、IP アドレスや TCP ポートに一意性はないため、ホストヘッダー (サイト名、または、カスタム ドメインを構成している場合はドメイン名) を使用して HTTP 要求のルーティングをする必要があります。

と書いてあるように、ホストヘッダを指定して振り分けるしかなさそうである。

nginx的にはこんな感じ。

server {
    listen 443 ssl;
    server_name testproxy.com;

    location  /a {
        proxy_pass https://XXXXXXXXXX(AppServiceのIP)
        proxy_set_header Host  test1.com;
        proxy_redirect default;
    }
    location  /b {
        proxy_pass https://XXXXXXXXXX
        proxy_set_header Host  test2.com;
        proxy_redirect default;
    }
}

これで、リクエストはAppServiceに転送できるが、問題はバックエンド(AppService上のtest1.com、test2,com)で Hostヘッダを見てなんかやっている処理があったりする場合。

HTTP 1.1のHost:ヘッダーの保持

にも書かれているが、通常リバプロでは proxy_set_header Host $host; とか設定して、クライアントから渡された、あるいは設定されていなければserver_nameから取得した値を Hostヘッダに指定する。と思う。

今回はHostヘッダを(強引に)指定してプロキシしているために、バックエンドで問題が起こる可能性がある。(リダイレクト時など)

リクエストURLを取得する(ASP.NET プログラミング)

↑とか。Request.Urlプロパティから値を取得するのだが、内容はHostヘッダから組み立てている模様。

Application Request Routing (ARR) を使う場合に必ず設定しておきたい項目

アプリケーション側で Host ヘッダを見て URL を組み立てる場合に、プライベート IP アドレスがホストになってしまうことがあります。特に ASP.NET の Request.Url でこの問題が発生します

上記のようなことである。

  • バックエンドのアプリのHostヘッダを見てる処理に手を入れる
  • AppServiceプランをIsolatedにしてIP固定にする。(どうやら、Isolatedプラン以外では例え1サイトのみの構成にしてもHOSTヘッダは指定する必要がある)

結局、この2点の何れかにすることになった。 nginxで色々頑張る(リクエスト見ていろいろ書き換える)も検討したが、それはなんかちゃう、という気がしたのでやめた。

しかし、こういう用途(リバプロ + 単一IPで複数ホスト)ってほとんどWeb上の情報がでてこない。

詳しくないのでわからないが、この用途自体がおかしい(珍しい)のか……
サポートに聞いたらnginxでの構築事例は聞かないが、普通にAppService上にプロキシ立てて、そこから AppServiceに。みたいなのはあるらしい。
というかパスで振り分けるだけだったらApplicationGateway使えばええやね…… Azure Application Gateway の概要 | Microsoft Docs

nginxは時々触るが毎回苦しめられるので、記憶に定着するように形として残していきたいものである。

参考URLまとめ

HTTP のリダイレクション
リバースプロキシーと HTTP リダイレクト
ホストヘッダー
AzureWebAppsのSSLでドハマリ
Application Gateway の複数サイトのホスト
HTTP 1.1のHost:ヘッダーの保持
リダイレクト