EC2インスタンスが参照するDNSサーバーは基本的にRoute 53 Resolverを使いたい件
コンテンツDNSサーバーがオンプレミスにある場合であっても、直接参照しない方が良いこともある
こんにちは、のんピ(@non____97)です。
皆さんはEC2インスタンスが参照するDNSサーバーとして、何に指定していますか?
AWS上のリソースのゾーン管理はRoute 53 Private Hosted Zoneで、オンプレミスのリソースのゾーン管理はオンプレミスにあるコンテンツDNSサーバーで行っている方は多いでしょう。
この時、普段はオンプレミスにあるコンテンツDNSサーバーを参照することが多いのであれば、EC2インスタンスが参照するDNSサーバーとして、オンプレミスのコンテンツDNSサーバー、もしくはコンテンツDNSサーバーの名前解決が可能なキャッシュDNSサーバーや、そのフォワーダーを参照することが多いのではないでしょうか。
しかし、個人的にはコストが許すのであれば、基本的にはEC2インスタンスが参照するDNSサーバーはRoute 53 Resolverを使いたいと感じています。
以降、その理由を紹介します。
何故おすすめなのか
何故Route 53 Resolverがおすすめなのかの理由は以下のとおりです。
- DNSサーバーまでの経路の可用性を気にする必要性がない
- 自VPCに紐づいているPrivate Hosted Zone及びリソースの名前解決ができる
- DNSサーバーの切り替えの際に簡単に切り替えることができる
- PrivateLinkを用いているなど、名前解決したいゾーンを保持しているコンテンツDNSサーバーや、そのコンテンツDNSサーバーに問い合わせできるキャッシュDNSサーバーと直接通信ができない場合についても名前解決できる
一つ一つ簡単に補足します。
1. DNSサーバーまでの経路の可用性を気にする必要性がない
Route 53 ResolverはVPC内に存在するマネージドなフォワーダー兼キャッシュDNSサーバーです。
オンプレミスのDNSサーバーをVPCから参照する場合、そのDNSサーバーの可用性が気になります。DNSサーバー自体は冗長化されていても、オンプレミスとVPC間とが十分に冗長性がない場合もあるでしょう。
例えば、参照しているオンプレミスDNSサーバーまでの経路が切断された場合、そのEC2インスタンスは一切の名前解決ができなくなります。名前解決ができないということはSSM Session Managerによる接続もできなくなります。普段SSM Session Managerで作業している場合は、慌てること間違い無いです。
一方、Route 53 Resolverを参照しており、Route 53 Private Hosted Zoneやインターネットのゾーン以外のゾーンの名前解決をする際にはRoute 53 Resolver Outbound Endpointを使用して一部ゾーンの名前解決をオンプレミスで行っている場合、経路切断がされて出来なくなる名前解決の範囲はRoute 53 Resolver RuleでOutbound Endpointから転送しているドメインのみです。つまりはトラブル時の影響範囲を小さく抑えることが可能です。
2. 自VPCに紐づいているPrivate Hosted Zone及びリソースの名前解決ができる
Route 53 Resolverを使用しているということは自VPCに紐づいているPrivate Hosted Zone及びリソースの名前解決が可能になります。
ここでいうPrivate Hosted Zone
は自前のRoute 53 Private Hosted Zoneだけでなく、EFSファイルシステムやInterface型のSSM VPCエンドポイント、Service Network型Association(=従来のVPC Lattice)などAWSが自動で作成するゾーンのも含めます。
これらの名前解決をVPC外から行うためにはRoute 53 Resolver Inbound Endpointが必要になります。
つまりは、オンプレミスのコンテンツDNSサーバーで管理しているゾーンの名前解決が不要なのであれば、Route 53 Resolverを使った方がコストを抑えて名前解決することが可能です。
3. DNSサーバーの切り替えの際に簡単に切り替えることができる
DNSサーバーの切り替えの際もRoute 53 Resolver + Route 53 Resolver Outbound Endpointを使用する形が楽だと考えています。
Active Direcotryに参加しているWindows Serverであれば、グループポリシーでDNSサーバーを指定するログオンスクリプトを設定することでまとめて変更することもできるでしょう。
一方で、それ以外の環境の場合は各リソースで都度設定変更が必要となり手間です。
AWSにおいてはDHCPオプションセットを用いてVPC内のリソースのDNSサーバーを指定している場合もあるでしょう。
しかし、マルチアカウント等で大量のVPCがある場合は、各VPCのDHCPオプションセットを設定変更していくのも手間だと感じます。
Route 53 Resolver + Route 53 Resolver Outbound Endpointの場合は、そのVPCに紐づいているResoluver Ruleにて特定ドメインの名前解決が可能なのDNSサーバーを変更するだけです。こうすることで、Resolver Ruleと紐付けているVPCでRoute 53 Resolverで名前解決をする全てのリソースで、特定ドメインの名前解決が可能なのDNSサーバーを変更することが可能です。
一つのResoluver Ruleあたりに設定可能なIPアドレス数は6なので、一時的に新旧DNSサーバーを指定してから、切り替えるということもできます。
また、Resolver RuleはRAMで共有することも可能なのでマルチアカウントでの統制も簡単です。
4. PrivateLinkを用いているなど、名前解決したいゾーンを保持しているコンテンツDNSサーバーや、そのコンテンツDNSサーバーに問い合わせできるキャッシュDNSサーバーと直接通信ができない場合についても名前解決できる
IPアドレスの重複時の対応でPrivateLinkを用いた接続をしている場合にも便利です。
PrivateLinkを用いるInterface型VPCエンドポイントやService Network型VPCエンドポイント、Resource型VPCエンドポイントは双方向での通信はできません。片方向のみとなります。それぞれの説明は以下記事をご覧ください。
この制約により、名前解決したいゾーンを保持しているコンテンツDNSサーバーやキャッシュDNSサーバーを直接参照することできないことがあります。
ただし、この場合もRoute 53 Resolver Outbound EndpointがコンテンツDNSサーバーやキャッシュDNSサーバーと直接通信できるのであれば問題ありません。つまりは、クライアントが直接DNSサーバーに参照をする経路を持たなくても名前解決が行えます。
注意点
良いところばかり紹介していますが注意点もあります。
最大の注意点はRoute 53 Resolver Endpointの料金です。2025/7/12時点では以下の料金がかかってきます。
- ENI ごとに 0.125 USD/時間
- 100 万件のクエリあたり 0.40 USD (最初の 10 億件のクエリ/月)
- 100 万件のクエリあたり 0.20 USD (10 億件超のクエリ/月)
抜粋 : 料金 - Amazon Route 53 | AWS
Route 53 Resolver Endpoint一つにつき最低2つENIを作成することになるため、2つ × 0.125 USD/h × 730 h × 150ドル円 = 27,375円
が毎月少なくともかかってきます。
小規模環境ではなかなかハードルが高いでしょう。
コストと紹介したメリットを勘案しながら選択しましょう。
やってみた
検証環境
実際にRoute 53 Resolverを指定する場合と、直接セルフマネージドのDNSサーバーを指定した場合との名前解決を試してみます。
検証環境は以下のとおりです。
Windows Serverのドメイン参加以外は完了しています。
Route 53 Resolverの設定は以下のとおりです。
以降、Windows Server 2025のOS操作はSSM Session Managerから行います。
参照するDNSサーバーがRoute 53 Resolverの場合
host.test.corp.non-97.netの名前解決
まず、host.test.corp.non-97.net
の名前解決をします。
> nslookup host.test.corp.non-97.net
Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
Non-authoritative answer:
Name: host.test.corp.non-97.net
Address: 10.10.0.10
正常にできましたね。
Route 53 Resolver Outbound Endpointを介したドメイン参加
それでは、Route 53 Resolver Outbound Endpointを介したドメイン参加を行います。
> $client = Get-NetAdapter | Get-DnsClient
> $client | Get-DnsClientServerAddress -AddressFamily IPv4
InterfaceAlias Interface Address ServerAddresses
Index Family
-------------- --------- ------- ---------------
Ethernet 3 IPv4 {10.10.10.2}
> $password=ConvertTo-SecureString -AsPlainText -Force <ドメインのAdministratorのパスワード>
> $credential=New-Object System.Management.Automation.PSCredential("test.corp.non-97.net\Administrator",$password)
> Add-Computer -DomainName test.corp.non-97.net -Credential $credential -Restart -Force
正常にコマンドを受け付けられました。
SSM Fleet ManagerからドメインのAdministratorでRDP接続をします。
> whoami -fqdn
CN=Administrator,CN=Users,DC=test,DC=corp,DC=non-97,DC=net
> hostname
EC2AMAZ-JL33NA5
> Get-NetAdapter | Get-DnsClient | Get-DnsClientServerAddress -AddressFamily IPv4
InterfaceAlias Interface Address ServerAddresses
Index Family
-------------- --------- ------- ---------------
Ethernet 3 IPv4 {10.10.10.2}
> nslookup EC2AMAZ-JL33NA5.test.corp.non-97.net
Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
Non-authoritative answer:
Name: EC2AMAZ-JL33NA5.test.corp.non-97.net
Address: 10.10.10.60
> ipconfig
Windows IP Configuration
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . : ec2.internal
Link-local IPv6 Address . . . . . : fe80::7d54:c22a:45c9:2094%3
IPv4 Address. . . . . . . . . . . : 10.10.10.60
Subnet Mask . . . . . . . . . . . : 255.255.255.192
Default Gateway . . . . . . . . . : 10.10.10.1
ドメイン参加が正常に行われており、参照しているDNSサーバーはRoute 53 Resolverのままであることが分かります。
VPCピアリングへのルートを削除した状態で、host.test.corp.non-97.netの名前解決
VPCピアリングへのルートを削除した状態で、host.test.corp.non-97.net
の名前解決ができることを確認します。
VPC Bのルートテーブルにて、AD DCがあるVPC AとWindows Server 2025のEC2インスタンスが存在するVPC BとのVPCピアリングへのルートを削除します。
この状態で名前解決をします。
> nslookup host.test.corp.non-97.net
Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
Non-authoritative answer:
Name: host.test.corp.non-97.net
Address: 10.10.0.10
> nslookup EC2AMAZ-JL33NA5.test.corp.non-97.net
Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
Non-authoritative answer:
Name: EC2AMAZ-JL33NA5.test.corp.non-97.net
Address: 10.10.10.60
問題なくできましたね。
host.test2.corp.non-97.netの名前解決
このままPrivate Hosted Zoneの名前解決ができることも確認します。
まずはhost.test2.corp.non-97.net
です。
> nslookup host.test2.corp.non-97.net
Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
Non-authoritative answer:
Name: host.test2.corp.non-97.net
Address: 10.10.10.20
正常にできました。
host.phz.test.corp.non-97.netの名前解決
続いて、host.phz.test.corp.non-97.net
です。
> nslookup host.phz.test.corp.non-97.net
Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
Non-authoritative answer:
Name: host.phz.test.corp.non-97.net
Address: 10.10.10.10
こちらも正常にできました。
参照するDNSサーバーがAD DCの場合
host.test.corp.non-97.netの名前解決
続いて、参照するDNSサーバーがAD DCの場合を試してみます。
host.test.corp.non-97.net
の名前解決から試します。
> nslookup host.test.corp.non-97.net 10.10.0.7
DNS request timed out.
timeout was 2 seconds.
Server: UnKnown
Address: 10.10.0.7
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 UnKnown timed-out
はい、VPCピアリングへのルートを削除したままなので、DNSサーバーに接続できず、タイムアウトとなりました。
VPCピアリングへのルートを追加してから再度名前解決をします。
> nslookup host.test.corp.non-97.net 10.10.0.7
Server: ip-10-10-0-7.ec2.internal
Address: 10.10.0.7
Name: host.test.corp.non-97.net
Address: 10.10.0.10
正常に名前解決できました。
host.test2.corp.non-97.netの名前解決
次にRoute 53 Private Hosted Zone上のレコードの名前解決です。
host.test2.corp.non-97.net
の名前解決から試します。
> nslookup
Default Server: ip-10-10-10-2.ec2.internal
Address: 10.10.10.2
> set debug
> host.test2.corp.non-97.net 10.10.0.7
Server: [10.10.0.7]
Address: 10.10.0.7
------------
Got answer:
HEADER:
opcode = QUERY, id = 2, rcode = NXDOMAIN
header flags: response, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
host.test2.corp.non-97.net.ec2.internal, type = A, class = IN
AUTHORITY RECORDS:
-> ec2.internal
ttl = 60 (1 min)
primary name server = ns0.ec2.internal
responsible mail addr = hostmaster.amazon.com
serial = 2012103100
refresh = 3600 (1 hour)
retry = 3600 (1 hour)
expire = 3600 (1 hour)
default TTL = 60 (1 min)
------------
------------
Got answer:
HEADER:
opcode = QUERY, id = 3, rcode = NXDOMAIN
header flags: response, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
host.test2.corp.non-97.net.ec2.internal, type = AAAA, class = IN
AUTHORITY RECORDS:
-> ec2.internal
ttl = 60 (1 min)
primary name server = ns0.ec2.internal
responsible mail addr = hostmaster.amazon.com
serial = 2012103100
refresh = 3600 (1 hour)
retry = 3600 (1 hour)
expire = 3600 (1 hour)
default TTL = 60 (1 min)
------------
------------
Got answer:
HEADER:
opcode = QUERY, id = 4, rcode = NXDOMAIN
header flags: response, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
host.test2.corp.non-97.net.us-east-1.ec2-utilities.amazonaws.com, type = A, class = IN
AUTHORITY RECORDS:
-> amazonaws.com
ttl = 13 (13 secs)
primary name server = dns-external-master.amazon.com
responsible mail addr = hostmaster.amazon.com
serial = 2017224478
refresh = 180 (3 mins)
retry = 60 (1 min)
expire = 604800 (7 days)
default TTL = 900 (15 mins)
------------
------------
Got answer:
HEADER:
opcode = QUERY, id = 5, rcode = NXDOMAIN
header flags: response, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
host.test2.corp.non-97.net.us-east-1.ec2-utilities.amazonaws.com, type = AAAA, class = IN
AUTHORITY RECORDS:
-> amazonaws.com
ttl = 13 (13 secs)
primary name server = dns-external-master.amazon.com
responsible mail addr = hostmaster.amazon.com
serial = 2017224478
refresh = 180 (3 mins)
retry = 60 (1 min)
expire = 604800 (7 days)
default TTL = 900 (15 mins)
------------
------------
Got answer:
HEADER:
opcode = QUERY, id = 6, rcode = NXDOMAIN
header flags: response, auth. answer, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
host.test2.corp.non-97.net.test.corp.non-97.net, type = A, class = IN
AUTHORITY RECORDS:
-> test.corp.non-97.net
ttl = 3600 (1 hour)
primary name server = ec2amaz-oraeuk8.test.corp.non-97.net
responsible mail addr = hostmaster.test.corp.non-97.net
serial = 25
refresh = 900 (15 mins)
retry = 600 (10 mins)
expire = 86400 (1 day)
default TTL = 3600 (1 hour)
------------
------------
Got answer:
HEADER:
opcode = QUERY, id = 7, rcode = NXDOMAIN
header flags: response, auth. answer, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
host.test2.corp.non-97.net.test.corp.non-97.net, type = AAAA, class = IN
AUTHORITY RECORDS:
-> test.corp.non-97.net
ttl = 3600 (1 hour)
primary name server = ec2amaz-oraeuk8.test.corp.non-97.net
responsible mail addr = hostmaster.test.corp.non-97.net
serial = 25
refresh = 900 (15 mins)
retry = 600 (10 mins)
expire = 86400 (1 day)
default TTL = 3600 (1 hour)
------------
DNS request timed out.
timeout was 2 seconds.
timeout (2 secs)
DNS request timed out.
timeout was 2 seconds.
timeout (2 secs)
*** Request to 10.10.0.7 timed-out
はい、失敗しました。
host.phz.test.corp.non-97.netの名前解決
続いて、host.phz.test.corp.non-97.net
の名前解決から試します。
> nslookup host.phz.test.corp.non-97.net 10.10.0.7
Server: ip-10-10-0-7.ec2.internal
Address: 10.10.0.7
*** ip-10-10-0-7.ec2.internal can't find host.phz.test.corp.non-97.net: Non-existent domain
こちらも失敗しました。
ただし、こちらは名前解決するDNS名が参照しているAD DCで管理しているゾーンのサブドメインの形になっているため、タイムアウトではなく、対象レコードが存在しないというメッセージになっています。
OS設定で参照するDNSサーバーをAD DCにしてからVPCピアリングを切断した場合
最後に、OS設定で参照するDNSサーバーをAD DCにしてからVPCピアリングを切断した場合の挙動を確認します。
参照先のDNSサーバーをAD DCに変更します。
> $dnsServers = @("10.10.0.7")
> $client = Get-NetAdapter | Get-DnsClient
> $client | Set-DnsClientServerAddress -ServerAddresses $dnsServers
> $client | Get-DnsClientServerAddress -AddressFamily IPv4
InterfaceAlias Interface Address ServerAddresses
Index Family
-------------- --------- ------- ---------------
Ethernet 3 IPv4 {10.10.0.7}
nslookupをする際に明示的にDNSサーバーを指定しなくとも、AD DCに問い合わせることを確認します。
> nslookup host.test.corp.non-97.net
Server: ip-10-10-0-7.ec2.internal
Address: 10.10.0.7
Name: host.test.corp.non-97.net
Address: 10.10.0.10
この状態で、VPCピアリングへのルートを再度削除します。
そして、SSM Session Managerで新規セッションを接続しようとすると以下のようになりました。
Your session has been terminated for the following reasons: ----------ERROR------- Setting up data channel with id <IAMユーザー名>-3xrf8kgldvg6ghykcyqvg8fd34 failed: failed to create websocket for datachannel with error: CreateDataChannel failed with no output or error: createDataChannel request failed: failed to make http client call: Post "https://ssmmessages.us-east-1.amazonaws.com/v1/data-channel/<IAMユーザー名>-3xrf8kgldvg6ghykcyqvg8fd34": dial tcp: lookup ssmmessages.us-east-1.amazonaws.com: no such host
データチャネルの作成に必要な名前解決に失敗して、接続できなかったようです。
SSM Session Managerだけでなく、SSM Run CommandなどSSMマネージドノードに対して行う操作もできない形になります。運用時はDNSサーバーの経路までの接続性について気をつけたいですね。
Route 53 Resolverの良さを再認識した
EC2インスタンスが参照するDNSサーバーは基本的にRoute 53 Resolverを使いたい理由を紹介しました。
最近Route 53 Resolverの良さを再認識したので勢いでブログを書いてしまいました。やっぱり良いですよね、Route 53 Resolver。
ハイブリッドクラウド、複数アカウントのDNS周りの運用については以下記事も参考になるかと思います。
この記事が誰かの助けになれば幸いです。
以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!