ドメイン名が IP アドレスになるまで:DNS の名前解決のしくみ

ブラウザに入力した名前がどのように IP アドレスに変わるのか。スタブリゾルバ・フルリゾルバ・権威サーバー・キャッシュの役割と A/AAAA レコード、TTL を RFC をもとに整理しました。

開発ネットワーク

ブラウザのアドレスバーに www.example.com と入力してから、ページが表示されるまでの間に片付けなければならないことがあります。コンピューターが相手に接続するには、名前ではなく IP アドレスが必要です。名前をアドレスに変換するしくみが DNS(Domain Name System)で、この記事ではその名前解決がどのように行われるのかを、RFC の用語に沿って整理します。

登場する構成要素

DNS の用語をまとめた RFC 9499 に従うと、名前解決にはおおよそ次の役割が登場します。

  • スタブリゾルバ(stub resolver):自分だけでは名前解決を最後まで行えないリゾルバです。ふつうは OS やライブラリの中にあり、アプリからの問い合わせを受けてフルリゾルバに渡します。
  • フルリゾルバ(recursive resolver、再帰リゾルバ):問い合わせを受け、必要なサーバーに順に問い合わせて最終的な答えを見つけるリゾルバです。通信事業者、パブリック DNS サービス、社内ネットワーク、家庭用ルーターなど、さまざまな場所で運用されています。受け取った答えをキャッシュに保存して再利用するのが一般的です。
  • 権威サーバー(authoritative server):あるゾーンの内容を自分で知っていて、ほかのサーバーに問い合わせなくてもそのゾーンについての問い合わせに答えられるサーバーです。example.com のレコードを最終的に教えてくれるのはここです。
  • キャッシュ(cache):以前に受け取った答えをしばらく保管しておく場所です。フルリゾルバだけでなく、OS やアプリにもある場合があります。

名前空間の頂点にはルートがあり、その下に .com のようなトップレベルドメイン(TLD)、さらにその下に example.com のようなドメインがあります。上位のゾーンは下位のゾーンの管理をほかのサーバーに委任(delegation)し、そのサーバーがどこかを知らせる応答が参照(referral)です。

キャッシュが空のときの簡略化した経路

DNS の名前解決の流れを示す図。クライアント(ブラウザ・アプリ)がスタブリゾルバに、スタブリゾルバがフルリゾルバに問い合わせます。フルリゾルバのキャッシュに有効な答えがあればすぐに返します。なければルートサーバー(.com のサーバーを参照)、TLD サーバー(example.com のサーバーを参照)、権威サーバー(A/AAAA レコードで回答)の順に問い合わせ、得た答えをスタブリゾルバ経由でクライアントに返します。

図:すべてのキャッシュが空だと仮定した、簡略化した経路です。実際にはアプリ、OS、フルリゾルバのキャッシュが答えたり、途中までの情報をすでに持っていたりすることがあり、その場合は経路が短くなります。

何もキャッシュされていないと仮定すると、www.example.com のアドレスを探す流れは次のように描けます。

  1. ブラウザやアプリが、スタブリゾルバに www.example.com のアドレスを問い合わせます。
  2. スタブリゾルバは、設定されているフルリゾルバに問い合わせを送ります。
  3. フルリゾルバはルートサーバーに問い合わせます。ルートサーバーは答えの代わりに「.com はこれらのサーバーが担当している」という参照を返します。
  4. フルリゾルバは .com のサーバーに問い合わせ、「example.com はこれらのサーバーが担当している」という参照を受け取ります。
  5. フルリゾルバは example.com の権威サーバーに問い合わせ、www.example.com の A または AAAA レコードを答えとして受け取ります。
  6. フルリゾルバはこの答えをキャッシュに入れてスタブリゾルバに返し、スタブリゾルバがアプリに渡します。

クライアントはフルリゾルバに「最終的な答えを探してほしい」と一度問い合わせ、フルリゾルバが参照をたどって複数のサーバーに問い合わせる、という構造です。RFC 1034 はこの 2 つのやり方を再帰(recursive)モードと反復(iterative)モードとして区別して説明し、リゾルバがまずキャッシュを確認し、知っている中でいちばん近いサーバーから問い合わせて参照をたどるアルゴリズムを示しています。

実際はこの図とは異なる

上の 6 ステップは理解を助けるためのモデルです。実際の名前解決はいくつもの理由で異なります。

  • キャッシュが先に答えます。 フルリゾルバに有効な答えがあれば、ステップ 3〜5 を行わずにすぐに返します。1 つのリゾルバを多くのユーザーが共有することもあるので、以前の問い合わせによって名前がすでにキャッシュにある場合もあります。
  • 途中の情報もキャッシュされます。 フルリゾルバは .com を担当するサーバーの一覧のような参照情報も保存しているので、毎回ルートから始めるわけではありません。
  • どこにキャッシュがあるかは実装によって異なります。 ブラウザが独自のキャッシュを持つか、OS がキャッシュを持つか、アプリが OS のリゾルバを使うか自分で DNS に問い合わせるか、hosts ファイルを先に参照するかは、ブラウザ、OS、設定によって違います。
  • 往復回数は決まっていません。 キャッシュの状態、応答の遅いサーバーへの再試行、複数のサーバーからの選択、別名(CNAME)をたどる追加の問い合わせなどによって、ネットワークの往復回数は 0 回から何回にもなります。「DNS の名前解決は何往復する」という決まった数はありません。

A レコードと AAAA レコード

DNS が返すアドレスは、レコードの種類で区別されます。

  • A レコード:IPv4 アドレス(32 ビット)を 1 つ持ちます。192.0.2.1 のような形式です。RFC 1035 で定義されています。
  • AAAA レコード:IPv6 アドレス(128 ビット)を 1 つ持ちます。2001:db8::1 のような形式です。RFC 3596 で定義されています。

1 つの名前に両方ある場合も、片方だけの場合もあります。両方を受け取ったとき、どちらのアドレスに先に接続を試みるかは、DNS ではなくクライアントが決めます。

TTL:キャッシュにどれだけ置けるか

すべてのレコードには TTL(Time To Live)が付いています。RFC 1035 は TTL を、レコードをキャッシュに置いておける時間間隔(秒)と定義し、その時間が過ぎたら情報源に問い合わせ直すべきだと説明しています。TTL が 0 なら、進行中のトランザクションにだけ使え、キャッシュすべきではないという意味です。

TTL はキャッシュに置いておける最長の期間であって、必ずその間置いておかなければならない期間ではありません。キャッシュはそれより前にレコードを破棄できます。ただし、キャッシュされたコピーが期限切れになるまではそのコピーで答えることがあるので、レコードを変更した直後は、一部のユーザーがまだ古いアドレスを受け取ることがあります。

DNS の名前解決は接続ではない

DNS の名前解決が終わっても、アプリはアドレスを知っただけです。Web ページを取得するには、そのアドレスに接続を確立し(TCP または QUIC)、HTTPS なら TLS で暗号化を取り決めてから HTTP リクエストを送る、という別の段階が続きます。そのため「サイトが開かない」という問題は、名前が見つからない DNS の問題の場合もあれば、アドレスは見つかったものの接続やサーバー側で失敗している場合もあります。

参照した RFC

RFC 1034 と 1035 は DNS の土台となった文書です。その後多くの RFC がこの 2 つを更新・補完しているため、現在のリゾルバやブラウザが行うことをすべて記述しているわけではありません。

ブログへ