再帰リゾルバー(Recursive Resolver)
概要
再帰リゾルバー(Recursive Resolver) は、クライアントからの DNS クエリを受け取り、ルートネームサーバーから TLD ネームサーバー、権威ネームサーバーへと順に問い合わせて最終的な回答を返す DNS サーバーです。RFC 1034 および RFC 1035(1987年)で基本仕様が定義されており、DNS アーキテクチャにおける「仲介者」の役割を担います。フルサービスリゾルバー、キャッシュ DNS サーバーとも呼ばれます。
ブラウザーやメールサーバーが直接ルートネームサーバーに問い合わせることはありません。OS のスタブリゾルバーが再帰リゾルバーにクエリを送り、再帰リゾルバーが複数のネームサーバーを巡回して答えを集めます。得られた結果は TTL に従ってキャッシュされ、同じドメインへの次の問い合わせではキャッシュから即座に応答します。
代表的なパブリック再帰リゾルバーとして、Google Public DNS(8.8.8.8)と Cloudflare DNS(1.1.1.1)があります。ISP が提供するリゾルバーも再帰リゾルバーです。
仕組み
再帰リゾルバーはクライアントからの再帰クエリを受け、内部では反復クエリをルートから権威サーバーまで繰り返して結果をキャッシュします。
再帰クエリと反復クエリ
DNS の問い合わせには 2 種類あります。
再帰クエリは、クライアントがリゾルバーに「最終的な答えを返してほしい」と依頼する形式です。リゾルバーは自力で答えを見つけるか、エラーを返すかのどちらかで、途中経過(リファラル)は返しません。DNS ヘッダーの RD(Recursion Desired)ビットを 1 にセットすることで再帰を要求します。
反復クエリは、リゾルバーが他のネームサーバーに対して使う形式です。問い合わせ先のネームサーバーは、自分が知っている範囲で最善の回答を返します。答えを持っていなければ、より詳しいネームサーバーへの参照(リファラル)を返します。
再帰リゾルバーは、クライアントからの再帰クエリを受け取り、内部では反復クエリを繰り返して答えを組み立てます。
名前解決のフロー
ブラウザーが www.example.com の IP アドレスを求めたとき、キャッシュが空の状態では次の流れで解決が進みます。
- OS のスタブリゾルバーが再帰リゾルバーに
www.example.comの A レコードを問い合わせる - 再帰リゾルバーはルートネームサーバー(
.)に問い合わせる - ルートネームサーバーは
.comTLD ネームサーバーのアドレスをリファラルとして返す - 再帰リゾルバーは
.comTLD ネームサーバーに問い合わせる - TLD ネームサーバーは
example.comの権威ネームサーバーのアドレスを返す - 再帰リゾルバーは権威ネームサーバーに
www.example.comの A レコードを問い合わせる - 権威ネームサーバーが
93.184.216.34を返す - 再帰リゾルバーは結果をキャッシュし、クライアントに回答を返す
この一連の処理は通常 50〜200 ミリ秒 で完了します。キャッシュにヒットした場合は 1 ミリ秒未満で応答します。
キャッシュの役割
再帰リゾルバーの性能はキャッシュに大きく依存します。上記のフローでは 4 回の問い合わせが発生しますが、.com TLD ネームサーバーのアドレスは多くのドメインで共通です。一度取得すれば TTL が切れるまでキャッシュから使い回せるため、2 回目以降の .com ドメインの解決ではステップ 2〜3 を省略できます。
大規模なパブリック DNS は膨大なクエリを処理するため、キャッシュヒット率が高くなります。Google Public DNS は 1 日あたり数千億件のクエリを処理しており、人気ドメインのレコードはほぼ常にキャッシュに存在します。
RFC 8767(2020年)は、権威サーバーが応答しない場合に TTL 切れのキャッシュを一時的に返す「Serve Stale」の仕組みを規定しています。Cloudflare DNS や Google Public DNS はこの仕組みを実装しており、権威サーバーの一時障害時でもドメイン解決を継続できます。
権威ネームサーバーとの違い
再帰リゾルバーと権威ネームサーバーは DNS の異なる役割を担います。
| 項目 | 再帰リゾルバー | 権威ネームサーバー |
|---|---|---|
| データの出所 | 他のサーバーへの問い合わせ結果 | 自身のゾーンデータ |
| キャッシュ | 使う(TTL まで保持) | 使わない |
| 担当範囲 | 任意のドメイン | 特定のゾーン |
| クライアントからの利用 | 直接利用される | 再帰リゾルバー経由で間接的に利用 |
| 例 | 8.8.8.8、1.1.1.1、ISP の DNS | Cloudflare DNS(権威側)、Route 53 |
Cloudflare は再帰リゾルバー(1.1.1.1)と権威ネームサーバーの両方を提供していますが、これらは独立したサービスです。
セキュリティ
再帰リゾルバーはクライアントと権威サーバーの間に位置するため、攻撃の対象になりやすい存在です。
RFC 5452(2009年)は、偽造された DNS 応答に対する耐性を高める手法を規定しています。送信元ポートのランダム化、トランザクション ID の予測困難性、ベイルウィック(bailiwick)チェックによる権限外レコードの排除が含まれます。
DNSSEC はリゾルバーが受け取った応答の署名を検証し、改ざんされたレコードを拒否する仕組みです。Google Public DNS と Cloudflare DNS は DNSSEC 検証を標準で有効にしています。
DNS over HTTPS(DoH、RFC 8484、2018年)と DNS over TLS(DoT、RFC 7858、2016年)は、スタブリゾルバーと再帰リゾルバーの間の通信を暗号化します。従来の平文 UDP 通信では、経路上の第三者がクエリ内容を盗聴できましたが、DoH / DoT はこの問題を解消します。
主要パブリック DNS の比較
| プロバイダー | IPv4 アドレス | IPv6 アドレス | DoH | DoT | DNSSEC 検証 |
|---|---|---|---|---|---|
| Google Public DNS | 8.8.8.8, 8.8.4.4 | 2001:4860:4860::8888 | 対応 | 対応 | 有効 |
| Cloudflare DNS | 1.1.1.1, 1.0.0.1 | 2606:4700:4700::1111 | 対応 | 対応 | 有効 |
| Quad9 | 9.9.9.9 | 2620:fe::fe | 対応 | 対応 | 有効 |
Cloudflare DNS はクエリログを 24 時間 で削除するプライバシーポリシーを採用しています。Google Public DNS もログの匿名化を行っていますが、保持期間は異なります。
確認方法
自分が使っている再帰リゾルバーを確認するには、OS の DNS 設定を確認します。
# macOS / Linux: 設定されているリゾルバーを表示
cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
特定の再帰リゾルバーを指定して DNS クエリを実行するには dig の @ オプションを使います。
# Google Public DNS 経由で A レコードを確認
dig A example.com @8.8.8.8
# Cloudflare DNS 経由で確認
dig A example.com @1.1.1.1
応答ヘッダーの flags: に ra(Recursion Available)フラグが含まれていれば、そのサーバーは再帰クエリに対応しています。
;; flags: qr rd ra; QUERY: 1, ANSWER: 1
rd は Recursion Desired(クライアント側の再帰要求)、ra は Recursion Available(サーバー側の再帰対応)を意味します。権威ネームサーバーに直接問い合わせた場合、ra は立たず aa(Authoritative Answer)が立ちます。
# 権威ネームサーバーに直接問い合わせた場合
dig A example.com @ns1.cloudflare.com +norec
;; flags: qr aa; QUERY: 1, ANSWER: 1
外部の視点からも確認したい場合は、Labee Dev Toolbox の DNS API を使うと、DNS over HTTPS を使って外部のリゾルバーから見た結果を取得できます。
curl "https://labee.dev/api/dns?domain=example.com&type=A"
{
"success": true,
"data": {
"domain": "example.com",
"records": {
"A": [
{ "address": "93.184.216.34", "ttl": 3600 }
]
}
},
"error": null,
"meta": { "responseTime": 45 }
}
records.A の各要素に address(IP アドレス)と ttl(残り TTL)が含まれます。手元の dig @8.8.8.8 と Labee API で返る TTL が大きく異なる場合、それぞれの再帰リゾルバーがレコードをキャッシュしたタイミングが異なることを意味します。
よくある問題
再帰リゾルバーのキャッシュ動作やネットワーク到達性の問題が、DNS 変更の反映遅延やクエリ失敗を引き起こします。
DNS を変更したのに反映されない
再帰リゾルバーが旧レコードを TTL まで保持しているために発生します。権威サーバーに直接問い合わせて新しいレコードが返る場合、変更自体は正しく行われています。
# 権威サーバーに直接確認(キャッシュをバイパス)
dig A example.com @ns1.example.com +norec
# 再帰リゾルバー経由で確認(キャッシュが返る可能性あり)
dig A example.com @8.8.8.8
変更前に TTL を 300 秒程度に下げておくと、切り替え後の待ち時間を最小化できます。
特定の ISP のユーザーだけ古い結果が返る
一部の ISP の再帰リゾルバーは、レコードの TTL を無視して独自の長い期間キャッシュすることがあります。RFC 1035 の規定に反しますが、実際に発生するケースです。影響を受けるユーザーには、DNS 設定を 1.1.1.1 や 8.8.8.8 に変更するよう案内します。
再帰リゾルバーがタイムアウトする
再帰リゾルバーが権威サーバーに到達できない場合、クエリがタイムアウトします。権威サーバーの障害、ネットワーク経路の問題、ファイアウォールによる UDP 53 番ポートのブロックが原因として考えられます。
# 権威サーバーへの到達性を確認
dig A example.com @ns1.example.com +timeout=5
応答がない場合は、権威サーバー側の状態を確認してください。Serve Stale(RFC 8767)に対応したリゾルバーであれば、TTL 切れのキャッシュを一時的に返すことで障害の影響を軽減します。
オープンリゾルバーになっている
自組織で運用する再帰リゾルバーがインターネット全体からのクエリを受け付ける状態(オープンリゾルバー)になっていると、DNS リフレクション攻撃の踏み台にされるリスクがあります。再帰リゾルバーへのアクセスは、自組織のネットワークからのみ許可するように制限してください。RFC 5452 でもアクセス制御の実施が推奨されています。