Private Endpoint宛のトラフィックをUDRで制御する際の動作と注意点
はじめに
Private Endpoint宛のトラフィックをUDRで制御する(経路上に Azure Firewall を挟んで検査する等)場合、ネットワーク経路設計における注意点があります。
- Private Endpointを設置しているサブネットでPrivateEndpointNetworkPolicies(UDR)の有効化が必要
- 原則SNATが必要
Private Endpoint宛の通信をUDRで制御する構成を検討する機会があり、個人のAzure環境でPoCしながら動作を理解してみました。
VNetのルーティング情報を読み解きながら、Private Endpoint宛のトラフィックにUDRを適用する時の注意点や振る舞いを解説します。
Private Endpointを使用しない時のルート
まずはPaaS(ストレージアカウントとSQL Database)を作成し、Private Endpointを作らずに VMから接続します。
この段階ではパブリックIPアドレスで名前解決されます。
$ curl -v telnet://stazpocusw2.blob.core.windows.net:443
* Host stazpocusw2.blob.core.windows.net:443 was resolved.
* IPv6: (none)
* IPv4: 57.150.149.97
* Trying 57.150.149.97:443...
* Connected to stazpocusw2.blob.core.windows.net (57.150.149.97) port 443
VMのルーティングテーブルを確認すると、VNet外はNext HopがInternetとなっています。これはVNetのデフォルト状態です。
$ az network nic show-effective-route-table --resource-group azpoc-vm --name vm-azpoc-usw2-01358_z1 -o table
Source State Address Prefix Next Hop Type Next Hop IP
-------- ------- ---------------- --------------- -------------
Default Active 192.168.0.0/24 VnetLocal
Default Active 0.0.0.0/0 Internet
... (Next Hop TypeがNoneは省略)
Private Endpoint設置時のシステムルート
次に、Private Endpoint用のサブネットを追加し、ストレージアカウントとSQL DatabaseのPrivate Endpointを設置します。
Private DNS Zoneも併せて作成しVNetにリンクしておきます。
これはよくあるPaaS接続パターンではないでしょうか。
この状態でVMのルートテーブルを確認してみると、Private Endpoint宛の/32システムルート(Next Hop TypeがInterfaceEndpointの2行)が自動追加されています。
ルーティングテーブルはロンゲストマッチで経路選択されるので、Private Endpoint宛の通信は常にこの経路が選ばれます。
$ az network nic show-effective-route-table --resource-group azpoc-vm --name vm-azpoc-usw2-01358_z1 -o table
Source State Address Prefix Next Hop Type Next Hop IP
-------- ------- ---------------- ----------------- -------------
Default Active 192.168.0.0/24 VnetLocal
Default Active 0.0.0.0/0 Internet
Default Active 192.168.0.68/32 InterfaceEndpoint
Default Active 192.168.0.69/32 InterfaceEndpoint
... (Next Hop TypeがNoneは省略)
VMからtelnetでストレージアカウントとSQL DatabaseへTCP接続をしてみると、Private DNS ZoneのAレコード値で名前解決され、TCP接続に成功します。
$ curl -v telnet://stazpocusw2.blob.core.windows.net:443
* Host stazpocusw2.blob.core.windows.net:443 was resolved.
* IPv6: (none)
* IPv4: 192.168.0.68
* Trying 192.168.0.68:443...
* Connected to stazpocusw2.blob.core.windows.net (192.168.0.68) port 443
$ curl -v telnet://sql-azpoc-usw2-01.database.windows.net:1433
* Host sql-azpoc-usw2-01.database.windows.net:1433 was resolved.
* IPv6: (none)
* IPv4: 192.168.0.69
* Trying 192.168.0.69:1433...
* Connected to sql-azpoc-usw2-01.database.windows.net (192.168.0.69) port 1433
VNet Peering先のPrivate Endpointへのルート
次は、Private EndpointをVNet2のみに設置し、VNet1とはPeeringした構成で確認します。
VNet1のVMのルートテーブルを確認してみると、先ほどと同じように/32のシステムルートが伝播されていることが確認できます。
Private Endpointのシステムルートは設置しているVNetだけではなく、PeeringしているVNetにも伝播されます。
$ az network nic show-effective-route-table --resource-group azpoc-vm --name vm-azpoc-usw2-01358_z1 -o table
Source State Address Prefix Next Hop Type Next Hop IP
-------- ------- ---------------- ----------------- -------------
Default Active 192.168.0.0/24 VnetLocal
Default Active 192.168.1.0/26 VNetPeering
Default Active 0.0.0.0/0 Internet
Default Active 192.168.1.4/32 InterfaceEndpoint
Default Active 192.168.1.5/32 InterfaceEndpoint
... (Next Hop TypeがNoneは省略)
つまり、Peeringを介さず直接PaaSへ接続していることになります。
結果的に構成図の経路と同等の振る舞いとなるように、Azure SDNが裏でいい感じに制御してくれているようです。
VMからtelnetでストレージアカウントとSQL DatabaseへのTCP接続も成功します。
Private Endpoint宛のトラフィックをUDRで制御する要件がなければ、このままの構成で問題ありません。
# vm serial console
$ curl -v telnet://stazpocusw2.blob.core.windows.net:443
* Host stazpocusw2.blob.core.windows.net:443 was resolved.
* IPv6: (none)
* IPv4: 192.168.1.4
* Trying 192.168.1.4:443...
* Connected to stazpocusw2.blob.core.windows.net (192.168.1.4) port 443
$ curl -v telnet://sql-azpoc-usw2-01.database.windows.net:1433
* Host sql-azpoc-usw2-01.database.windows.net:1433 was resolved.
* IPv6: (none)
* IPv4: 192.168.1.5
* Trying 192.168.1.5:1433...
* Connected to sql-azpoc-usw2-01.database.windows.net (192.168.1.5) port 1433
Private Endpoint宛の通信をUDRで制御する時のルート
次に、Private Endpoint宛のトラフィックをUDRでAzure Firewall経由にし、トラフィックを検査してみます。
ここでは設計上の注意として PrivateEndpointNetworkPoliciesの有効化 と SNAT(経路対称化) の考慮が必要です。
Private Endpoint宛のトラフィックのNext HopをAzure FirewallとするUDRを作成し、VMのサブネットに割り当てます。
Private Endpointサブネットのアドレス(192.168.1.0/26)をNext Hop = Virtual Appliance(FirewallのプライベートIP:192.168.0.68)にします。
この状態でVMのルートテーブルをState列に注目して確認してみます。
UDRのルート(Source列がUserの行)が挿入されており、Address Prefixが同じ/26のシステムルート(Next Hop TypeがVNet Peeringの行)はInvalidとなりました。システムルートはUDRで上書きができるためです。
しかし、まだ/32のシステムルート(Next Hop TypeがInterfaceEndpointの2行)がActiveになっています。
$ az network nic show-effective-route-table --resource-group azpoc-vm --name vm-azpoc-usw2-01358_z1 -o table
Source State Address Prefix Next Hop Type Next Hop IP
-------- ------- ---------------- ----------------- -------------
Default Active 192.168.0.0/24 VnetLocal
Default Invalid 192.168.1.0/26 VNetPeering
Default Active 0.0.0.0/0 Internet
User Active 192.168.1.0/26 VirtualAppliance 192.168.0.68
Default Active 192.168.1.4/32 InterfaceEndpoint
Default Active 192.168.1.5/32 InterfaceEndpoint
このままではロンゲストマッチでAddress Prefixが/32のルートが選択されてしまい、Private Endpoint宛のトラフィックはInterfaceEndpoint宛となり、Azure Firewallに転送されません。
Private Endpoint宛のトラフィックにUDRを適用するには、Private Endpointを設置しているVNet2側のサブネットの設定で、PrivateEndpointNetworkPoliciesのルートテーブルを有効化する必要があります。
PrivateEndpointNetworkPoliciesを有効化した後、再度VMのルートテーブルを確認してみると、Address Prefixが/32のシステムルートのStateがInvalidに変わりました。これでUDRのルート(Source列がUserの行)が選択されるようになります。
$ az network nic show-effective-route-table --resource-group azpoc-vm --name vm-azpoc-usw2-01358_z1 -o table
Source State Address Prefix Next Hop Type Next Hop IP
-------- ------- ---------------- ----------------- -------------
Default Active 192.168.0.0/24 VnetLocal
Default Invalid 192.168.1.0/26 VNetPeering
Default Active 0.0.0.0/0 Internet
User Active 192.168.1.0/26 VirtualAppliance 192.168.0.68
Default Invalid 192.168.1.4/32 InterfaceEndpoint
Default Invalid 192.168.1.5/32 InterfaceEndpoint
Azure Firewallにアプリケーションルールを投入しておきます。VNet1からすべての宛先を許可しています。
これでVMからAzure Firewall宛のUDR設定と、Azure Firewallのルール設定ができたので、VMから疎通をしてみます。
Azure Firewallでアプリケーションルールを使用している構成で疎通確認を行うときには、使用するプロトコルで注意が必要です。
アプリケーションルールでDenyアクションが動いた場合でも、L4のTCP 3way handshakeは成功します。
TCP接続だけではアプリケーションルールの疎通確認にはならないので、L7のプロトコルを使う必要があります。
今回はストレージアカウントはAzure CLI、SQL Databaseはsqlcmdで疎通確認を行います。
Azure CLIを用いたBLOBストレージへの接続も成功します。
$ az storage blob list --auth-mode login --account-name stazpocusw2 -c poc -o table
Name Blob Type Blob Tier Length Content Type Last Modified Snapshot
-------- ----------- ----------- -------- -------------- ------------------------- ----------
test.txt BlockBlob Hot 5 text/plain 2025-09-21T05:07:32+00:00
sqlcmdで接続も成功しました。
$ sqlcmd -S sql-azpoc-usw2-01.database.windows.net -U azpoc -d sqldb-azpoc-usw2-01
Password:
1> SELECT client_net_address FROM sys.dm_exec_connections WHERE session_id = @@SPID;
2> GO
client_net_address
------------------------------------------------
192.168.0.69
L7のプロトコルを用いた疎通確認も成功し、Azure FirewallのログにもAllowアクションとして記録されました。
まとめ
Private EndpointをVNetに設置すると、Private EndpointのプライベートIPアドレス/32のInterfaceEndpointシステムルートが自動伝播(Peering先のVNetにも)されます。Private Endpoint宛のトラフィックはロンゲストマッチで常に/32の経路が選択され、ダイレクトに到達します。
UDRでPrivate Endpoint宛のトラフィックを制御する場合は、Private Endpointを置いている側のサブネットでPrivateEndpointNetworkPoliciesを有効化(これにより/32のInterfaceEndpointシステムルートがInvalidになりUDRが効く)します。
また、UDRでPrivate Endpointの戻りのトラフィックを制御することはできないので、Azure Firewallでトラフィック検査をする場合は、経路の対称化のためにSNATが必要です。
参考
Discussion