Route 53 Resolver Inbound EndpointからRoute 53 Global Resolverへ置き換えられるシチェーションを考えてみた

Route 53 Resolver Inbound EndpointからRoute 53 Global Resolverへ置き換えられるシチェーションを考えてみた

Endpoint CategoryがデフォルトのRoute 53 Resolver Inbound Endpointを使っており、DNSクエリがインターネットを平文で流れることを許容できる もしくは手間無く DoH/DoT でフォワーディングできるのであれば置き替えられそう
2025.12.12

Route 53 Resolver Inbound Endpointから置き換えたい

こんにちは、のんピ(@non____97)です。

皆さんはRoute 53 Resolver Inbound Endpointを廃止したいなと思ったことはありますか? 私はあります。

Route 53 Resolver Inbound Endpointはオンプレミスもしくは、別VPCからRoute 53 Private Hosted Zoneで管理されているゾーンの名前解決をする際に使用します。

利用ケースとしては特に多いのはオンプレミスからRoute 53 Private Hosted Zoneのカスタムドメインの名前解決でしょう。

もう少し具体的に言うと以下のような形です。

  • クライアントはオンプレミス上のサーバーやPC
  • 接続先はInternal ALB
  • Internal ALBとはHTTPS通信をしたい
  • Internal ALBにはカスタムドメインを割り当てたい
    • DNSゾーンはプライベートで管理したい

図にすると以下のとおりです。

ALB.png

オンプレミスサーバーにコンテンツDNSサーバーがあり、同一ゾーンで管理したいのであれば、Internal ALBのDNS名を値にしたCNAMEレコードを作成するのもあるでしょう。ただし、Zone Apexを使用したい場合やDNSゾーンの管理をシステムの管理者単位で分離したい場合があります。そんな時にはRoute 53 Private Hosted Zoneを使うことになるでしょう。ざっくり「マネージドの機能で良い感じにDNSゾーンを管理したい」という場合でも良いですね。

ただし、上述のようにクライアントとサーバーが別ネットワークに存在している場合はRoute 53 Resolver Inbound Endpointを使うことになります。

他にも、EC2インスタンスがドメイン参加している関係でオンプレミスのAD DCをDNSサーバーとしているが、ログを大量に出力するのでCloudWatch LogsのVPCエンドポイント経由でログ出力させたいという時もRoute 53 Resolver Endpointを使うでしょう。

図にすると以下のとおりです。

ドメイン参加パターン.png

まだプレビューですが、先日Route 53 Global Resolverが登場しました。

https://dev.classmethod.jp/articles/amazon-route-53-global-resolver-secure-anycast-dns-resolution-preview/

これがRoute 53 Global Resolverが登場したことによりどのように変わるでしょうか。

Route 53 Resolver Inbound EndpointとRoute 53 Global Resolverの料金は以下のとおりです。

項目 Route 53 Resolver Inbound Endpoint Route 53 Global Resolver
存在していることに対する課金 ENI ごとに 0.125 USD/h

= 2つ × 0.125 USD/h × 730 h × 150ドル円
= 27,375円
※ Route 53 Resolver Endpoint一つにつき最低2つENIを作成することになるため
- 最初の2つ : 1リージョンあたり 5.00 USD/h (DNSフィルタリングを使用しない場合は 4.50 USD/h)
- 追加リージョン : 1リージョンあたり 1.50 USD/h (DNSフィルタリングを使用しない場合は 0.75 USD/h)

= 5.00 USD × 150円
= 750円
クエリに対する課金 - 最初の 10 億件のクエリ/月 : 0.60 USD/100万クエリ
- 10億クエリを超過した分 : 0.40 USD/100万クエリ
10億クエリを超過した分 : 1.50 USD/100万クエリ

ということでクエリ量がそこまで多くなければRoute 53 Global Resolverの方が安そうです。

では、Route 53 Global Resolverを使うことによってRoute 53 Resolver Inbound Endpointを廃止できるシチェーションはどのような時でしょうか。

考えてみました。

いきなりまとめ

  • Endpoint CategoryがデフォルトのRoute 53 Resolver Inbound Endpointを使っており、DNSクエリがインターネットを平文で流れることを許容できる もしくは手間無く DoH/DoT でフォワーディングできるのであれば置き替えられそう
    • ただし、現在使っているDNSサーバーとは別にDoTやDoHでフォワーディングするDNSサーバーを構築する場合は、コスト削減観点で言うと本末転倒
      • Windows Serverにおいては、標準機能でDoTやDoHでフォワーディングするのは非対応
  • 以下場合はRoute 53 Resolver Inbound Endpointを使おう
    • DNSクエリをVPNやDirect Connectを通したい場合
    • DNSクエリのレイテンシーが気になる場合
      • 要計測
    • Route 53 Private Hosted Zoneへ委任をしたい場合
    • 特定のVPCに紐付くAWSマネージドなPrivate Hosted Zoneのドメインの名前解決をしたい場合
  • Route 53 Global Resolverは条件付きフォワーダーのフォワーディング先として設定しよう
    • 全てのDNSクエリのフォワーディング先とすると、Route 53 Global ResolverおよびRoute 53 Global Resolverまでの経路で障害が発生した場合の影響が大きくなるため
      • 元々フォワーダー設定をしておらず、ルートヒントを使っている場合は特に気にしなくとも良い
    • DNSクエリのコストはRoute 53 Global ResolverよりもRoute 53 Resolver Inbound Endpointの方が安価なため

やってみる

検証環境

各クライアントがRoute 53 Resolver Inbound Endpointをフルサービスリゾルバーとして使用するケースはレアではないでしょうか。

基本的にはクライアントは別のDNSサーバーを参照しており、そのDNSサーバーから条件付きフォワーダーを用いてフォワーディングしていることが多いと思います。

ということで、以下のような検証環境を用意しました。

検証環境.png

こちらのケースで問題なくRoute 53 Private Hosted Zoneの名前解決ができればRoute 53 Resolver Inbound Endpointは不要そうです。

セルフマネージドDNSサーバーのDNSフォワーディング設定以外は完了している状態です。

DNSサーバーのフォワーディング先として指定して名前解決

まず、DNSサーバーのフォワーディング先として指定して名前解決をする場合です。

現在のフォワーディング設定には10.0.0.2とRoute 53 VPC Resolverが設定されています。

1.現在のフォワーダー設定.png

この状態で名前解決をします。

# DNSサーバーを指定しない場合
> nslookup www.non-97.net
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.82
          108.138.85.44
          108.138.85.24
          108.138.85.20

# 明示的にRoute 53 VPC Resolverを指定した場合
> nslookup www.non-97.net 169.254.169.253
Server:  UnKnown
Address:  169.254.169.253

Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.44
          108.138.85.20
          108.138.85.24
          108.138.85.82

# Route 53 Global Resolverを指定した場合
> nslookup www.non-97.net 52.223.8.240
Server:  a7b429450611ddf68.awsglobalaccelerator.com
Address:  52.223.8.240

Non-authoritative answer:
Name:    www.non-97.net
Address:  10.20.30.40

# 自身が管理しているゾーンで存在しないドメインの名前解決をしようとした場合
> nslookup host.phz.test.corp.non-97.net
Server:  localhost
Address:  ::1

*** localhost can't find host.phz.test.corp.non-97.net: Server failed

# 自Route 53 Global Resolverを指定して、自身が管理しているゾーンで存在しないドメインの名前解決をしようとした場合
> nslookup host.phz.test.corp.non-97.net 52.223.8.240
Server:  a7b429450611ddf68.awsglobalaccelerator.com
Address:  52.223.8.240

Non-authoritative answer:
Name:    host.phz.test.corp.non-97.net
Address:  10.10.10.10

host.phz.test.corp.non-97.net以外は名前解決できました。これはAD統合ゾーンがcorp.non-97.netであり、自身が管理しているゾーンおよび委任先のゾーンで名前解決しようとしているためです。言うなればRoute 53 VPC Resolver並びにRoute 53 Global Resolverの設定は関係ありません。

また、Route 53 ResolverではパブリックIPアドレスが返ってきたところ、Route 53 Global Resolverを指定した場合はプライベートIPアドレスが返ってきました。

大量にあるDNSクライアントが参照するDNSサーバーをRoute 53 Global Resolverとするのは以下観点から非現実的です。

  • 参照先DNSサーバーのIPアドレスの変更
  • Route 53 Global Resolverのアクセスソースの管理

ということで、セルフマネージドのDNSサーバーのフォワーディング先としてRoute 53 Global Resolverを指定します。

2.Global Resolverのフォワーディング先に設定.png

また、Route 53 Global ResolverのDNSビューのアクセスソースに、セルフマネージドDNSサーバーに割り当てられているElastic IPアドレスからのDo53を許可します。

7.ADDC_Do53.png

この状態で名前解決をします。

> nslookup www.non-97.net
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.82
          108.138.85.24
          108.138.85.44
          108.138.85.20

> nslookup host.phz.test.corp.non-97.net
Server:  localhost
Address:  ::1

*** localhost can't find host.phz.test.corp.non-97.net: Server failed

はい、何も変わりませんね。

これはフォワーディング先の優先順位としてRoute 53 VPC Resolverが最も高くなっているためです。

フォワーディング先の順番を変更し、Route 53 VPC Resolverの優先度が最も低くなるようにします。

3.DNSフォワーディング先の順番を入れ替え.png

この状態で名前解決をします。

> nslookup www.non-97.net
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Address:  10.20.30.40

> nslookup host.phz.test.corp.non-97.net
Server:  localhost
Address:  ::1

*** localhost can't find host.phz.test.corp.non-97.net: Server failed

明示的なRoute 53 Global Resolverを指定していないにも関わらず、www.non-97.netの名前解決をするとプライベートIPアドレスが返ってきました。つまりはRoute 53 Resolver Inbound EndpointなしにRoute 53 Private Hosted Zoneで管理さているドメインの名前解決をできました。やったね。

なお、host.phz.test.corp.non-97.netの名前解決が失敗しているのは先ほどと同じ理由なので問題ありません。意図したとおりです。

インターネット上に公開されているゾーンの名前解決ができるかも確認します。

> nslookup dev.classmethod.jp
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    dev.classmethod.jp
Addresses:  2600:9000:27ce:f600:14:e623:c740:93a1
          2600:9000:27ce:5800:14:e623:c740:93a1
          2600:9000:27ce:4600:14:e623:c740:93a1
          2600:9000:27ce:b600:14:e623:c740:93a1
          2600:9000:27ce:5a00:14:e623:c740:93a1
          2600:9000:27ce:6600:14:e623:c740:93a1
          2600:9000:27ce:a00:14:e623:c740:93a1
          2600:9000:27ce:7000:14:e623:c740:93a1
          3.167.99.98
          3.167.99.14
          3.167.99.118
          3.167.99.120

問題なくできました。バッチリです。

Route 53 Global Resolverのアクセスソースでのフォワーダーの許可を外して名前解決

次に気になるのはRoute 53 Global ResolverおよびRoute 53 Global Resolverまでの経路がダウンした場合の挙動です。

Route 53 Global ResolverのアクセスソースでセルフマネージドDNSサーバーのElastic IPアドレスの許可を外してみます。

この状態で名前解決します。

> nslookup www.non-97.net
Server:  localhost
Address:  ::1

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Request to localhost timed-out

> nslookup www.non-97.net.
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.20
          108.138.85.24
          108.138.85.44
          108.138.85.82

> nslookup dev.classmethod.jp
Server:  localhost
Address:  ::1

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Request to localhost timed-out

> nslookup dev.classmethod.jp.
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    dev.classmethod.jp
Addresses:  2600:9000:27ce:8c00:14:e623:c740:93a1
          2600:9000:27ce:4000:14:e623:c740:93a1
.
.
(中略)
.
.
          2600:9000:27ce:a400:14:e623:c740:93a1
          3.167.99.98
          3.167.99.14
          3.167.99.118
          3.167.99.120

はい、名前解決できません。フォワーディング先としてRoute 53 VPC Resolverも指定しているため、インターネット上に公開されているゾーンの名前解決はできることを期待していました。

末尾に.を付与した場合に名前解決できているのはルートヒントに問い合わせをしているためなのでしょうか?

現在のDNSフォワーダーの設定を確認します。

> Get-DnsServerForwarder


UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : True
IPAddress          : {52.223.8.240, 166.117.206.85, 10.0.0.2}
ReorderedIPAddress : {10.0.0.2, 52.223.8.240, 166.117.206.85}

ReorderedIPAddressで先頭がRoute 53 VPC Resolverである10.0.0.2となっていますね。

もしかすると、次に名前解決する時は正常に応答があるかもしれません。試しにトライします。

> nslookup www.non-97.net
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.82
          108.138.85.20
          108.138.85.24
          108.138.85.44

> nslookup dev.classmethod.jp
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    dev.classmethod.jp
Addresses:  2600:9000:27ce:2200:14:e623:c740:93a1
          2600:9000:27ce:e00:14:e623:c740:93a1
.
.
(中略)
.
.
          2600:9000:27ce:fa00:14:e623:c740:93a1
          3.167.99.120
          3.167.99.118
          3.167.99.14
          3.167.99.98

名前解決できました。

DNSフォワーダー設定としてEnableReorderingが有効になっています。これにより、DNSフォワーダーの順序が動的に並び替えられています。

Setting IP addresses by using this cmdlet causes the DNS server to perform recursive queries to the DNS servers at the specified IP addresses. By default, the DNS server waits five seconds for a response from one forwarder IP address before it tries another forwarder IP address. You can use the Timeout parameter to change the number of seconds that the DNS server waits. When the server has exhausted all forwarders, it attempts standard recursion. By default, a DNS server performs iterative queries when it cannot resolve a query.

..(中略)..

-EnableReordering

Specifies whether to enable the DNS server to reorder forwarders dynamically.

Set-DnsServerForwarder (DnsServer) | Microsoft Learn

要するに繰り返しフォワーディングできないフォワーディング先の優先度は下がるような仕組みになっています。

試しにこちらを無効化して名前解決しましょう。

> Set-DnsServerForwarder -EnableReordering $false
> Get-DnsServerForwarder


UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : False
IPAddress          : {52.223.8.240, 166.117.206.85, 10.0.0.2}
ReorderedIPAddress : {52.223.8.240, 166.117.206.85, 10.0.0.2}

> nslookup -timeout=1 -retry=20 www.non-97.net
Server:  localhost
Address:  ::1

DNS request timed out.
    timeout was 1 seconds.
.
.
(25回タイムアウト)
.
.
DNS request timed out.
    timeout was 1 seconds.
Non-authoritative answer:
DNS request timed out.
    timeout was 1 seconds.
.
.
(9回タイムアウト)
.
.
DNS request timed out.
    timeout was 1 seconds.
Name:    www.non-97.net
Addresses:  108.138.85.24
          108.138.85.20
          108.138.85.44
          108.138.85.82

> Get-DnsServerForwarder


UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : False
IPAddress          : {52.223.8.240, 166.117.206.85, 10.0.0.2}
ReorderedIPAddress : {10.0.0.2, 52.223.8.240, 166.117.206.85}

正常に名前解決できるまで非常に時間がかかりました。ReorderedIPAddress自体は並び替えられていますね。

では、再度同じクエリを叩いてみます。並び替え順序に基づいてフォワーディングするのであれば同じように長時間はかからない想定です。

> nslookup -timeout=1 -retry=20 www.non-97.net
Server:  localhost
Address:  ::1

DNS request timed out.
    timeout was 1 seconds.
.
.
(37回タイムアウト)
.
.
DNS request timed out.
    timeout was 1 seconds.
*** localhost can't find www.non-97.net: Server failed

> Get-DnsServerForwarder


UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : False
IPAddress          : {52.223.8.240, 166.117.206.85, 10.0.0.2}
ReorderedIPAddress : {10.0.0.2, 166.117.206.85, 52.223.8.240}

はい、今度は正常に名前解決できませんでした。

再度EnableReorderingを有効にして名前解決しましょう。

> Set-DnsServerForwarder -EnableReordering $true
> Get-DnsServerForwarder


UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : True
IPAddress          : {52.223.8.240, 166.117.206.85, 10.0.0.2}
ReorderedIPAddress : {52.223.8.240, 166.117.206.85, 10.0.0.2}


> nslookup -timeout=2 -retry=30 www.non-97.net
Server:  localhost
Address:  ::1

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.24
          108.138.85.20
          108.138.85.44
          108.138.85.82

> Get-DnsServerForwarder


UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : True
IPAddress          : {52.223.8.240, 166.117.206.85, 10.0.0.2}
ReorderedIPAddress : {10.0.0.2, 52.223.8.240, 166.117.206.85}



> nslookup -timeout=2 -retry=30 www.non-97.net
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Addresses:  108.138.85.20
          108.138.85.44
          108.138.85.82
          108.138.85.24

今度は2回目のクエリ実行時はタイムアウトなしに名前解決できました。

DNSフォワーダーとしてRoute 53 Global Resolverを設定するのであれば、Route 53 Global Resolverもしくは経路がダウンした場合に備えてEnableReorderingを有効にするのが良さそうです。

ただし、Route 53 Global Resolverおよび、その経路が復旧して正常にフォワーディングできる状態になっても、一度変わった順序は自動では元に戻らないです。復旧確認後は手動で並び替えましょう。

そもそも個人的に、Route 53 Global Resolverへフォワーディングできなかった場合の影響および、クエリにかかる料金的が気になります。Route 53 Global Resolverはフォワーダーではなく、条件付きフォワーダーのフォワーディング先に設定するのが良いでしょう。条件付きフォワーダーなのであれば影響は特定ドメインの名前解決する時のみなので、影響度合いを抑えることができます。

DNSフォワーダーからRoute 53 Global Resolverへフォワーディングする際にDNS over TLSをする

DNSフォワーダーからのフォワーディング先としてRoute 53 Global Resolverは非常に有用そうなのが分かりました。

一方でRoute 53 Resolver Inbound Endpointと異なり、Route 53 Global Resolverを使用するDNSクエリはインターネットを通ることになります。

内部DNSゾーンの名前解決が平文でインターネットを流れることで、名前解決結果からシステム名や使用しているネットワーク体系を知るヒントになり得ることもあります。

Route 53 Public Hosted Zoneで値がプライベートIPアドレスのレコード管理をされているような場合は許容できるとは思いますが、セキュリティポリシー上許容できないこともあるでしょう。

このような場合はDNSフォワーダーからRoute 53 Global Resolverフォワーディングする際にDNS over TLS(以降DoT)やDNS over HTTPS(以降DoH)を使用することになります。

こうすることでDNSクエリをインターネット上で暗号化することが可能です。図示すると以下になります。

DoTによる暗号化.png

実際に試してみましょう。

アクセスソースでセルフマネージドDNSサーバーのプロトコルをDoTに変更します。

6.ADDC_DoT.png

名前解決をします。

> Get-DnsServerForwarder

UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : True
IPAddress          : {52.223.8.240, 166.117.206.85}
ReorderedIPAddress : {52.223.8.240, 166.117.206.85}

> nslookup  www.non-97.net
Server:  localhost
Address:  ::1

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Request to localhost timed-out

はい、失敗しました。

私の方で調べたところWindows ServerはDoHやDoTでDNSクエリを投げれても、DoHやDoTでフォワーディングすることはできないようです。

ということで別でDoHやDoTをお喋りできるフォワーダーを用意する必要があります。

今回はunboundで実装します。図にすると以下のとおりです。

DoTフォワーダーの追加.png

セルフマネージドDNSサーバーと同じサブネットにEC2インスタンスを用意し、インストールします。

$ sudo dnf install unbound
Last metadata expiration check: 0:02:30 ago on Thu Dec 11 08:02:37 2025.
Dependencies resolved.
=================================================================================================================
 Package                    Architecture       Version                             Repository               Size
=================================================================================================================
Installing:
 unbound                    x86_64             1.17.1-1.amzn2023.0.10              amazonlinux             949 k
Installing dependencies:
 unbound-anchor             x86_64             1.17.1-1.amzn2023.0.10              amazonlinux              37 k
 unbound-libs               x86_64             1.17.1-1.amzn2023.0.10              amazonlinux             533 k
Installing weak dependencies:
 unbound-utils              x86_64             1.17.1-1.amzn2023.0.10              amazonlinux              61 k

Transaction Summary
=================================================================================================================
Install  4 Packages

Total download size: 1.5 M
Installed size: 4.8 M
Is this ok [y/N]: y
Downloading Packages:
.
.
(中略)
.
.
Installed:
  unbound-1.17.1-1.amzn2023.0.10.x86_64                  unbound-anchor-1.17.1-1.amzn2023.0.10.x86_64
  unbound-libs-1.17.1-1.amzn2023.0.10.x86_64             unbound-utils-1.17.1-1.amzn2023.0.10.x86_64

Complete!

DoTを使ってRoute 53 Global Resolverへフォワーディングを行う設定をし、unboundを起動します。

$ sudo vi /etc/unbound/unbound.conf
$ unbound-checkconf
unbound-checkconf: no errors in /etc/unbound/unbound.conf

$ sudo systemctl restart unbound
$ systemctl status unbound
● unbound.service - Unbound recursive Domain Name Server
     Loaded: loaded (/usr/lib/systemd/system/unbound.service; disabled; preset: disabled)
     Active: active (running) since Thu 2025-12-11 09:23:24 UTC; 5s ago
    Process: 16174 ExecStartPre=/usr/sbin/unbound-checkconf (code=exited, status=0/SUCCESS)
   Main PID: 16176 (unbound)
      Tasks: 1 (limit: 1057)
     Memory: 8.0M
        CPU: 66ms
     CGroup: /system.slice/unbound.service
             └─16176 /usr/sbin/unbound -d

設定は以下のとおりです。

/etc/unbound/unbound.conf
server:
    # ログレベル
    verbosity: 4

    # 0.0.0.0/0 で待受
    interface: 0.0.0.0

    # ポート 53 で LISTEN
    port: 53

    # IPv4を有効化
    do-ip4: yes

    # UDPプロトコルを有効化
    do-udp: yes

    # TCPプロトコルを有効化)
    do-tcp: yes

    # デフォルトで全て拒否
    access-control: 0.0.0.0/0 refuse

    # ループバックアドレスから許可
    access-control: 127.0.0.0/8 allow
    
    # DNSクライアントが存在する 10.0.0.0/20 から許可
    access-control: 10.0.0.0/20 allow

    # サーバー情報の隠蔽
    hide-identity: yes

    # バージョン情報の隠蔽
    hide-version: yes
    
    # グルーレコードの整合性チェックを強化
    harden-glue: yes
    
    # DNSSEC検証済みデータからDNSSECレコードが除去された応答を拒否
    harden-dnssec-stripped: yes

    # TLS証明書の検証
    tls-cert-bundle: "/etc/ssl/certs/ca-bundle.crt"
    tls-system-cert: yes

forward-zone:
    # すべてのドメイン (.) の名前解決をフォワーディング
    name: "."

    # DoTでフォワーディング
    forward-tls-upstream: yes
    
    # フォワーディング先としてRoute 53 Global Resolverを指定
    forward-addr: 52.223.8.240@853#2788e8200b414d28.route53globalresolver.global.on.aws
    forward-addr: 166.117.206.85@853#2788e8200b414d28.route53globalresolver.global.on.aws

#2788e8200b414d28.route53globalresolver.global.on.awsというのはRoute 53 Global Resolverのドメイン名です。<リゾルバーIDの先頭から"gr-"を除いたもの>.route53globalresolver.global.on.awsという形式です。

unbound.confの内容は以下unboundのマニュアルが参考になります。

https://nlnetlabs.nl/documentation/unbound/unbound.conf/

また、unboundのDNSフォワーダーからRoute 53 Global Resolverへフォワーディングできるように、アクセスソースでunbound EC2インスタンスに割り当てられているElastic IPアドレスからのDoTを許可します。

4.dot-forwarder.png

この状態でunboundをインストールしたEC2インスタンス上で名前解決をします。

$ dig www.non-97.net @localhost

; <<>> DiG 9.18.33 <<>> www.non-97.net @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9370
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.non-97.net.                        IN      A

;; ANSWER SECTION:
www.non-97.net.         300     IN      A       10.20.30.40

;; Query time: 60 msec
;; SERVER: 127.0.0.1#53(localhost) (UDP)
;; WHEN: Thu Dec 11 09:27:08 UTC 2025
;; MSG SIZE  rcvd: 59

正常に名前解決できました。プライベートIPアドレスが返っているところを見るとRoute 53 Global Resolverへのフォワーディングができていることが分かります。

この時のunboundのログは以下のとおりです。

$ sudo journalctl -u unbound -f
.
.
(中略)
.
.
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: start
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_new
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: subnetcache operate: query www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: subnetcache: not found in cache. pass to next module
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: subnetcache module exit state is module_wait_module
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_pass
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: validator operate: query www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: validator: pass to next module
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: validator module exit state is module_wait_module
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: process_request: new external request event
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: iter_handle processing q with state INIT REQUEST STATE
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: resolving www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: request has dependency depth of 0
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: forwarding request
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: iter_handle processing q with state QUERY TARGETS STATE
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: processQueryTargets: www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: processQueryTargets: targetqueries 0, currentqueries 0 sentcount 0
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: DelegationPoint<.>: 0 names (0 missing), 2 addrs (0 result, 2 avail) parentNS
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug:   [2788e8200b414d28.route53globalresolver.global.on.aws] ip4 166.117.206.85 port 853 (len 16)
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug:   [2788e8200b414d28.route53globalresolver.global.on.aws] ip4 52.223.8.240 port 853 (len16)
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: attempt to get extra 3 targets
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: rpz: iterator module callback: have_rpz=0
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: selrtt 376
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: sending query: www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: sending to target: <.> 166.117.206.85#853
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: dnssec status: not expected
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: iterator module exit state is module_wait_reply
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: mesh_run: end 1 recursion states (1 with reply, 0 detached), 1 waiting replies, 0 recursion replies sent, 0 replies dropped, 0 states jostled out
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: 0RDd mod2 rep www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: cache memory msg=66072 rrset=66072 infra=8128 val=66352 subnet=74504
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: serviced send timer
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: the query is using TLS encryption, for 2788e8200b414d28.route53globalresolver.global.on.aws
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point start listening 11 (-1 msec)
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point listen_for_rw 11 0
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: peer certificate:
                                                            Issuer: C=US, O=Amazon, CN=Amazon RSA 2048 M01
                                                            Validity
                                                            Not Before: Dec 1 00:00:00 2025 GMT
                                                            Not After : Nov 2 23:59:59 2026 GMT
                                                            Subject: CN=route53globalresolver.us-east-1.on.aws
                                                            X509v3 extensions:
                                                            X509v3 Authority Key Identifier:
                                                            81:B8:0E:63:8A:89:12:18:E5:FA:3B:3B:50:95:9F:E6:E5:90:13:85
                                                            X509v3 Subject Key Identifier:
                                                            D0:4E:54:27:25:19:3D:3F:26:07:F1:42:0F:82:B2:BC:45:CF:45:B3
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: SSL connection to *.route53globalresolver.global.on.aws authenticated ip4 166.117.206.85 port 853 (len 16)
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point listen_for_rw 11 1
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point stop listening 11
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: outnettcp cb
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: outnet tcp pkt was written event
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: outnet tcp writes done, wait
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point stop listening 11
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point start listening 11 (60000 msec)
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: Reading ssl tcp query of length 73
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point stop listening 11
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: outnettcp cb
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: measured TCP-time at 55 msec
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: svcd callbacks start
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: worker svcd callback for qstate 0x55aef2bf6360
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: start
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: iterator operate: query www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: process_response: new external response event
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: scrub for . NS IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: response for www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: reply from <.> 166.117.206.85#853
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: incoming scrubbed packet: ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0
                                                           ;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
                                                           ;; QUESTION SECTION:
                                                           www.non-97.net.        IN        A

                                                           ;; ANSWER SECTION:
                                                           www.non-97.net.        300        IN        A        10.20.30.40

                                                           ;; AUTHORITY SECTION:

                                                           ;; ADDITIONAL SECTION:
                                                           ;; MSG SIZE  rcvd: 48
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: iter_handle processing q with state QUERY RESPONSE STATE
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: query response was ANSWER
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: iter_handle processing q with state FINISHED RESPONSE STATE
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: finishing processing for www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: iterator module exit state is module_finished
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: validator operate: query www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: validator: nextmodule returned
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: val handle processing q with state VAL_INIT_STATE
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: validator classification positive
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: no signer, using www.non-97.net. TYPE0 CLASS0
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: val handle processing q with state VAL_FINISHED_STATE
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: validator module exit state is module_finished
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: subnetcache operate: query www.non-97.net. A IN
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: reply has edns subnet (null)
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: mesh_run: subnetcache module exit state is module_finished
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: query took 0.055474 sec
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: mesh_run: end 0 recursion states (0 with reply, 0 detached), 0 waiting replies, 1 recursion replies sent, 0 replies dropped, 0 states jostled out
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: average recursion processing time 0.055474 sec
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: histogram of recursion processing times
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: [25%]=0 median[50%]=0 [75%]=0
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info: lower(secs) upper(secs) recursions
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] info:    0.032768    0.065536 1
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: cache memory msg=66328 rrset=66318 infra=8425 val=66352 subnet=74504
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: svcd callbacks end
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point stop listening 11
Dec 11 09:27:08 ip-10-0-0-123.ec2.internal unbound[16327]: [16327:0] debug: comm point start listening 11 (60000 msec)

Route 53 Global Resolverのドメイン名を検証した上でTLSセッションを張り、名前解決していることが分かります。

Windows ServerのセルフマネージドDNSサーバーにて、フォワーディング先に先ほど作成したunbound DNSサーバーを設定して名前解決します。

> Get-DnsServerForwarder

UseRootHint        : True
Timeout(s)         : 3
EnableReordering   : True
IPAddress          : 10.0.0.123
ReorderedIPAddress : 10.0.0.123

> nslookup www.non-97.net
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    www.non-97.net
Address:  10.20.30.40

> nslookup dev.classmethod.jp
Server:  localhost
Address:  ::1

Non-authoritative answer:
Name:    dev.classmethod.jp
Addresses:  2600:9000:27ce:4c00:14:e623:c740:93a1
          2600:9000:27ce:e400:14:e623:c740:93a1
.
.
(中略)
.
.
          2600:9000:27ce:0:14:e623:c740:93a1
          3.167.99.98
          3.167.99.118
          3.167.99.14
          3.167.99.120

正常に名前解決できました。

CloudWatch Logsに出力されたRoute 53 Global Resolverのクエリログも確認します。

www.non-97.net
{
    "action_id": 1,
    "action_name": "Allowed",
    "activity_id": 6,
    "activity_name": "Traffic",
    "answers": [],
    "category_name": "Network Activity",
    "category_uid": 4,
    "class_name": "DNS Activity",
    "class_uid": 4003,
    "cloud": {
        "provider": "AWS",
        "region": "us-east-1",
        "account": {
            "uid": "<AWSアカウントID>"
        }
    },
    "connection_info": {
        "direction": "Inbound",
        "direction_id": 1,
        "protocol_name": "tcp",
        "protocol_num": 6,
        "protocol_ver_id": 4,
        "uid": "1bc2667f624a42c8"
    },
    "duration": 1,
    "end_time": 0,
    "enrichments": [
        {
            "name": "global-resolver",
            "value": "gr-2788e8200b414d28",
            "data": {
                "dns_view_id": "dnsv-e4385db72ac849b4"
            }
        }
    ],
    "message": "",
    "metadata": {
        "version": "1.2.0",
        "product": {
            "name": "Global Resolver",
            "vendor_name": "AWS",
            "feature": {
                "name": "DNS"
            }
        }
    },
    "query": {
        "hostname": "www.non-97.net.ec2.internal.",
        "class": "IN",
        "type": "A",
        "opcode": "Query",
        "opcode_id": 0
    },
    "query_time": 1765445369504,
    "rcode": "NOERROR",
    "rcode_id": 0,
    "response_time": 1765445369505,
    "severity": "Informational",
    "severity_id": 1,
    "src_endpoint": {
        "ip": "3.89.60.161",
        "port": 59522
    },
    "start_time": 0,
    "status": "Success",
    "status_id": 1,
    "time": 1765445369505,
    "type_name": "DNS Activity: Traffic",
    "type_uid": 400306
}

{
    "action_id": 1,
    "action_name": "Allowed",
    "activity_id": 6,
    "activity_name": "Traffic",
    "answers": [],
    "category_name": "Network Activity",
    "category_uid": 4,
    "class_name": "DNS Activity",
    "class_uid": 4003,
    "cloud": {
        "provider": "AWS",
        "region": "us-east-1",
        "account": {
            "uid": "<AWSアカウントID>"
        }
    },
    "connection_info": {
        "direction": "Inbound",
        "direction_id": 1,
        "protocol_name": "tcp",
        "protocol_num": 6,
        "protocol_ver_id": 4,
        "uid": "326cec94b5b24cf8"
    },
    "duration": 175,
    "end_time": 0,
    "enrichments": [
        {
            "name": "global-resolver",
            "value": "gr-2788e8200b414d28",
            "data": {
                "dns_view_id": "dnsv-e4385db72ac849b4"
            }
        }
    ],
    "message": "",
    "metadata": {
        "version": "1.2.0",
        "product": {
            "name": "Global Resolver",
            "vendor_name": "AWS",
            "feature": {
                "name": "DNS"
            }
        }
    },
    "query": {
        "hostname": "www.non-97.net.non-97.net.",
        "class": "IN",
        "type": "A",
        "opcode": "Query",
        "opcode_id": 0
    },
    "query_time": 1765445369513,
    "rcode": "NOERROR",
    "rcode_id": 0,
    "response_time": 1765445369688,
    "severity": "Informational",
    "severity_id": 1,
    "src_endpoint": {
        "ip": "3.89.60.161",
        "port": 59522
    },
    "start_time": 0,
    "status": "Success",
    "status_id": 1,
    "time": 1765445369688,
    "type_name": "DNS Activity: Traffic",
    "type_uid": 400306
}
dev.classmethod.jp
{
    "action_id": 1,
    "action_name": "Allowed",
    "activity_id": 6,
    "activity_name": "Traffic",
    "answers": [],
    "category_name": "Network Activity",
    "category_uid": 4,
    "class_name": "DNS Activity",
    "class_uid": 4003,
    "cloud": {
        "provider": "AWS",
        "region": "us-east-1",
        "account": {
            "uid": "<AWSアカウントID>"
        }
    },
    "connection_info": {
        "direction": "Inbound",
        "direction_id": 1,
        "protocol_name": "tcp",
        "protocol_num": 6,
        "protocol_ver_id": 4,
        "uid": "73999e13bdc44944"
    },
    "duration": 2,
    "end_time": 0,
    "enrichments": [
        {
            "name": "global-resolver",
            "value": "gr-2788e8200b414d28",
            "data": {
                "dns_view_id": "dnsv-e4385db72ac849b4"
            }
        }
    ],
    "message": "",
    "metadata": {
        "version": "1.2.0",
        "product": {
            "name": "Global Resolver",
            "vendor_name": "AWS",
            "feature": {
                "name": "DNS"
            }
        }
    },
    "query": {
        "hostname": "dev.classmethod.jp.ec2.internal.",
        "class": "IN",
        "type": "A",
        "opcode": "Query",
        "opcode_id": 0
    },
    "query_time": 1765445385491,
    "rcode": "NOERROR",
    "rcode_id": 0,
    "response_time": 1765445385493,
    "severity": "Informational",
    "severity_id": 1,
    "src_endpoint": {
        "ip": "3.89.60.161",
        "port": 59522
    },
    "start_time": 0,
    "status": "Success",
    "status_id": 1,
    "time": 1765445385493,
    "type_name": "DNS Activity: Traffic",
    "type_uid": 400306
}

{
    "action_id": 1,
    "action_name": "Allowed",
    "activity_id": 6,
    "activity_name": "Traffic",
    "answers": [],
    "category_name": "Network Activity",
    "category_uid": 4,
    "class_name": "DNS Activity",
    "class_uid": 4003,
    "cloud": {
        "provider": "AWS",
        "region": "us-east-1",
        "account": {
            "uid": "<AWSアカウントID>"
        }
    },
    "connection_info": {
        "direction": "Inbound",
        "direction_id": 1,
        "protocol_name": "tcp",
        "protocol_num": 6,
        "protocol_ver_id": 4,
        "uid": "4356e18c0a2a456d"
    },
    "duration": 67,
    "end_time": 0,
    "enrichments": [
        {
            "name": "global-resolver",
            "value": "gr-2788e8200b414d28",
            "data": {
                "dns_view_id": "dnsv-e4385db72ac849b4"
            }
        }
    ],
    "message": "",
    "metadata": {
        "version": "1.2.0",
        "product": {
            "name": "Global Resolver",
            "vendor_name": "AWS",
            "feature": {
                "name": "DNS"
            }
        }
    },
    "query": {
        "hostname": "dev.classmethod.jp.non-97.net.",
        "class": "IN",
        "type": "A",
        "opcode": "Query",
        "opcode_id": 0
    },
    "query_time": 1765445385496,
    "rcode": "NOERROR",
    "rcode_id": 0,
    "response_time": 1765445385563,
    "severity": "Informational",
    "severity_id": 1,
    "src_endpoint": {
        "ip": "3.89.60.161",
        "port": 59522
    },
    "start_time": 0,
    "status": "Success",
    "status_id": 1,
    "time": 1765445385563,
    "type_name": "DNS Activity: Traffic",
    "type_uid": 400306
}

{
    "action_id": 1,
    "action_name": "Allowed",
    "activity_id": 6,
    "activity_name": "Traffic",
    "answers": [
        {
            "rdata": "3.167.99.98",
            "type": "A",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "3.167.99.118",
            "type": "A",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "3.167.99.14",
            "type": "A",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "3.167.99.120",
            "type": "A",
            "class": "IN",
            "ttl": 60
        }
    ],
    "category_name": "Network Activity",
    "category_uid": 4,
    "class_name": "DNS Activity",
    "class_uid": 4003,
    "cloud": {
        "provider": "AWS",
        "region": "us-east-1",
        "account": {
            "uid": "<AWSアカウントID>"
        }
    },
    "connection_info": {
        "direction": "Inbound",
        "direction_id": 1,
        "protocol_name": "tcp",
        "protocol_num": 6,
        "protocol_ver_id": 4,
        "uid": "2732091a91a94101"
    },
    "duration": 28,
    "end_time": 0,
    "enrichments": [
        {
            "name": "global-resolver",
            "value": "gr-2788e8200b414d28",
            "data": {
                "dns_view_id": "dnsv-e4385db72ac849b4"
            }
        }
    ],
    "message": "",
    "metadata": {
        "version": "1.2.0",
        "product": {
            "name": "Global Resolver",
            "vendor_name": "AWS",
            "feature": {
                "name": "DNS"
            }
        }
    },
    "query": {
        "hostname": "dev.classmethod.jp.",
        "class": "IN",
        "type": "A",
        "opcode": "Query",
        "opcode_id": 0
    },
    "query_time": 1765445385566,
    "rcode": "NOERROR",
    "rcode_id": 0,
    "response_time": 1765445385594,
    "severity": "Informational",
    "severity_id": 1,
    "src_endpoint": {
        "ip": "3.89.60.161",
        "port": 59522
    },
    "start_time": 0,
    "status": "Success",
    "status_id": 1,
    "time": 1765445385594,
    "type_name": "DNS Activity: Traffic",
    "type_uid": 400306
}

{
    "action_id": 1,
    "action_name": "Allowed",
    "activity_id": 6,
    "activity_name": "Traffic",
    "answers": [
        {
            "rdata": "2600:9000:27ce:4600:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:fa00:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:9a00:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:3a00:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:1a00:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:0:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:4c00:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        },
        {
            "rdata": "2600:9000:27ce:e400:14:e623:c740:93a1",
            "type": "AAAA",
            "class": "IN",
            "ttl": 60
        }
    ],
    "category_name": "Network Activity",
    "category_uid": 4,
    "class_name": "DNS Activity",
    "class_uid": 4003,
    "cloud": {
        "provider": "AWS",
        "region": "us-east-1",
        "account": {
            "uid": "<AWSアカウントID>"
        }
    },
    "connection_info": {
        "direction": "Inbound",
        "direction_id": 1,
        "protocol_name": "tcp",
        "protocol_num": 6,
        "protocol_ver_id": 4,
        "uid": "1998b94372184a7f"
    },
    "duration": 5,
    "end_time": 0,
    "enrichments": [
        {
            "name": "global-resolver",
            "value": "gr-2788e8200b414d28",
            "data": {
                "dns_view_id": "dnsv-e4385db72ac849b4"
            }
        }
    ],
    "message": "",
    "metadata": {
        "version": "1.2.0",
        "product": {
            "name": "Global Resolver",
            "vendor_name": "AWS",
            "feature": {
                "name": "DNS"
            }
        }
    },
    "query": {
        "hostname": "dev.classmethod.jp.",
        "class": "IN",
        "type": "AAAA",
        "opcode": "Query",
        "opcode_id": 0
    },
    "query_time": 1765445385601,
    "rcode": "NOERROR",
    "rcode_id": 0,
    "response_time": 1765445385606,
    "severity": "Informational",
    "severity_id": 1,
    "src_endpoint": {
        "ip": "3.89.60.161",
        "port": 59522
    },
    "start_time": 0,
    "status": "Success",
    "status_id": 1,
    "time": 1765445385606,
    "type_name": "DNS Activity: Traffic",
    "type_uid": 400306
}

DNSクライアントであるセルフマネージドDNSサーバーのDNSサフィックスで、ec2.internalcorp.non-97.netが設定されているので寄り道していますが、最終的に正常にAレコードの名前解決ができていることが分かります。

ということで、DoHやDoTのフォワーダーを用意することで内部DNSゾーンへのDNSクエリを暗号化することが可能です。

ただし、DoHやDoT対応のDNSサーバーを別途構築する場合、その分だけ運用維持管理するコストがかかるため、あまり現実的ではないでしょう。個人的にはDNSクエリが平文でインターネットを流れることに対して、セキュリティポリシー的に許容できない場合はRoute 53 Global Resolverは不向きでしょう。

ちなみにRouete 53 Resolver EndpointでもDoH/DoTはサポートしています。詳細は以下きじをご覧ください。

https://dev.classmethod.jp/articles/dns-usedroute-53-endpoint-over-doh/

Route 53 Global Resolverを用いて委任する

Route 53 Global Resolver Inbound Endpointの用途の中にRoute 53 Private Hosted Zoneの委任があります。

https://dev.classmethod.jp/articles/amazon-route-53-resolver-endpoints-dns-delegation-private-hosted-zones/

AWS公式ドキュメントではRoute 53 Global Resolverが委任をサポートしていることは一言も書かれておらず、おそらくできないとは思いますが念の為試してみます。

セルフマネージドDNSサーバー上でphz.test.corp.non-97.netの委任を作成し、値がunbound EC2インスタンスのIPアドレスのNSレコードを作成します。

5.委任.png

この状態で名前解決します。

> nslookup host.phz.test.corp.non-97.net
Server:  localhost
Address:  ::1

*** localhost can't find host.phz.test.corp.non-97.net: Server failed

はい、ダメでした。

NSレコードの値をRoute 53 Global Resolverに変更し、Route 53 Glaobl ResolverのアクセスソースでセルフマネージドDNSサーバーからのUDP/53のアクセスを許可します。

この状態で名前解決をします。

> nslookup www.non-97.net 52.223.8.240
Server:  a7b429450611ddf68.awsglobalaccelerator.com
Address:  52.223.8.240

Non-authoritative answer:
Name:    www.non-97.net
Address:  10.20.30.40

> nslookup host.phz.test.corp.non-97.net
Server:  localhost
Address:  ::1

*** localhost can't find host.phz.test.corp.non-97.net: Server failed

はい、結果は変わりませんでした。

ということで、Route 53 Global ResolverはRoute 53 Private Hosted Zoneの委任をサポートしていません。委任を行いたい場合はRoute 53 Resolver Inbound Endpointを作成しましょう。

デフォルトのRoute 53 Resolver Inbound Endpointを使っており、DNSクエリがインターネットを平文で流れることを許容できる もしくは手間無く DoH/DoT でフォワーディングできるのであれば置き替えられそう

一言でまとめると、

デフォルトのRoute 53 Resolver Inbound Endpointを使っており、DNSクエリがインターネットを平文で流れることを許容できる もしくは手間無く DoH/DoT でフォワーディングできるのであれば置き替えられそう

でしょうか。

他にも細かい条件でいうと、インターネットにDNSクエリが流れる訳なのでインターネット回線の信頼性やレイテンシーも気にしなければならない要素ではあります。Route 53 Resolver Inbound Endpointにフォワーディングする際にDirect Connectを介している場合はDNSクエリを投げて応答が返ってくるまでのレイテンシーを実測したいところです。

また、Route 53 Global ResolverはVPCに紐づく訳ではないため、EFSのようにAWSマネージドなPrivate Hosted Zoneが作成され、そのVPCでのみしか名前解決できない場合にも対応できません。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

FacebookHatena blogX

関連記事