0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

App Service を Public IP なしで社外公開する:Entra Application Proxy を使った構成を検証してみた

0
Posted at

はじめに

Azure App Service を社外向けに公開したいけれど、「Public IP は持たせたくない」「IP 制限ではなくユーザー単位で認証・認可をかけたい」というご相談を頂くことがあります。

このようなケースで使える選択肢の 1 つが Microsoft Entra Application Proxy(以下、App Proxy) です。本記事では App Service の publicNetworkAccess = Disabled(パブリックアクセス無効)の状態で、App Proxy 経由で社外ブラウザからアクセスできる構成を実際に検証してみました。実際に E2E で疎通まで確認できたので、構成と手順、ハマりどころを残しておきます。

公式ドキュメントは以下です。

※ 記事作成の補助に GitHub Copilot を活用しています。


目的

以下の 4 点を同時に満たす構成を作ることが今回のゴールです。

要件 採用したアプローチ
インバウンドのパブリックアクセスをゼロにしたい App Service の publicNetworkAccess = Disabled + Private Endpoint
社外ユーザーがブラウザだけでアクセスしたい Entra Application Proxy(リバーストンネル方式)
認証を Entra ID で一元管理したい App Proxy の Pre-Authentication 機能
アプリ側でもユーザーを識別・制御したい App Proxy が転送するヘッダーを使ったアプリ内認可

なお、本来 App Service を社外公開するのであれば、Application Gateway(+ WAF)や Front Door などを前段に置く構成が望ましいケースが多いかと思います。今回はそもそも インバウンド向けのパブリック IP を一切持ちたくない という要件があったため、あえて App Proxy を使った構成を検証しています。後述の通り、この構成でもパブリック IP は残りますが、それは Connector VM のアウトバウンド通信用 のものに限定されます。


前提知識

Entra Application Proxy とは

App Proxy は、社内・プライベートに置かれた Web アプリを 顧客側のインバウンドポートを 1 つも開けずに 社外公開できるリバースプロキシサービスです。

仕組みとしては、お客様の VNet 内に「Connector」と呼ばれるエージェントを Windows Server VM 上にインストールし、Connector から Microsoft クラウドに対して outbound 443 のみ で接続を維持します(リバーストンネル)。社外ユーザーからのリクエストはこのトンネルを通ってバックエンドに届きます。

公式のネットワーク トポロジはこちら。

社外ユーザー ─HTTPS→ *.msappproxy.net(Microsoft 管理)
                            │  リバーストンネル (outbound 443 のみ)
                       Connector VM(顧客 VNet 内)
                            │  Private Network
                       App Service(publicNetworkAccess = Disabled)

ライセンス要件

App Proxy の利用には Entra ID P1 / P2 のライセンスが必要です(無料 SKU では使えません)。


構成

全体構成

リソース一覧

種別 役割 パブリック面
App Service 業務アプリ本体 なし (publicNetworkAccess = Disabled)
Private Endpoint App Service への VNet 内接続口 なし
Private DNS Zone (privatelink.azurewebsites.net) Connector VM からの名前解決を Private IP に向ける なし
仮想ネットワーク + サブネット 3 つ ネットワーク基盤 なし
Connector VM (Windows Server 2022) App Proxy Connector ホスト なし(Private IP のみ)
NAT Gateway Connector の outbound 443 出口 あり(送信専用)
Azure Bastion Connector VM への管理アクセス あり(管理専用)

認証・認可の設計

ここが今回検証で一番悩んだポイントです。App Proxy の Pre-Authentication と App Service の Easy Auth(組み込み認証) はそれぞれ独立してオン/オフできるため、組み合わせで 4 パターン存在します。

パターン比較

# App Proxy Pre-Authentication App Service Easy Auth 認証の担当 評価
あり (Entra ID) なし App Proxy が完全に担当 本記事の構成(推奨)
なし (Passthrough) あり (Entra ID) Easy Auth が担当 代替可。ただし App Proxy 側の条件付きアクセスは効かない
あり (Entra ID) あり (Entra ID) 二重認証 非推奨。設定ミスで陥りやすい罠
なし (Passthrough) なし 認証なし アプリ自前認証がある場合のみ

パターン①(推奨)— App Proxy Pre-Auth のみ

[社外ユーザー] → App Proxy(Entra ID 認証)→ Connector → App Service(Easy Auth 無効)
                   ↑ここで認証・認可を完結

App Proxy が Entra ID によるサインインを強制するため、未認証・未割り当てのリクエストはバックエンドに届きません。アプリ側はヘッダーを読むだけで済み、認証ロジックを実装する必要がありません。

サインイン済みユーザーの情報は、ヘッダーベース SSO の設定で以下のような HTTP ヘッダーとしてバックエンドに転送されます。

ヘッダー名 ソース属性 内容
X-AppProxy-UPN user.userprincipalname ユーザー プリンシパル名
X-AppProxy-Email user.mail メールアドレス
X-AppProxy-OID user.objectid Entra ID オブジェクト ID(GUID)

ヘッダー名は任意に決められます。アプリ側はこれらのヘッダーを読むだけで、認証済みユーザーの情報を取得できます。

ヘッダーベース SSO の設定方法は公式手順をご参照ください。

パターン③(要注意)— 二重認証

[社外ユーザー] → App Proxy(Entra ID 認証)→ Connector → App Service(Easy Auth 有効)
                   ↑1回目                                  ↑2回目(競合)

App Proxy と Easy Auth の両方が独立してトークン検証を要求するため、認証ループや二重サインインが発生する場合があります。Easy Auth は Authorization ヘッダーを書き換えるため、App Proxy のトークンと競合することもあります。

App Proxy を導入する際は、App Service 側の認証機能(Easy Auth)は必ず無効化 することがポイントです。

認証フロー全体


構築手順

1. ネットワーク基盤のデプロイ

VNet とサブネットを作成します。

  • snet-connector:Connector VM 配置用
  • snet-pe:App Service 用 Private Endpoint 配置用
  • AzureBastionSubnet:Bastion 用(/26 以上)

加えて、Connector VM の outbound 443 を集約するための NAT Gateway を snet-connector に関連付けます。

2. App Service のパブリックアクセス無効化

az webapp update -g <リソースグループ> -n <アプリ名> \
    --set publicNetworkAccess=Disabled

これで publicNetworkAccessDisabled になり、インターネットからの直接アクセスは遮断されます。ポータル上も Networking → Public network access = Disabled と表示されます。

05-appservice-public-disabled.png

3. Private Endpoint と Private DNS Zone

App Service 用の Private Endpoint を snet-pe に作成し、privatelink.azurewebsites.net の Private DNS Zone を VNet にリンクします。これで Connector VM から <アプリ名>.azurewebsites.net を引いたときに、Private IP(例: 10.50.1.4)が返るようになります。

# Connector VM 上で名前解決を確認
nslookup <アプリ名>.azurewebsites.net
# → Address: 10.50.1.4 (PE の Private IP)を返すこと

公式手順はこちら。

4. Connector VM の作成

snet-connector に Windows Server 2022 の VM をデプロイします。Public IP は付与しません。NSG は inbound すべて Deny、outbound 443 を許可します。管理アクセスは Azure Bastion 経由で行います。

VM 上で nslookup <アプリ名>.azurewebsites.net を実行し、Private IP が返ってくることを確認します。

5. App Proxy Connector のインストール

Entra 管理センターから Connector のインストーラをダウンロードし、Connector VM 上で実行します。インストール時にグローバル管理者でサインインすると、Connector が Entra テナントに登録されます。

  • Entra 管理センター → Application Proxy

正常にインストールされると、Connector のステータスが Active になります。

01-connector-active.png

補足(条件付きアクセスでハマった場合): Connector のインストーラは内部で WebView2 によるサインイン画面を出します。このダイアログは FIDO キーや証明書ベース MFA 等の条件付きアクセスポリシー下では完了できないことがあります。
その場合は、サービスだけ先に静かにインストール(/q)した上で、別端末で az account get-access-token --resource https://proxy.cloudwebappproxy.net/registerapp でトークンを取得し、VM 上の Register-AppProxyConnector -AuthenticationMode Token -Token <SecureString> で登録するという回避策が使えます。

6. Enterprise Application としてアプリを公開

Entra 管理センター → Enterprise applicationsNew applicationOn-premises application から、以下の項目を設定します。

項目 設定値
Internal URL https://<アプリ名>.azurewebsites.net/
External URL https://<アプリ名>-<テナント名>.msappproxy.net/(既定)
Pre-Authentication Microsoft Entra ID
Connector Group 作成した Connector グループ
Translate URLs in Headers Yes

その後、Users and groups からアプリにアクセスを許可するユーザーを割り当て、Single sign-on で前述のヘッダーマッピングを設定します。

02-enterprise-app-overview.png

03-sso-header-based.png

04-users-and-groups.png

7. 動作確認

社外ネットワーク(テザリング等)からブラウザで External URL にアクセスし、以下の動作を確認します。

シナリオ 期待動作
未サインインで外部 URL にアクセス Entra サインイン画面にリダイレクト
割り当て済みユーザーでサインイン アプリ画面が表示され X-AppProxy-UPN ヘッダーを確認できる
アプリ未割り当てユーザーでサインイン App Proxy レベルで拒否(バックエンドに届かない)
社外から直接 azurewebsites.net にアクセス 接続不可(Public アクセス無効のため)

実際にアプリを開くと、X-AppProxy-UPN / X-AppProxy-Email / X-AppProxy-OID ヘッダーがアプリに届いていることと、判定結果が ALLOWED になっていることが見えます。

06-poc-app-allowed.png


ハマりどころ・注意点

Header-based SSO の保存に P1 ライセンス保有者のアサインが必要

今回いちばんハマったのがこれです。Single sign-on でヘッダーマッピングを設定して保存しても、再度開くと SSO 方式が「Disabled」に戻ってしまう という現象が発生しました。

原因は、対象アプリに Entra ID P1 ライセンスを持つユーザーが 1 人もアサインされていなかった ことでした。Header-based SSO は P1 機能のため、保存時に「P1 を持つ割り当て済みユーザーが 1 人以上いること」がチェックされるようです。
手順としては 「ユーザー割り当て → SSO 設定保存」の順 で進めるのが安全です。

Azure サブスクリプションと Entra テナントが別組織でも OK

今回の検証は、Azure リソースは A サブスクリプション、Entra / App Proxy 設定は B テナント、という構成で実施しました。Connector を登録するテナントと Enterprise App を作成するテナントが 同一 であれば、Azure サブスクリプションと Entra テナントは別の組織でも構成可能です。マルチテナント運用や、リソース管理用テナントと従業員 ID テナントが分離している環境でも導入できます。

App Service の SKU クォータ

当初 Japan East で構築を試みたのですが、Free / PremiumV3 の SKU クォータが 0 で App Service Plan の作成に失敗しました。本番ではリージョン選定の前にクォータ確認を行うのが安全です。

Easy Auth の二重有効化

前述の通り、App Proxy の Pre-Authentication を使う場合は App Service の認証機能(Easy Auth)を必ず無効化します。両方有効にするとトークンが競合してハマります。

残存するパブリック IP

「パブリックアクセスゼロ」と言いつつも、以下の用途でパブリック IP が残ります。

  • NAT Gateway:Connector VM の outbound 443(App Proxy クラウドへ)の送信元 IP
  • Azure Bastion:管理者の RDP アクセス用

どちらもアプリの inbound 公開には使われませんが、構成上は残ります。Bastion については Private-only deployment(プレビュー)でパブリック IP を不要にできますが、その場合は管理者端末から VNet までのプライベート接続(ExpressRoute / VPN Gateway)が別途必要です。

App Proxy の機能制限

WebSocket、1GB 超レスポンス、長時間接続(タイムアウト 4 時間)など、App Proxy ではサポートされない通信があります。リアルタイム性の高いアプリは事前確認が必要です。

ヘッダー偽装リスク

X-AppProxy-* ヘッダーは単なる HTTP ヘッダーなので、App Proxy を経由しない経路から偽装されると認可をすり抜ける可能性があります。publicNetworkAccess = Disabled で直接アクセスを完全に遮断することが必須の防御策となります。


まとめ

App Service を Public IP なしで社外公開する手段として、Entra Application Proxy は非常に有効な選択肢でした。今回は E2E 検証として、未認証アクセス / 許可ユーザーアクセス / 許可外ユーザーアクセス / 直接アクセス遮断 の 4 つのシナリオをいずれも期待通り動かすことができました。特に以下の条件に当てはまる場合は検討する価値があると思います。

  • インバウンドのパブリックアクセスを完全に遮断したい
  • 認証を Entra ID で一元管理し、条件付きアクセスを効かせたい
  • アプリ側に認証ロジックを実装したくない(または既存アプリを改修したくない)

逆に、WebSocket を多用するアプリや、1GB を超えるレスポンスを返すアプリには向きません。要件に応じて Front Door + WAF + Private Link 構成などとの比較検討をおススメします。

認証・認可方式の組み合わせは複数あり、特に App Proxy と Easy Auth の二重有効化はハマりやすいポイントなので、最初に設計の絵を描いてから構築するのが近道かと思います。


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?