【ハマりポイント】AppGW + Azure Firewall + Private Endpoint 構成で Health Probe が失敗した話と解決策
Azure 上でセキュリティを高めた Web アプリケーション基盤を構築する際、Application Gateway (AppGW)、Azure Firewall、Private Endpoint (PE) を組み合わせて Web App を公開する構成はよく使われます。
今回、「ルーティング(UDR)も NSG も問題なく、Azure Firewall Log でも Allow となっているのに、AppGW の Health Probe が失敗して Backend が Unhealthy になる」という現象に遭遇しました。
最終的には Azure Firewall のルールを Network Rule から Application Rule に変更(=SNATを有効化)することで解決 したため、その原因と学びを共有します。
ネットワーク構成と発生した問題
今回構築していた構成は以下の通りです。
全体構成
[ Client ]
│
▼
[ Application Gateway ] (AppGW Subnet: 10.0.1.0/24)
│
▼ (UDR: 10.0.2.0/24 -> Azure Firewall)
[ Azure Firewall ] (FW Subnet: 10.0.0.4)
│
▼ (Target IP: 10.0.2.10)
[ Private Endpoint ] (PE Subnet: 10.0.2.0/24)
│
▼
[ Web App (Backend) ]
発生したエラー
Application Gateway の Backend Health が Unhealthy となり、以下のエラーが出力されていました。
-
AppGW 側のエラー:
ngx_http_upstream_check_err_ServerNotReachable -
クライアント側の表示:
Cannot connect to backend server. Check whether any NSG/UDR/Firewall is blocking access.
一見すると問題なさそうに見えた理由
構築時の確認では、ネットワーク設定に落ち度がないように見えていました。
-
往路の UDR(AppGW Subnet):
10.0.2.0/24宛(PEのサブネット)の通信は Azure Firewall(10.0.0.4)へ転送するよう設定。 -
復路の UDR(PE Subnet):
10.0.1.0/24宛(AppGWのサブネット)の通信も Azure Firewall(10.0.0.4)へ返すよう設定。 -
Azure Firewall ログ:
TCP request from 10.0.1.4 to 10.0.2.10:443 Action: Allowと出力されており、FW までは正常に到達し通過していた。
UDR による対称ルーティングが組まれており、ログ上も Allow であるため、「非対称ルーティング(Asymmetric Routing)は起きていないはず」と考えてドハマりしました。
原因と解決策:なぜ Network Rule ではダメだったのか?
原因:Network Rule と Application Rule の SNAT 挙動の違い
Azure Firewall のルール種別による 送信元 IP アドレス変換(SNAT)の挙動 が影響していました。
| ルール種別 | 送信元 IP アドレスの変換(SNAT) |
|---|---|
| Network Rule | デフォルトでは SNAT されない(元の送信元 IP を維持) |
| Application Rule | 常に SNAT される(送信元 IP が Azure Firewall の IP に置換される) |
Network Rule の場合、送信元 IP が AppGW(10.0.1.4)のまま Private Endpoint に届きます。Private Endpoint 側のネットワーク構成やプラットフォームの応答挙動によっては、戻りのパケットが意図した経路を辿らなかったり、AppGW 側でセッションが正常に認識されず、TCP ハンドシェイクや TLS 接続が途中で失敗することがあります。
Microsoft の公式ドキュメントでも、Private Endpoint 宛の通信を Azure Firewall で検査・制御する場合は Application Rule の使用が推奨 されています。
試したことと結果
Azure Firewall のルール設定を変更し、NSG を調整しました。
-
ルール変更: Azure Firewall.
Azure Firewall のルールを Network Rule から Application Rule に変更。 -
NSG 設定調整: Private Endpoint Subnet.
Application Rule の使用により送信元 IP が Azure Firewall に変換されるため、Private Endpoint Subnet の NSG で Azure Firewall の IP(10.0.0.4)からの 443 通信を許可。
変更後の結果
設定変更後、即座に Application Gateway の Backend Health が Healthy に変化し、Health Probe が成功してサービスが復旧しました!
この事例から学んだ 3 つのポイント
[!IMPORTANT]
1. UDR が正しく設定されていても通信失敗は起こり得る
往路・復路の UDR を正しく設定して対称ルーティングを意識していても、L4(Network Rule)レベルの透過通信では Private Endpoint 特有の制限やプラットフォームの挙動に引っかかるケースがあります。
[!NOTE]
2. Azure Firewall Log のAction: Allowは接続成功を保証しない
ログのAllowは「Firewall がパケットを通過させた」ことしか示していません。その先のハンドシェイク完了や Health Probe の成功まで保証するものではないため、ログだけで「FW は原因から除外」と判断するのは危険です。
[!TIP]
3. Private Endpoint 宛通信は Application Rule (SNAT) を優先検討する
Private Endpoint を経由する構成で Azure Firewall を挟む場合は、最初から Application Rule(または Network Rule での明示的な SNAT 設定) を検討するのが最も安定します。
まとめ
- 現象: AppGW + AzFW + PE 構成で、UDR/NSG/FWログが正常に見えるのに Health Probe が失敗する。
- 原因: Network Rule 使用時の SNAT 非適用に起因する通話不全。
- 解決策: Azure Firewall のルールを Application Rule に変更して送信元 IP を SNAT する。
「設定はすべて合っているはずなのに AppGW から Private Endpoint への Health Probe が通らない…」と悩んだ際は、Azure Firewall の SNAT 挙動(Application Rule への切り替え) をぜひ疑ってみてください!