Azure DNS Private Resolver を利用してオンプレから名前解決を行う

Azure DNS Private DNS Resolver が ~~Public Preview (2022/05/16)~~ <font color="Red"> GA (2022/10/12) </font> となりました。この機能を利用することでオンプレから Private DNS zone へ名前解決要求を転送できるようになりますので、Azure 上にフォワーダーとして機能する DNS サーバーを構成する必要がなくなります。公開情報でも高可用性や運用費用の削減、高パフォーマンス等の利点があげられています。
実際に検証を行い、検証の中で確認した留意点等をまとめてみましたので利用する際はご一読いただけたらと思います。~~パブリックプレビューですので、今後、修正・変更が入る可能性がある点はご了承ください。~~

https://docs.microsoft.com/en-us/azure/dns/dns-private-resolver-overview

参考手順

https://docs.microsoft.com/en-us/azure/dns/dns-private-resolver-get-started-portal

## 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/97e4df5a-a2a3-4a9e-b4ea-b5dd4e9dce73.png)

### 前提
- 対象リージョンは EastUS (Japan East でも GA しており検証済み。) ~~<font color="Red">※2022/05/17 時点では JapanEast/West はサポートされてません</font>~~
https://docs.microsoft.com/en-us/azure/dns/dns-private-resolver-overview#regional-availability
- 構成図内の DNS Private Resolver と DNS forwarding rule set 以外のリソースは作成済みであること
- Onpre-VNet / Hub-VNet / Sopke1 の各仮想ネットワークは相互に通信できる構成であること (VNet ピアリングの Use remote gateway 有効)
- Hub-VNet に受信エンドポイント、送信エンドポイント専用のサブネットを作成済みであること (/24-/28 の範囲)

## 用語、機能について

- 受信エンドポイント : DNS フォワーダーとして名前解決要求をうけつけるエンドポイント
- 送信エンドポイント : 条件付き転送を行うためのエンドポイント。受信エンドポイントとは別の専用サブネットが必要となります。
- DNS 転送ルールセット : 条件付きフォワーダーのルールをまとめたグループ。送信エンドポイントと関連付けて利用します。
- 仮想ネットワーク リンク : DNS 転送ルールセットの条件付きフォワーダーを利用する仮想ネットワークを指定します。

## 1. DNS Private Resolver [Inbound Endpoint (受信エンドポイント)]

以下の構成図のような流れで自宅の端末から VPN と DNS Private Resolver の受信エンドポイントを経由して Private DNS zone の名前解決を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9f18dc48-e00d-e62f-7476-309658210070.png)

### 1-1. リソース作成
まず DNS Private Resolver のリソースを作成して、自宅から Private DNS zone の名前解決を行い、Private Endpoint への接続を試してみます。

1. 以下のリンクから preview が有効化されているポータルにログインします。
https://go.microsoft.com/fwlink/?linkid=2194569

2. ポータル上の部の検索画面で dns と検索し、"DNS Private Resolver" を選択します。
実際の操作画面は利用する時期によって異なる可能性があります。見つからない時は Marktplace から resolver や ruleset を検索してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9618f899-30bc-f502-f11a-509763ddbc45.png)

3. サブスクリプション、リソースグループ、名前、リージョン、仮想ネットワークを選択/入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/5aacc6cd-6851-677b-2b74-d6ca77707bef.png)

4. 受信エンドポイント用のサブネットの名前を入力し、サブネットを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/28e639bc-f319-30d3-c29b-46dbe2dd9a3d.png)

5. 送信エンドポイント、ルールセットは作成せずに進み、作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/8b984db4-3e26-0812-cb1a-3bcf4109263a.png)

6. リソースが作成できたらリソースの画面に移動し、受信エンドポイントから IP アドレスを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/d868731d-2539-aee4-dfa3-53f078392d18.png)

### 1-2. 動作確認
1. 自宅から P2S VPN 経由で Azure に接続し、DNS Private Resolver で名前解決を行えるか確認します。
クライアントの DNS が適切に構成されていないため、そのままだと BLOB のパブリックのエンドポイントが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/00942c4d-13df-99f5-0b38-996fb87e007c.png)

2. 受信エンドポイントの IP アドレス "10.0.0.4" を付け足して、nslookup を実行します。
期待通り、BLOB の Private Endpoint 用の IP アドレスが返ってきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/0596eaf4-0db5-127b-7d9e-183465c7616b.png)

3. クライアントの DNS の設定を 10.0.0.4 に変更し、WSL の curl コマンドにて BLOB へ接続してみます。
問題なく Private Endpoint 経由で接続できました。
```
$ curl -v https://testdnsresolver.blob.core.windows.net/test1/index.html
*   Trying 10.0.5.4:443...
* TCP_NODELAY set
* Connected to testdnsresolver.blob.core.windows.net (10.0.5.4) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=*.blob.core.windows.net
*  start date: Feb 25 18:47:29 2022 GMT
*  expire date: Feb 25 18:47:29 2023 GMT
*  subjectAltName: host "testdnsresolver.blob.core.windows.net" matched cert's "*.blob.core.windows.net"
*  issuer: C=US; O=Microsoft Corporation; CN=Microsoft RSA TLS CA 02
*  SSL certificate verify ok.
> GET /test1/index.html HTTP/1.1
> Host: testdnsresolver.blob.core.windows.net
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 12
< Content-Type: text/html
< Content-MD5: bLL+2vK0uXm1HPdaivMY1w==
< Last-Modified: Tue, 17 May 2022 01:25:57 GMT
< ETag: 0x8DA37A431D6A9A2
< Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
< x-ms-request-id: 436326b5-c01e-008d-0f99-69d72c000000
< x-ms-version: 2009-09-19
< x-ms-lease-status: unlocked
< x-ms-blob-type: BlockBlob
< Date: Tue, 17 May 2022 02:53:22 GMT
<
* Connection #0 to host testdnsresolver.blob.core.windows.net left intact
﻿Test BLOB
```

## 2. DNS Private Resolver [Outbound Endpoint (送信エンドポイント)]

以下の構成図のような流れで、Spoke 側の VM から DNS Private Resolver の送信エンドポイントと VPN を経由して、疑似オンプレ環境 (Azure) の DNS サーバーを利用した名前解決を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/2ba5fb01-3bb9-4bdf-e7ff-1ceef34d2fe1.png)

### 2-1. 送信エンドポイントの設定

1. DNS サーバーに事前にテスト用の A レコード (test1.testdnsreslvzone.com/10.0.0.1) を追加しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/7c7edd34-a5a8-384d-5049-217c5d3f33ec.png)

2. 送信エンドポイントの名前を入力し、サブネットを選択して、保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/346377c5-bad1-f2cd-2b54-f0c573f48a04.png)

~~outbound 用のサブネットを 10.0.1.0/24や 10.0.4.0/26 で作ったところ、以下のエラーで失敗してしまいました。Validation の不具合のように見えますが、先に進めませんでしたので公開ドキュメントを真似て 10.1.1.0/26 で作ったところ成功しました。現時点ではエラーにあるような 10.0.x.0/24 のようなアドレス帯は使わないほうがよさそうです。 <font color="Red">ポータルの Warning にある通り、10.0.0.0/24 - 10.0.16.0/24 のアドレス空間は使えないようです。</font>~~ (2024/12/06 問題なく使えることを確認)



### 2-2. DNS 転送ルールセットの設定
1. DNS 転送ルールセットの設定の作成
ポータル上の部の検索画面で dns と検索し、"DNS 転送ルールセット" を選択します。
実際の操作画面は利用する時期によって異なる可能性があります。見つからない時は Marktplace から resolver や ruleset を検索してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9618f899-30bc-f502-f11a-509763ddbc45.png)

2. サブスクリプション、リソースグループ、ルールセット名、リージョン、Private Resolver、Outbound endpoints を選択/入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/2152d48d-287e-8dcf-afa4-85f87811a129.png)

3. ルール名、ドメイン名、ルールの状態 [Enable のまま]、接続先 IP アドレス [DNS サーバー] を設定し、追加を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/a4f6b08d-fa78-2363-5ba1-c13a847e03a6.png)

4. 仮想ネットワーク リンクの追加で Spoke 用の仮想ネットワークを指定し、追加を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b213a804-b073-3e1d-e2b0-f49b6fb8030b.png)

5. ルールセットを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/8bffa7b0-7432-9049-1e57-dad2ad3f1146.png)

### 2-3. 動作確認

SpokeVM1 から test1.testdnsreslvzone.com を nslookup した際、ルールセットを作成する前は、"Non-existent domain" のエラーで終わっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/58020021-d810-cfd4-4e61-341d9c5a08ad.png)

ルールセットを作成した後は下記のように Azure provided DNS 経由で、疑似オンプレ環境の DNS サーバーの名前解決ができるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/e67869fb-0f8f-d65a-cbd2-4032588b1848.png)

~~ただし、プレビューのためかこの条件付きフォーワーダーの動作は不安定なようで、二回に一回くらいはタイムアウトが出る動作となってました。受信エンドポイントと比べるとこちらはまだまだ改善が必要そうです。~~ <font color="Red">GA 後は安定して名前解決できました。</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/de4f32f4-1ef6-7bea-d5cb-619513080a52.png)

ちなみに送信エンドポイントを利用する場合、クライアントと送信エンドポイントのサブネットとの接続は必須ではないようで、以下の様に VNet ピアリングを削除した状態でも利用可能でした。需要があるかはわかりませんが、条件付きフォワーダーのドメインをドット (.) としてすべての要求を指定した DNS サーバーに転送することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/993b44c2-3ada-622a-2628-5f7246ac6e20.png)

https://learn.microsoft.com/ja-jp/azure/dns/private-resolver-endpoints-rulesets#rules


~~こちらも高確率でタイムアウトが発生していたので、今後の改善に期待したいです。~~ <font color="Red">GA 後は安定して名前解決できました。</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/3ae51b7d-ca49-eeb2-a442-85fd5445d7e8.png)

ちなみに DNS サーバー側からみたときの送信元アドレスは送信エンドポイントで指定したサブネット内のアドレスが複数利用されておりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/fba6f550-0857-3afb-adb0-0ad08a3665e9.png)


## 3. DNS Private Resolver [送受信のエンドポイントを利用]

公開ドキュメントの以下のアーキテクチャを見る限り、受信エンドポイントで名前解決要求を受け付けた後、条件付きフォーワーダーと送信エンドポイントを利用できるように読み取れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/34390706-a511-1684-d002-98b2a4c12f81.png)

そのため、以下のような動作が可能かも試してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/0511bc2e-34bb-fe09-e3dd-b7761ba7ecf8.png)

自宅から受信エンドポイントを指定して、nslookup した際、ルールセットを作成する前は、"Non-existent domain" のエラーで終わっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b68e297f-b78f-e1bc-7c41-3a710a7203a8.png)

DNS 転送ルールセットに Hub-VNet のリンクを追加したところ、~~タイムアウトは発生しましたが、疑似オンプレ環境の DNS サーバーの名前解決ができるようになりました。~~ <font color="Red">GA 後は安定して名前解決できました。</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/e055ac19-52e7-9ea9-882d-15e7e9d4c4a1.png)

## 4. 名前解決のフロー

公開情報の内容と確認した動作をふまえると DNS Private Resolver を利用した名前解決は以下のようなフローチャートになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b8b5171e-ab3e-0ac1-b544-72e175912587.png)