Azure Private Endpoint のための DNS 構成パターン

Azure の PaaS を ExpressRoute や VPN 経由で利用する場合、Private Endpoint によるアクセスがスタンダードな構成となりますが、その際の名前解決をどのように行うべきかは様々なパターンがあります。本記事では名前解決の方法とアーキテクチャのパターンをまとめておりますので、検討する際に参考にしていただけたら幸いです。

# Private Endpoint における名前解決の必要性
パブリッククラウド上の PaaS はマルチテナント型で構成されることが多く、ほとんどのサービスで特定のホスト名でのアクセスを要求されます。Application Gateway のように元から IP アドレスだけで接続可能なサービスも一部ありますが、様々な PaaS と連携することが多いクラウドでは基本、ホスト名によるアクセスが前提となります。[こちら](https://qiita.com/Isato-Hiyama/items/8798b144ae82957814ff) にも仕組みをまとめてますが、Host ヘッダー、SNI を使う Web アクセスでは必須となります。

# Private Endpoint の名前解決の仕組み
Private Endpoint を PaaS に追加すると xxx.privatelink.xxx という FQDN が CNAME として返ってくるようになります。そのため、この xxx.privatelink.xxx 用の名前解決がプライベート IP (Private Endpoint の IP) に解決されるように構成されているかで、Public Endpoint へのアクセスになるか Private Endpoint へのアクセスになるのかが決まります。

以下は Private Endpoint が Private DNS ゾーンにて解決される際のフローとなります。もし、Private DNS ゾーンが構成されていなかった場合は Public DNS で解決されパブリック IP アドレスへアクセスすることになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/deadb469-6966-8fd9-666a-55f86f061e06.png)

https://learn.microsoft.com/ja-jp/azure/private-link/private-endpoint-dns#virtual-network-workloads-without-custom-dns-server

:::note warn
クライアントと Private Endpoint の間に Web Proxy や L7 ファイアウォール (Azure Firewall アプリケーションルールを含む) がある場合、DNS の構成によっては Private Endpoint の IP アドレスが解決されず、パブリック IP アドレスが利用される可能性があります。トラブルシューティングの際はご確認ください。
:::

:::note info
Azure Migrate の場合は以下のように privatelink の FQDN をそのまま使うサービスがあります。

https://learn.microsoft.com/ja-jp/azure/migrate/troubleshoot-network-connectivity#remediation-1

|プライベート エンドポイント URL を含む DNS マッピング|	詳細|
|-|-|
|*.disc.privatelink.prod.migration.windowsazure.com|	Azure Migrate Discovery のサービス エンドポイント|
|*.asm.privatelink.prod.migration.windowsazure.com|	Azure Migrate Assessment のサービス エンドポイント|
|*.hub.privatelink.prod.migration.windowsazure.com|	他の Microsoft または外部の独立系ソフトウェア ベンダー (ISV) のオファリングからデータを受信するための Azure Migrate ハブ エンドポイント
|*.privatelink.siterecovery.windowsazure.com|	レプリケーションを調整するための Azure Site Recovery サービス エンドポイント|
:::



# 条件付き転送を設定する際の考慮事項

### パブリック DNS ゾーンの転送が推奨される理由

公開情報にもありますが、フォワーダーを利用する際はパブリック DNS ゾーンに対して設定する旨の記載があります。

https://learn.microsoft.com/ja-jp/azure/private-link/private-endpoint-dns?source=docs#on-premises-workloads-using-a-dns-forwarder

:::note warn
条件付き転送は、推奨されるパブリック DNS ゾーン フォワーダーに対して行われる必要があります。 たとえば、 privatelink.database.windows.net ではなく、database.windows.net です。
:::

なぜこのような推奨事項があるかというと、例えば以下の図のように privatelink.database.windows.net という条件付きフォワーダーの設定のみだと、リカーシブ DNS またはフォワーダーの動作によっては privatelink.database.windows.net の条件付き転送を利用せず、パブリック DNS にて名前解決を行ってしまう (パブリック DNS 用のキャッシュが使われる) 可能性があるためです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/70d9e3f2-0983-7695-72f1-6326a39308d4.png)

実際に上記の構成を手元でも試してみましたが、初回の名前解決は Private Endpoint の IP アドレスが返ってきましたが、2 回目以降はパブリック IP アドレスが返ってきており、安定した動作ではありませんでした。この動作は DNS の構成や動作に依存するものと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/4fb204ab-1e83-0ac4-8f3e-976e311c4faf.png)

パブリック DNS ゾーンを条件付き転送している場合は、"Private Endpoint の名前解決の仕組み" に記載した方法にて Azure 側で Private Endpoint の IP アドレスを解決した結果を返すため、上記のような問題になることはありません。***環境によっては両方 (Public/Private) の条件付き転送を設定したほうが良い場合もあるため、想定通りに名前解決ができるかは事前に検証することをお勧めします。***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/a9d5cbf9-0e14-bc9f-e09d-bce74890f101.png)

### DNS フォワーダーの転送条件をゾーン単位とするか FQDN 単位とするか

#### パブリック DNS ゾーン単位

公開情報や上記の例は "database.windows.net" という PaaS 単位で提供されているゾーンを転送の条件としております。このゾーン単位の場合、条件付き転送を設定してしまえば同じゾーンを利用するサービスが増えたとしても条件付き転送設定を追加する必要がないというメリットがあります。
ただし、以下の図のように一つの拠点から複数の Azure 環境へ接続するような構成である場合は DNS を統一するなど、それぞれの環境で正しく名前解決できるように DNS の構成を検討する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/821c6fee-56f3-3648-b546-40e81f577061.png)

#### FQDN 単位

条件付き転送は FQDN 単位でも設定することができますので、FQDN 毎に異なるフォワーダーを指定することで複数の環境の DNS を使用して名前解決を行うことができます。ただし、FQDN が増えるごとに条件付き転送を設定する必要があるというデメリットもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/151f90a9-a7d5-9879-2159-0dd4bb313201.png)

### Azure 上の DNS フォーワーダーの検討
Azure Provided DNS (168.63.129.16) は仮想ネットワークからのみアクセス可能な DNS であるため、オンプレミスから名前解決を転送する場合は、Azure 上にも 168.63.129.16 へ転送するための DNS フォワーダーを構成する必要があります。以下が代表的な 3 つの方法となります。

|#| 方法 | メリット | デメリット | 備考 |
|-|-|-|-|-|
|1| Azure Firewall DNS Proxy | 拡張性、可用性は既定で担保されているため構築・運用が容易。名前解決のログも診断ログで確認できる。 | Azure Firewall の価格が高価。 (Standard SKU 以上) 固定費 $912 程度。 |ネットワークルールで FQDN を利用する場合は必須 |
|2| DNS Private Resolver| 拡張性、可用性は既定で担保されているため構築・運用が容易。価格も Firewall より安価。固定費 $180 程度。エンドポイントの数により変動。 | 特になし |[DNS Security Policy でログを取得可能](https://qiita.com/Isato-Hiyama/items/7bb6483f29e981df9e23)|
|3| Azure VM で構築 | VM のためログ取得やパケットキャプチャ等が容易に行える。個別の設定追加も可能。 | IaaS のため、構築・運用が必要となる。高可用性のため 2 台以上必要。例：D2d v5 (2c/8GB,AHUB) 2 台で $213 程度。||

### Private Endpoint の名前解決方法のおさらい

|#| 方法 | メリット | デメリット |
|-|-|-|-|
|1|Azure Provided DNS (168.63.129.16) を利用する。 ※仮想ネットワークからの接続のみ可能|Private DNS ゾーンを仮想ネットワークにリンクするだけで利用可能|オンプレミスからは利用できない|
|2| DNS フォワーダーにてパブリック DNS ゾーン単位 (database.windows.net 等)で転送する。| DNS フォーワーダーを設定してしまえばその後のメンテナンスが不要となる。 | オンプレミスから複数の Azure 環境に ExpressRoute または VPN で接続している場合、1 環境のみにしか転送できないため、将来的な利用予定も含めて考慮する必要あり。||
|3| DNS フォワーダーにて FQDN 単位で転送する。(azsql1.database.windows.net 等) | Azure 環境が複数ある場合でも対応が可能。 | Private Endpoint を作成するたびに DNS の登録が必要になる。 |
|4| オンプレミスの DNS に対して A レコードを作成する。利用する FQDN 単位でゾーン作成が可能である必要あり。| DNS フォワーダーの構成が不要。柔軟性が高い。| Private Endpoint を再作成した場合は対応が必要になる可能性がある。また、Azure Database for PostgreSQL のように Private Endpoint を使わずプライベートアクセスを実現してる場合、静的 IP が保証されてないサービスもある。[Link](https://learn.microsoft.com/ja-jp/azure/postgresql/flexible-server/concepts-networking#host-name)|
|5| Hosts を利用する。| DNS の設定が不要。 | Private Endpoint を作成するたびに全利用端末の Hosts の更新が必要となる。 |

# Private Endpoint と Private DNS ゾーンの関係
Private Endpoint を作成する際に関連する Private DNS ゾーンを同時に作成することができますが、Private Endpoint へアクセスする際に ***Private DNS ゾーンによる名前解決は必須ではありません。***

ホスト名でアクセスした際に、正しく Private Endpoint に割り当てられた IP アドレスに解決できれば問題ありませんので、***オンプレ DNS の A レコードや hosts ファイルを使うことも技術的には可能***です。ただし、
設定や運用のしやすさ等は考慮する必要があります。Private DNS ゾーンを連携しておくとリソース作成・削除時に自動的にレコード登録・削除をしてくれるというメリットもあります。

なお、以下にもありますが、Private Endpoint の IP アドレスはリソースを削除しなければ変わることはありません。

https://learn.microsoft.com/ja-jp/azure/private-link/private-endpoint-overview#private-endpoint-properties

:::note info
インターフェイスには、プライベート リンク リソースにマップされる、サブネットからの動的プライベート IP アドレスが割り当てられます。 プライベート IP アドレスの値は、プライベート エンドポイントのライフサイクル全体にわたって変更されません。
:::

# DNS 構成パターンを検討するにあたっての前提
- ExpressRoute または VPN で Azure とオンプレと接続している (Virtual WAN の構成は考慮できてません)
- Hub & Spoke の構成となっている
- オンプレミスと Azure VM から Private Endpoint 経由で PaaS に接続する要件がある
- Private Endpoint の名前解決だけを対象とする (他のゾーンは対象としない)
- Azure Monitor Private Link Service、Application Insight、AVD 等の FQDN が共通となるサービスは利用してない (考慮点がふえるため、本記事では除外)
- [Azure Machine Learning](https://learn.microsoft.com/ja-jp/azure/machine-learning/how-to-custom-dns?view=azureml-api-2&tabs=azure-cli) のように対象が動的に増減するサービスは対象外

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/466dc22c-bbeb-2331-c1f5-4ce743f7d2b1.png)

## アーキテクチャ検討

DNS 構成パータンとして集約型 (Hub VNet に集約) か分散型 (Spoke VNet 毎に配置) になるかと思います。アーキテクチャを検討する際は以下のような要素を参考に検討いただければと思います。

|要件|集約型/分散型| 
|-|-|
|Azure Firewall のネットワークルールで FQDN ベースのルールを使う要件がある| 集約型 (DNS Proxy 経由必須)|
|Private Endpoint 以外の機能でプライベート IP が提供されており、IP が動的である |集約型 (分散型1 も可能)|
| Azure VM が Active Directory のドメインに参加する要件がある (AVD 等) |集約型|
|共通基盤のような利用形態になっており、Hub 側での管理に集約したい |集約型|
|共通基盤のような利用形態になっているが、自由度を優先し Spoke 側で管理したい |分散型|
|"Hub - Spoke1 - Spoke2" のような隔離された VNet から名前解決する要件がある |分散型|


### 集約型1 (オンプレ、各 Spoke からの名前解決はすべて Hub VNet に集約)

Microsoft の CAF ではこの構成が記載されています。

https://learn.microsoft.com/ja-jp/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale

| メリット | デメリット | 
|-|-|
|Private DNS を集約可能|Hub と Spoke の管理部門が異なる携帯の場合、Spoke 側の自由度が下がる。また、複数の VNet から同一リソースを利用する場合に課題あり。Hub - Spoke1 - Spoke2 のような構成も対応不可。|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/3b471f59-d03b-2a79-4aa5-beb69b46a168.png)

複数の VNet から同一リソースを利用する場合の課題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/e5ab69e9-2f73-a7cb-8050-df2dd5a869e3.png)

上記のような課題については Hosts を個別に利用するか、Private Endpoint を共有するための VNet を個別に作成し、Spoke 間で共有するといった方法があります。後者の方法は以下の公開ドキュメントにもあります。

https://learn.microsoft.com/ja-jp/azure/private-link/private-endpoint-dns-integration#virtual-network-workloads-without-custom-dns-server

### 集約型2 (オンプレからの名前解決のみ Hub VNet に集約)

| メリット | デメリット | 
|-|-|
|集約型1 の課題は解決可能。|Hub と Spoke の管理部門が異なる携帯の場合、Spoke 側の自由度が下がる。また、同一ゾーンの複数リソースの利用時に課題あり。Hub - Spoke1 - Spoke2 のような構成も対応不可。|

オンプレから名前解決をする必要がある Private DNS ゾーンだけを Hub VNet に関連付ける方法により、集約型1 の "複数の VNet から同一リソースを利用する場合の課題" は解決できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/5611689b-89a5-9d9e-e76e-dc24db9b0f9c.png)

ただし、以下の様に複数の Private DNS ゾーンを 1 つの VNet に関連付けることができないため、複数のリソースで Private DNS ゾーンを分けて構成し、あとからオンプレから接続する要件が出てきた場合等には対応できないことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/1dc002f6-7d20-2457-b4a1-94be745deb53.png)


### 分散型1 (Spoke 毎にフォワーダーを配置し、FQDN 単位で転送)

オンプレから名前解決要求がある FQDN のみ適切な DNS フォワーダーに名前解決要求を転送するようにオンプレの DNS で条件付き転送を設定します。Private DNS ゾーンは Hub には関連付けせず各 Spoke で管理します。

| メリット | デメリット | 
|-|-|
|柔軟性が高い。様々なシナリオに対応可能。|DNS フォワーダーが Spoke 毎に必要で、コストもかかる。|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/ce794c82-b7fa-5218-2f2e-920583091162.png)

### 分散型2 (オンプレの DNS A レコードで管理)

オンプレから名前解決要求がある FQDN のみオンプレの DNS の A レコードで管理します。Private DNS ゾーンは Hub には関連付けせず各 Spoke で管理します。

| メリット | デメリット | 
|-|-|
|柔軟性が高い。様々なシナリオに対応可能。|FQDN 単位で前方参照ゾーンの作成が必要になる。リソース再作成により、Private Endpoint の IP アドレスが変わった場合は DNS 側も設定変更する必要がある。ごく一部の Azure Database for PostgreSQL のような Private Endpoint を使わないサービスでは対応できない。|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/d40be471-e437-2fff-efc9-139c34c7f9c5.png)

:::note warn
Azure Firewall のアプリケーションルールでは Host ヘッダー、SNI の FQDN を Azure Firewall が名前解決した宛先に通信する動作となることを確認しております。(クライアントが通信を試みた宛先は上書きされます) 上記の構成ですと、Hub VNet に Private DNS ゾーンがリンクされていないため、Azure Firewall 上でパブリック IP アドレスが解決され、結果としてアクセスが失敗します (PaaS 側のファイアウォールで拒否されます)。そのような場合はネットワークルールでの通信制御をご検討ください。
:::

## Public Endpoint (サービスエンドポイント含む) と Private Endpoint 併用時の注意点

例えば VNet1 からは Private Endpoint、VNet2 からはサービスエンドポイント (宛先は Public のままです) にて BLOB1 にアクセスしている構成とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b3309238-365c-0be0-ac66-556ebd3c676d.png)

この環境に BLOB2 を追加し、VNet2 から Private Endpoint でアクセスできるように構成を追加します。
これにより、BLOB1 の名前解決時に CNAME : ***blob1***.privatelink.blob.core.windows.net の解決を試みるようになりますが、BLOB2 用に作成した Private DNS ゾーンには該当の A レコードがないため、名前解決に失敗します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/212001f1-74e5-f26d-4944-596944340cfa.png)

このような事態を防ぐため可能であれば Public Endpoint と Private Endpoint の併用は避け、どちらかに統一するのが望ましいでしょう。この例であれば以下のような構成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/57745945-1373-cc48-702f-96246c6fbc77.png)

**また、~~パブリックプレビュー (2024/11/20 追記)~~ (2025/2/10 GA) Internet へのフォールバックの機能が追加されております。**
上記に書いたような構成でも NXDOMAIN を返している Private DNS Zone の仮想ネットワークリンクにて "Fallback to Internet" を有効化するとインターネットの名前解決ができるようになり、Private Endpoint を使いつつ、その他のリソースでパブリックエンドポイントの名前解決ができるようになります。この機能が使えるのは Private Link に関連付けられた Private DNS Zone だけです。

https://learn.microsoft.com/en-us/azure/dns/private-dns-fallback

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/3ea4b7a9-f3ce-2bde-1352-cc47a292d4c8.png)

# VNet 毎の Private DNS ゾーンのリンク状態の確認

Private DNS ゾーンを管理する際にどのゾーンがどの仮想ネットワークに関連付けられているかを一覧で見たい時がありますが、現状ポータルからは仮想ネットワークのリンクを一覧でみることができません。

ポータルの Azure Resource Graph Explorer や Auzre PowreShell 等で VNet 毎にリンクされている Private DNS ゾーンを確認することができますので参考にしていただければと思います。

### Azure Resource Graph Explorer

```
resources
| where type == "microsoft.network/privatednszones/virtualnetworklinks"
| extend ZoneName = split(tolower(id), "/")[-3]
| extend VNetId = tostring(properties.virtualNetwork.id)
| extend VNetName = split(tolower(VNetId), "/")[-1]
| project subscriptionId, resourceGroup, name, ZoneName, VNetName, VNetId
| order by VNetId asc
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b7ba0400-1507-8f8c-aa7b-736dd7ed1499.png)

### Azure Powershell

```
Get-AzPrivateDnsZone | foreach { Get-AzPrivateDnsVirtualNetworkLink -ResourceGroupName $_.ResourceGroupName -ZoneName $_.Name } | Select-Object ResourceGroupName,Name,ZoneName,VirtualNetworkId |Sort-Object -Property VirtualNetworkId |ft -AutoSize -Wrap
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9ea8e501-c08a-1812-2065-411e821243bf.png)