DNSの仕組みを徹底解明!【シンプルだけどすごい技術】

DNS(Domain Name System)は、インターネットで使われている名前とIPアドレスとの変換を行うプロトコルです。

IPプロトコルではIPアドレスを使用して通信相手を特定しますが、数字の羅列であるIPアドレスを人間が覚えるのは大変です。一方、「www.google.co.jp」のような文字列であれば覚えやすいです。

例えば、Googleにアクセスしたいとき、IPアドレスを直接打ち込む人はいないと思います。ブラウザのアドレスバーに「www.google.co.jp」などと入力するはずです。

クライアントはこの名前をDNSサーバーに問い合わせ、対応するIPアドレスを取得します。その結果、ユーザーはIPアドレスを意識せずGoogleのページを開けるというわけです。

簡単に書いていますが、これはかなりすごいことです。例えば、上記のようにWebページを閲覧する場合、巨大なインターネット上からユーザーを待たせることなく瞬時にIPアドレスを探しだす必要があるからです。

今回の記事では、そのDNSの仕組みについて掘り下げて調べていきたいと思います。

DNSの仕組み

PCからの要求にもとづいて、DNSサーバーが世界規模で分散されたテキストデータベースに記録されているレコードを探索して、ホスト名+ドメイン名※とIPアドレスとの変換を行います。このことを名前解決と言います。
※下図例では「www」がホスト名、「sample.com」がドメイン名となります。また、ホスト名+ドメイン名をFQDNと呼びます。

FQDNは「Fully Qualified Domain Name:完全修飾ドメイン名」のことを指し、名前のとおり、完全に修飾されたドメイン名という意味です。ここで修飾されるのはホストです(上図例では「www」)。ドメイン名だけでは、Webサーバーなのかメールサーバーなのかなどがわからないので、ホストをひとつに特定できません。FQDNであればホストをひとつに特定できるので、そのホストのIPアドレスも一意に決めることができます。

ではここで、IPAの情報処理技術者試験の過去問からDNSの基本的な知識を確認していきましょう。

インターネットで使われるドメイン名及びIPアドレスは、DNSを利用して管理されている。DNSは多数のDNSサーバーで構成される分散型データベースであり、ルートDNSサーバーを頂点とし、ドメイン名空間と呼ばれるツリー構造を構成している。インターネットでは、負荷分散可用性を考慮して、13のルートDNSサーバーが配置されている。 DNSのツリー構造の最上位に位置するルートDNSサーバーの配下には、ドメイン名(例:jpドメイン、co.jpドメインなど)に対応したDNSサーバーがある。あるドメイン名を管理するDNSサーバーに関する情報は、ツリー構造の上位階層のドメイン名を管理するDNSサーバーが保持している。ホストに関する情報は、そのホストが所属するドメイン名を管理するDNSサーバーが保持している。 ドメイン名の中で、www.example.co.jpのように特定のホストを表現したドメイン名をFQDNと呼ぶ。 一つのドメインを管理するDNSサーバーは、通常は可用性を考慮して2台のサーバーで構成される。一方をプライマリサーバー、もう一方をセカンダリサーバーと呼ぶ。

黄色の背景色となっているところが空欄の穴埋め問題として問われたところです。補足として、プライマリサーバー、セカンダリサーバーのことをそれぞれマスターサーバー、スレーブサーバーと呼ばれることもあります。意味は一緒なので混同しないようにしましょう。

DNSのレコード種類

DNSサーバーは、データベースとして「リソースレコード」と呼ばれるテキストデータを持ちます。代表的なリソースレコードして以下があります。

リソースレコードの種類説明
SOA(Start Of Authority)ゾーン全体の基本情報を記述。具体的には、DNSサーバーの管理情報、設定番号(シリアル値)、スレーブサーバーの更新間隔、ゾーン転送が失敗したときの再実行間隔、リソースレコードの有効期限など、そのドメインの管理情報を記述する。
A(Address)DNS正引きで利用するホスト名→IPアドレスの関係を登録。
MX(Mail eXchange)メールサーバーのホスト名を登録。具体的には、ドメイン名ごとに転送先のメールサーバーと、その転送の優先度(プレファレンス)を対応させる。優先度の値が小さい順にメールが優先的に転送される。
CNAME(Canonical NAME)ホスト名の別名(エイリアス)を登録。
NS(Name Server)ゾーン情報を管理するDNSサーバーを登録。そのゾーン自身や下位ドメインのゾーン情報が定義されているDNSサーバーのホスト名を指定する。
TXT(Text)ドメインやホスト名の付加情報を記述。SPFにも利用される。
AAAA(quad A)IPv6用のAレコード
Cさん

いっぱいあって覚えきれません。そもそも「ゾーン」って何ですか?

ゾーンとは自身が管理するDNSの領域のことです。例えば”「example.com」というドメインは私が管理します”といった感じで、自信が管理するゾーン情報をSOAレコードに明記します。DNSを覚えるには一度、DNSサーバーを組んでみるのが最も効率的だと思います。Linuxやbindなどの環境であれば無料で構築できるので、機会があればぜひ試してみてください。

DNSの動作

DNSの名前解決は基本的にとてもシンプルです。

まず、クライアント(リゾルバと呼ばれます)は「www.google.co.jp」のIPアドレスは何ですか?」という名前解決の要求をDNSサーバーに対して出します。
次にDNSサーバーは「www.google.jpのアドレスはXXX.XXX.XXX.XXXです」と応答します。

このように、DNSは、要求とその応答の2つのパケットで事足りる、とてもシンプルなプロトコルです。
実際にDNSによる名前解決の様子をパケットキャプチャして確認してみましょう。

上記例では、「router.webtest01.com」というFQDNの名前解決要求(1番目のパケット)に対して、DNSサーバー(10.0.0.100)が「router.webtest01.com」のIPアドレスは10.0.0.254であると応答(2番目のパケット)を返している例です。

2つのパケットで完結しており、とてもシンプルであることがわかります。
しかし、さすがにここまで単純ではなく、これで終わりというわけではありません。上記のDNSパケットのキャプチャは、あくまで同じネットワーク上のDNSサーバーにより名前解決ができた場合の例です。

実際にインターネットを利用するときは、もっと段階を踏みます。

まず、クライアントは、あらかじめ設定してあるDNSサーバーへ問い合わせます。上記例ではここですぐに該当するリソースレコード(この場合はAレコード)が見つかっていますが、本来はそうはいきません。インターネットには様々なドメインがあるため、ほとんどの問い合わせは、設定したDNSサーバー自身には持ち合わせていない未知の情報の要求となります。

そこで、要求を受け取ったDNSサーバーは自身のサーバーに情報がない場合、ドメイン名を上位のレベルから下位のレベルに向かって問い合わせを続けながらサーバーを検索していきます。

DNSサーバーが要求されたドメインの情報を持っていなかった場合、まずルートDNSサーバーに問い合わせます。ルートDNSサーバーのNSレコードを手がかりに、名前解決要求されたドメインを管理しているDNSサーバーを探索します。NSレコードには次のレベルのドメインを管理するDNSサーバーについての情報が記述されています。

上図例のように、ブラウザのアドレスバーに「www.example.com」と入力した場合、まず初めに、トップレベルドメインの「com」を調べるために、ドメインの階層構造の頂点であるルートドメインのDNSサーバーに対して、comのドメインを管理するDNSサーバーについて問い合わせます。

問い合わせの回答にはNSレコードに、comのドメインを管理するDNSサーバーの名前が登録されています。

次に、問い合わせ先のDNSサーバーをcomのDNSサーバーに切り替えます。そして、「example」を調べるために、comのDNSサーバーのNSレコード検索します。すると、exampleのドメインを管理するDNSサーバーの名前が得られます。あとはそのDNSサーバーから「www.example.com」のIPアドレスを教えてもらえば完了です。

Cさん

DNSは、ルートDNSサーバーを頂点としたツリー構造になっていて、上から順番に探していくわけですね。ただ、そうだとすると一番上のルートDNSサーバーは問い合わせがたくさん来て大変なように思えます。

確かに、ルートDNSサーバーはDNS(ドメインネームシステム)の中核を担う非常に重要なサーバーであり、その構造上、負荷が集中しやすいと言えます。一度問い合わせた結果をキャッシュしておくなど、負荷軽減の仕組みはありますが、それでも問い合わせの数は膨大なため、トラフィックの負荷に対応できる高速で広帯域でのアクセスが可能な、複数の安全な場所に設置され、運用しています。

nslookupコマンドで実際にDNSを探ってみよう!

DNS(ドメインネームシステム)はパソコンとインターネットにつながる環境があれば簡単にその仕組みに触れることができます。早速、nslookupを使って体験してみましょう。
nslookupはWindowsコマンドのひとつでDNSによる名前解決を行うツールです。

例えば「www.google.co.jp」のIPアドレスを知りたいとき(つまりAレコードを知りたいとき)はコマンドプロンプトを起動し、以下のようにコマンドを実行します。

> nslookup www.google.co.jp

「www.google.co.jp」のIPアドレスが「172.217.26.35」だと分かります。ブラウザのアドレスバーに「http://172.217.26.35」と入力してアクセスしても、Googleのページが開きます。

権限のない回答とは

nslookupコマンドの実行結果に、「権限のない回答」と表示されています。この「権限のない回答」とは、問合せを受けたDNS サーバーが自分で「www.google.co.jp」の情報を管理しているわけではなく、「以前、他のDNSサーバーに問い合わせたらそういう回答だったよ」ということを示しています。

つまり、今回は、ルートDNSサーバーからたどって、「www.google.co.jp」を管理するDNSサーバーまで順に問い合わせたわけではなく、少し前に他の誰かが問い合わせた結果を、最初に問い合わせたDNSサーバーが保持(キャッシュ)しており、その情報をもらったということです。

SさんSさん

Googleのようにみんなが閲覧するサイトは、他の誰かが問い合わせているからもう一回わざわざ聞き直すことはしないということですね!

じゃあ、「権限のある回答」にするためにはどうすればいいの?

答えは簡単で、「www.google.co.jp」の情報を持っているDNSサーバーに直接問い合わせれば良いわけです。

ん?そもそも「www.google.co.jp」の情報を持っているDNSサーバーがわからないです。

DNSはIPアドレス、つまりAレコードだけしか問い合わせできないわけではありません。NSレコードも問い合わせることができます。NSレコードには、そのドメインを管理するDNSサーバーの名前が登録されています。
では、「google.co.jp」ドメインのNSレコード調べてみます。

> nslookup -type=ns google.co.jp

上記結果から、「216.239.34.10」などのDNSサーバーが「google.co.jp」に関するドメイン情報を保持していることが分かります。

では、問い合わせるDNSサーバーを指定して、nslookupコマンドを実行してみます。

> nslookup www.google.co.jp 216.239.34.10

今回は、「権限のない回答」と表示されません。これは、「google.co.jp」に関するドメイン情報を保持しているDNSサーバーに対して問い合わせているからです。

このように、nslookupコマンドによって、DNSサーバーから各種レコードを問い合わせることができます。使い方も簡単で、「nslookup -type=[レコードタイプ]」という書式により、知りたいレコードの情報を取得できます。「-type」オプションを省略すれば、IPアドレス指定ならAレコードが、FQDN指定ならPTRレコードを問い合わせることになります。

レコードの種類には [ A 、 MX 、 NS 、 PTR 、 SRV 、 TXT ] 等を指定できます。一度、迷惑にならない範囲で試してみてください。

DNSサーバーの種類

DNSサーバーには、DNSキャッシュサーバーとDNSコンテンツサーバー2つの種類があります。

DNSキャッシュサーバーは、クライアントから再帰問い合わせを受け付け、その結果をしばらくキャッシュします。通常、インターネット接続する際、プロバイダから付与されるDNSサーバーはこのキャッシュサーバーになります。(「ローカルサーバー」あるいは「フルリゾルバ」とも呼ばれます。)

対して、DNSコンテンツサーバーは、自身が管理するドメインを持つDNSサーバーになります。(ゾーン情報を持つことから「権威DNSサーバーとも呼ばれます。)

DNSキャッシュサーバーとDNSコンテンツサーバーを一台のDNSサーバーで兼用することもできますが、DNSの再帰的な問い合わせを使ったサービス不能攻撃(DNS amp攻撃)の踏み台にされることを防止する意味で、セキュリティ上、DNSサーバーをキャッシュサーバーとコンテンツサーバーで分離し、インターネット側からキャッシュサーバーに問い合わせできないようにするなどの対策を取ることが望ましいと言えます。

そのため、DNS問い合わせは自社内のPCなどの端末からしか受け付けないように制限するのが一般的です。