Delegation(委任)カテゴリで作成されたRoute 53 Resolver インバウンドエンドポイントは再帰的クエリを実行しません
こんにちは、なおにしです。
Route 53 Resolver インバウンドエンドポイントの「Delegation」カテゴリについて確認する機会がありましたのでご紹介します。
はじめに
先日(2025/6/24)、Route 53 Resolver Endpointがプライベートホストゾーンの DNS 委任をサポートするようになりました。詳細は以下の記事およびアナウンスをご参照ください。
プライベートホストゾーンのDNS委任がサポートされたことに伴い、追加された機能としては大きく分けると以下の2つになります。
Route 53 Resolver インバウンドエンドポイントのカテゴリに「Delegation」が追加
セルフマネージドDNSゾーン等から委任されたゾーンに対するDNS問い合わせに対して、プライベートホストゾーンに登録されているレコードに基づいて権威サーバとして応答できるようになります。
なお、現状ではエンドポイントのプロトコルとしてDo53のみがサポートされていることにはご注意ください。
Route 53 Resolver アウトバウンドトラフィックのルールタイプに「Delegation」が追加
「Delegation」タイプで作成したルールを指定のVPCにアタッチすることで、当該VPCに紐づくプライベートホストゾーン に登録されている委任設定レコード(委任対象ドメインのNSレコードおよび必要に応じてそのグルーレコード)に基づき、対象となるDNS問い合わせをアウトバウンドエンドポイントを経由して外部のDNSサーバに転送することができるようになります。
本記事では、前者のRoute 53 Resolver インバウンドエンドポイントのカテゴリにおける「Delegation」
について少しだけ掘り下げます。
今回のアップデートに関して、エンドポイントカテゴリをDefault
にした場合とDelegation
にした場合のそれぞれの挙動については、以下のドキュメントに処理の流れがまとめられています。
よく読むと、大きな差分としては以下の記述になります。
-
エンドポイントカテゴリ
Default
の場合-
-
Resolver gets the applicable value for the domain name in the DNS query, either internally or by performing a recursive lookup against public name servers.
(リゾルバーは、DNSクエリで指定されたドメイン名に対応する値を、内部的に取得するか、またはパブリックネームサーバーに対して再帰的クエリを実行することで取得します。)
-
-
-
エンドポイントカテゴリ
Delegation
の場合-
-
Resolver returns the address to the AWS resource from the private hosted zone to the inbound endpoint.
(リゾルバーは、プライベートホストゾーンからインバウンドエンドポイントに対して、AWSリソースのアドレスを返します。)
-
-
こうやって比べると、エンドポイントカテゴリDelegation
の場合はパブリックネームサーバーに対して再帰的クエリを実行しないように受け取れるので、実際にどのような挙動になるのか確認してみます。
先に結論
- エンドポイントカテゴリを
Delegation
に設定しているRoute 53 Resolver インバウンドエンドポイントは、対象のVPCに紐付いているプライベートホストゾーンで名前解決が可能なドメインのみ応答します- プライベートホストゾーンに登録されていないAWSリソースの名前解決や、その他のインターネット上のコンテンツの名前解決にもインバウンドエンドポイントを利用する場合(つまり、フルリゾルバとして利用したい場合)は、エンドポイントカテゴリを
Default
に設定する必要があります - プライベートホストゾーンで名前解決可能なドメインには、インターフェース VPC エンドポイントを作成し、プライベートDNS名を有効にしたAWSサービスが含まれます
- プライベートホストゾーンに登録されていないAWSリソースの名前解決や、その他のインターネット上のコンテンツの名前解決にもインバウンドエンドポイントを利用する場合(つまり、フルリゾルバとして利用したい場合)は、エンドポイントカテゴリを
やってみた
事前準備
以下の構成で検証します。
BINDに登録しているゾーンファイルは以下のとおりです。
$TTL 300
@ IN SOA ns1.parent.example.com. admin.parent.example.com. (
2024010101 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
300 ) ; Minimum TTL
; Name servers for parent zone
@ IN NS ns1.parent.example.com.
ns1 IN A 10.0.1.10
; Delegation to child1 zone (VPC B)
child1 IN NS ns1.child1.parent.example.com.
child1 IN NS ns2.child1.parent.example.com.
; Glue records for child1 delegation (pointing to VPC B Resolver endpoints)
ns1.child1 IN A 10.1.1.100
ns2.child1 IN A 10.1.2.100
; Delegation to child2 zone (VPC C)
child2 IN NS ns1.child2.parent.example.com.
child2 IN NS ns2.child2.parent.example.com.
; Glue records for child2 delegation (pointing to VPC C Resolver endpoints)
ns1.child2 IN A 10.2.1.100
ns2.child2 IN A 10.2.2.100
BINDの設定ファイル(/etc/named.conf)については詳細を割愛しますが、転送設定(forwarders/forward)は適用していない状態です。
委任先のサーバとして応答できるかどうか
まず、VPC AのBINDがインストールされているEC2インスタンスで、委任したゾーン内の名前解決が可能か確認してみます。
エンドポイントカテゴリをDelegation
に設定しているインバウンドエンドポイントの場合、以下のとおり問題なく応答がありました。
# dig vpcb-ec2.child1.parent.example.com @localhost
; <<>> DiG 9.18.33 <<>> vpcb-ec2.child1.parent.example.com @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23078
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 6502a2fd3b3875c001000000686b9d2b8b5ff64b33015359 (good)
;; QUESTION SECTION:
;vpcb-ec2.child1.parent.example.com. IN A
;; ANSWER SECTION:
vpcb-ec2.child1.parent.example.com. 10 IN A 10.1.1.241
;; Query time: 1210 msec
;; SERVER: 127.0.0.1#53(localhost) (UDP)
;; WHEN: Mon Jul 07 10:10:51 UTC 2025
;; MSG SIZE rcvd: 107
エンドポイントカテゴリをDefault
に設定しているインバウンドエンドポイントの場合、以下のとおり回答を得ることができませんでした。
# dig vpcc-ec2.child2.parent.example.com @localhost
; <<>> DiG 9.18.33 <<>> vpcc-ec2.child2.parent.example.com @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 38169
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 1ae1b1a09e9fff6701000000686b9d4108389fa71a3b97ed (good)
;; QUESTION SECTION:
;vpcc-ec2.child2.parent.example.com. IN A
;; Query time: 1210 msec
;; SERVER: 127.0.0.1#53(localhost) (UDP)
;; WHEN: Mon Jul 07 10:11:13 UTC 2025
;; MSG SIZE rcvd: 91
digに対する応答として、status: SERVFAIL
となっている部分については以下のre:Postの記事に記載がある内容と一致します。(re:Postの回答は、本記事の執筆時点では2年前の更新となっていたので、エンドポイントカテゴリDelegation
は存在していないタイミングの情報です)
プライベートホストゾーンはゾーン委任をサポートしていません。委任が設定されている場合、クライアントは VPC リゾルバーから「Servfail」レスポンスコードを取得します。
BINDのログとしては以下のようなエラーが出力されました。
DNS format error from 10.2.1.100#53 resolving vpcc-ec2.child2.parent.example.com/A for 127.0.0.1#57629: server sent FORMERR
received FORMERR resolving 'vpcc-ec2.child2.parent.example.com/A/IN': 10.2.1.100#53
DNS format error from 10.2.1.100#53 resolving ns2.child2.parent.example.com/AAAA for <unknown>: server sent FORMERR
received FORMERR resolving 'ns2.child2.parent.example.com/AAAA/IN': 10.2.1.100#53
権威サーバとして応答しているかどうか
DNSにおける権威(オーソリティ)は以下のように定義されています。
DNSにおいて、あるゾーンの管理権限を持っていることを表す言葉です。ルートゾーンを階層の頂点とし、親ゾーンから委任された権威サーバー(権威DNSサーバー)は、そのゾーンの完全な情報と子ゾーンへの委任情報を持ち、そのゾーンに対する「権威を持つ」と表現されます。
このため、それぞれのカテゴリのエンドポイントが権威サーバとしてDNS問い合わせに応答しているかどうかを確認してみます。
エンドポイントカテゴリをDelegation
に設定しているインバウンドエンドポイントでは、以下のように応答があります。
$ dig vpcb-ec2.child1.parent.example.com @10.1.1.100 | grep flags
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
; EDNS: version: 0, flags:; udp: 1232
エンドポイントカテゴリをDefault
に設定しているインバウンドエンドポイントでは、以下のように応答があります。
$ dig vpcc-ec2.child2.parent.example.com @10.2.1.100 | grep flags
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
; EDNS: version: 0, flags:; udp: 1232
簡略のためにgrepで出力を制限していますが、着目する部分としてはエンドポイントカテゴリをDelegation
に設定しているインバウンドエンドポイントではフラグに「aa ビット」が付与されていることです。
「aa ビット」が存在する場合、応答したネームサーバーは問い合わされたドメイン名に対する管理権限を持っていることを示します。つまり、エンドポイントカテゴリをDelegation
に設定しているインバウンドエンドポイントは権威サーバとして応答しています。
一方で、エンドポイントカテゴリをDefault
に設定しているインバウンドエンドポイントは、紐付いているプライベートホストゾーンに対象レコードが存在するものの、非権威サーバ(キャッシュサーバ/フルリゾルバ)として応答しています。
DNSに関わる詳細については以下の資料もご参照ください。
なお、委任先のサーバとして応答できるかどうかで確認したエラーメッセージに関しては、権威サーバからの応答ではないからFORMERR になっている、というわけではなく、純粋にエンドポイントカテゴリDefault
ではゾーン委任をサポートしていない、という形で捉えていただければと思います。
AWSリソースの名前解決ができるかどうか(インターフェースエンドポイント無し)
インバウンドエンドポイントが紐付いているVPCと同じVPCに配置されているEC2インスタンスのDNS名を対象にクエリしてみます。
エンドポイントカテゴリをDefault
に設定しているインバウンドエンドポイントでは、以下のように問題なく名前解決できました。
# dig ip-10-2-1-166.ap-northeast-1.compute.internal @10.2.1.100
; <<>> DiG 9.18.33 <<>> ip-10-2-1-166.ap-northeast-1.compute.internal @10.2.1.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26064
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;ip-10-2-1-166.ap-northeast-1.compute.internal. IN A
;; ANSWER SECTION:
ip-10-2-1-166.ap-northeast-1.compute.internal. 60 IN A 10.2.1.166
;; Query time: 0 msec
;; SERVER: 10.2.1.100#53(10.2.1.100) (UDP)
;; WHEN: Mon Jul 07 10:14:01 UTC 2025
;; MSG SIZE rcvd: 90
エンドポイントカテゴリをDelegation
に設定しているインバウンドエンドポイントでは、以下のとおり名前解決できませんでした。
# dig ip-10-1-1-241.ap-northeast-1.compute.internal @10.1.1.100
; <<>> DiG 9.18.33 <<>> ip-10-1-1-241.ap-northeast-1.compute.internal @10.1.1.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 4864
;; flags: qr aa rd ad; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 5d14f645f2e800b4 (echoed)
;; Query time: 0 msec
;; SERVER: 10.1.1.100#53(10.1.1.100) (UDP)
;; WHEN: Mon Jul 07 10:14:54 UTC 2025
;; MSG SIZE rcvd: 35
まず、status: REFUSED
となっているので、クエリを処理することが拒否されたことが分かります。また、WARNINGの内容からも再帰問い合わせが利用できないという応答があったことが分かります。
digコマンドはデフォルトの動作が再帰問い合わせなので、非再帰問い合わせで再実行した結果は以下のとおりです。
# dig ip-10-0-1-10.ap-northeast-1.compute.internal @10.1.1.100 +norecurse
; <<>> DiG 9.18.33 <<>> ip-10-0-1-10.ap-northeast-1.compute.internal @10.1.1.100 +norecurse
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 51223
;; flags: qr aa ad; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 49bccaf6b4a9448b (echoed)
;; Query time: 0 msec
;; SERVER: 10.1.1.100#53(10.1.1.100) (UDP)
;; WHEN: Fri Jul 04 10:15:15 UTC 2025
;; MSG SIZE rcvd: 35
WARNINGの出力は無くなりましたがstatus: REFUSED
であることに変わりはなく、名前解決できませんでした。
AWSリソースの名前解決ができるかどうか(インターフェースエンドポイント有り)
そもそもインターフェースエンドポイントの有無で比較している背景・前提知識については、以下の記事をご参照ください。
今回はVPC BにS3 インターフェースエンドポイントを設定しています。改めて各VPCに関連付けられているプライベートホストゾーンを確認してみます。
VPC Aについては、プライベートホストゾーンを作成していないので空で表示されます。
$ aws route53 list-hosted-zones-by-vpc \
--vpc-id vpc-00b66602df70fe27e \
--vpc-region ap-northeast-1
{
"HostedZoneSummaries": [],
"MaxItems": "100"
}
VPC BについてはS3 インターフェースエンドポイントを作成しているため、マネジメントコンソールから確認可能なプライベートホストゾーンだけではなく、"OwningService": "vpce.amazonaws.com"
のプライベートホストゾーンが関連付いていることが分かります。
$ aws route53 list-hosted-zones-by-vpc \
--vpc-id vpc-0c0a8c0ac2f2d4d6f \
--vpc-region ap-northeast-1
{
"HostedZoneSummaries": [
{
"HostedZoneId": "Z03731293TSIHRLZJX8H7",
"Name": "s3-accesspoint.ap-northeast-1.amazonaws.com.",
"Owner": {
"OwningService": "vpce.amazonaws.com"
}
},
{
"HostedZoneId": "Z00288553KLFHH836TQUZ",
"Name": "s3-control.ap-northeast-1.amazonaws.com.",
"Owner": {
"OwningService": "vpce.amazonaws.com"
}
},
{
"HostedZoneId": "Z002889913E1ENCK5B64O",
"Name": "s3.ap-northeast-1.amazonaws.com.",
"Owner": {
"OwningService": "vpce.amazonaws.com"
}
},
{
"HostedZoneId": "Z00197611OGKEY18PV611",
"Name": "child1.parent.example.com.",
"Owner": {
"OwningAccount": "123456789012"
}
}
],
"MaxItems": "100"
}
VPC CについてはS3 インターフェースエンドポイントを作成していないため、マネジメントコンソールから確認可能なプライベートホストゾーンだけが関連付いていることが分かります。
$ aws route53 list-hosted-zones-by-vpc \
--vpc-id vpc-098ffd9ea2e042b96 \
--vpc-region ap-northeast-1
{
"HostedZoneSummaries": [
{
"HostedZoneId": "Z03640631YHN610V85PT1",
"Name": "child2.parent.example.com.",
"Owner": {
"OwningAccount": "123456789012"
}
}
],
"MaxItems": "100"
}
つまり、インターフェースエンドポイントを作成してプライベートDNS 名を有効にしている環境であれば、対象のAWSリソースについてはプライベートホストゾーンで名前解決可能であるため、インバウンドエンドポイントのカテゴリがDelegation
であっても応答できるかどうかを確認するという意図です。
まず、エンドポイントカテゴリをDefault
に設定しているインバウンドエンドポイントに対してS3バケットの名前解決を試してみます。
# dig (バケット名).s3.ap-northeast-1.amazonaws.com @10.2.1.100
; <<>> DiG 9.18.33 <<>> (バケット名).s3.ap-northeast-1.amazonaws.com @10.2.1.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47041
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;(バケット名).s3.ap-northeast-1.amazonaws.com. IN A
;; ANSWER SECTION:
(バケット名).s3.ap-northeast-1.amazonaws.com. 261 IN CNAME s3-r-w.ap-northeast-1.amazonaws.com.
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 3.5.154.44
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 52.219.172.54
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 52.219.199.186
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 3.5.158.160
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 3.5.157.122
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 52.219.199.18
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 3.5.156.229
s3-r-w.ap-northeast-1.amazonaws.com. 5 IN A 3.5.156.56
;; Query time: 0 msec
;; SERVER: 10.2.1.100#53(10.2.1.100) (UDP)
;; WHEN: Mon Jul 07 09:46:13 UTC 2025
;; MSG SIZE rcvd: 227
再帰問い合わせによってS3バケットのグローバルIPアドレスが返ってきています。今回は割愛しますが、エンドポイントカテゴリをDefault
に設定しているインバウンドエンドポイントが紐付いているVPCでS3 インターフェースエンドポイントを作成してプライベートDNS 名を有効にすれば、インターフェースエンドポイントのプライベートIPアドレスが返ってくるようになります。
続いて、エンドポイントカテゴリをDelegation
に設定しているインバウンドエンドポイントでも同様に確認してみます。
# dig (バケット名).s3.ap-northeast-1.amazonaws.com @10.1.1.100
; <<>> DiG 9.18.33 <<>> (バケット名).s3.ap-northeast-1.amazonaws.com @10.1.1.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54592
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;(バケット名).s3.ap-northeast-1.amazonaws.com. IN A
;; ANSWER SECTION:
(バケット名).s3.ap-northeast-1.amazonaws.com. 60 IN A 10.1.1.69
;; Query time: 0 msec
;; SERVER: 10.1.1.100#53(10.1.1.100) (UDP)
;; WHEN: Mon Jul 07 09:47:14 UTC 2025
;; MSG SIZE rcvd: 94
インターフェースエンドポイントのプライベートIPアドレスの応答があり、名前解決可能でした。WARNINGが出力されていますが、以下のとおり明示的に非再帰問い合わせでクエリすれば表示されません。
# dig (バケット名).s3.ap-northeast-1.amazonaws.com @10.1.1.100 +norecurse
; <<>> DiG 9.18.33 <<>> (バケット名).s3.ap-northeast-1.amazonaws.com @10.1.1.100 +norecurse
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11069
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;(バケット名).s3.ap-northeast-1.amazonaws.com. IN A
;; ANSWER SECTION:
(バケット名).s3.ap-northeast-1.amazonaws.com. 60 IN A 10.1.1.69
;; Query time: 10 msec
;; SERVER: 10.1.1.100#53(10.1.1.100) (UDP)
;; WHEN: Mon Jul 07 10:03:14 UTC 2025
;; MSG SIZE rcvd: 94
まとめ
Route 53 Resolver インバウンドエンドポイントの用途としては、オンプレミスのネットワークからプライベートホストゾーンに登録されているドメインの名前解決をしたいケースだけではなく、プライベートホストゾーンに登録されていないAWSリソースの名前解決や、インターネット上のコンテンツ(パブリックドメイン)を含む名前解決に活用されているケースもあるかと思います。
インバウンドエンドポイントを採用する場合は、ゾーン委任が必要なケースとそうではないケースのそれぞれで、今回追加されたDelegation
カテゴリと従来のDefault
カテゴリを使い分けるように、設計時には気をつけたいと思いました。
本記事がどなたかのお役に立てれば幸いです。