DNS(Domain Name System)は、インターネットで使われている名前とIPアドレスとの変換を行うプロトコルです。
IPはIPアドレスを使用して通信相手を特定しますが、数字の羅列であるIPアドレスを人間が覚えるのは大変です。一方、「www.google.jp」のような文字列であれば覚えやすいです。
例えば、Googleにアクセスしたとき、実アドレスである「74.125.153.103」をブラウザのアドレスバーに直接入力する人はいないと思います。「www.google.jp」などと入力するはずです。
クライアントはこの名前をDNSサーバーに問い合わせ、対応するIPアドレスを取得します。その結果、ユーザーはIPアドレスを意識せずコンテンツを閲覧できるというわけです。
簡単に書いていますが、これはかなりすごいことです。例えば、上記のようにWebページを閲覧する場合、巨大なインターネット上からユーザーを待たせることなく瞬時にIPアドレスを探しだす必要があるからです。
DNSの仕組み
PCからの要求にもとづいて、DNSサーバーが世界規模で分散されたテキストデータベースに記録されているレコードを探索して、ホスト名+ドメイン名※とIPアドレスとの変換を行います。このことを名前解決と言います。
※下図例では「www」がホスト名、「sample.com」がドメイン名となります。また、ホスト名+ドメイン名をFQDNと呼びます。
DNSサーバーは、データベースとして「リソースレコード」と呼ばれるテキストデータを持ちます。代表的なリソースレコードして以下があります。
リソースレコードの種類 | 説明 |
---|---|
SOA(Start Of Authority) | ゾーン全体の基本情報を記述。具体的には、DNSサーバーの管理情報、設定番号(シリアル値)、スレーブサーバーの更新間隔、ゾーン転送が失敗したときの再実行間隔、リソースレコードの有効期限など、そのドメインの管理情報を記述する。 |
A(Adress) | DNS正引きで利用するホスト名→IPアドレスの関係を登録。 |
MX(Mail eXchange) | メールサーバーのホスト名を登録。具体的には、ドメイン名ごとに転送先のメールサーバーと、その転送の優先度(プレファレンス)を対応させる。優先度の値が小さい順にメールが優先的に転送される。 |
CNAME(Canonical NAME) | ホスト名の別名(エイリアス)を登録。 |
NS(Name Server) | ゾーン情報を管理するDNSサーバーを登録。そのゾーン自身や下位ドメインのゾーン情報が定義されているDNSサーバーのホスト名を指定する。 |
PTR(Pointer) | DNS逆引きで利用するIPアドレス→ホスト名の関係を登録。 |
TXT(Text) | ドメインやホスト名の付加情報を記述。SPFにも利用される。 |
AAAA(quad A) | IPv6用のAレコード |
DNSパケットのキャプチャ
DNSの名前解決は非常にシンプルで、たいていの場合2つのパケットで事足ります。
最初のパケットは、「www.google.jpのIPアドレスは何ですか?」というDNSサーバーへの名前解決の要求です。
2つ目は「www.google.jpのアドレスはXXX.XXX.XXX.XXXです」というDNSサーバーからの応答です。
このように、DNSは、要求とその応答の2つのパケットで事足りる、とてもシンプルなプロトコルです。
では、実際にDNSパケットの例を見てみます。以下は「router.webtest01.com」というFQDNの名前解決要求(1番目のパケット)に対して、DNSサーバー(10.0.0.100)が「router.webtest01.com」のIPアドレスは10.0.0.254であると応答(2番目のパケット)を返している例です。
DNSクエリ要求パケットの詳細部についても見てみます。(なお、パケット構成は環境(DNSサーバーの種類やOS)によって異なるため、自身でキャプチャしたパケットと構成が異なっていることもあります。)
「Transaction ID」フィールドは、問い合わせを区別する識別子が2バイトで表示されます。DNSクエリ要求、DNSクエリ応答パケットで共通の値が格納されます。
「Flags」は、DNSの制御を行うためのフィールドです。
1ビット目の部分のフラグは「QR」ビットと呼ばれ、「0」であれば、DNSクエリ要求、「1」であればDNSクエリ応答であることを示します。上記例ではクエリ要求パケットのため、「0」が入っています。
2ビット目の「Opcode」は、問い合わせの種類を4ビットで示します。
0:標準の問い合わせ、1:逆の問い合わせ、2:サーバーの状態を要求 等
次の「Truncated」は「TC」と呼ばれ、メッセージが切断されて分割しているかどうかを1ビットで示します。上記例では、「0」が入っているため、分割されていないことがわかります。
次の「Recursion desired」の1ビットは「RD」ビットと呼ばれ、再帰問い合わせを行う場合にオンになります。(再帰問い合わせについてはこの後で説明します。)
「Z」は予約済みの1ビットで、0が入ります。
「Queries」フィールドは問い合わせ部になります。このフィールドはクエリ要求、クエリ応答ともに共通となります。上記例では、「router.webtest01.com: type A, class IN」となっています。
「router.webtest01.com」の部分は問い合わせを行う名前になります。次の「type A」は、問い合わせの種類がA(Address)レコードであることを示します。以下はtype値と問い合わせるレコードの種類の対応表になります。
type値 | 問い合わせるレコードの種類 |
---|---|
1 | A(Adress)レコード |
2 | NS(Name Server)レコード |
5 | CNAME(Canonical NAME)レコード |
6 | SOA(Start Of Authority)レコード |
120 | PTR(PoinTeR)レコード |
121 | HINFO(Hardware INFOrmation)レコード |
123 | MX(Mail eXchanger)レコード |
125 | AAAA(IPv6 Address)レコード |
次の「class IN」は、DNS問い合わせ対象ドメインを16ビットで示します。
class値 | 問い合わせ対象(ドメイン) |
---|---|
1 | Internet(インターネット) |
2 | CSNET(Computer Science NETwork)(米国NSFのネットワーク) |
DNSはインターネット以外にも拡張可能となるよう設計されているため、様々なclass値が利用される前提となっていますが、実際は、インターネットのドメインの問い合わせであることを示すクラス1が登録されるケースに限られます。
DNSの動作
上記のDNSパケットのキャプチャは、あくまで同じネットワーク上のDNSサーバーにより名前解決ができた場合の例です。
実際にインターネットを利用するときは、もっと段階を踏みます。
まず、クライアントとなるPC(リゾルバ)は、あらかじめ設定してあるDNSサーバーへ問い合わせます。上記例ではここですぐに該当するリソースレコード(この場合はAレコード)が見つかっていますが、本来はそうはいきません。インターネットには様々なドメインがあるため、ほとんどの問い合わせは、設定した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サーバーの名前が得られます。
再帰問い合わせと反復問い合わせ
上述のように、NSレコードを用いて上位レベルのドメインから下位レベルのドメインへと次々にリレーしながら答えを得られるまで繰り返します。このひとつひとつの問い合わせを「反復問い合わせ」と言います。
この反復問い合わせにより、最終目的であるexampleドメインを管理するDNSサーバーを見つけたら、そのDNSサーバーのリソースレコードには「www」というホスト名に対応するIPアドレスが記録されているはずであり、DNS名前解決をしてもらうという流れです。
DNSの名前解決方法には反復問い合わせの他に再帰問い合わせがあります。
再帰問い合わせは、クライアントとなるPC(リゾルバ)からの問い合わせ要求を受けたDNSサーバーが、他のDNSサーバーに問い合わせを行いその最終的な結果をリゾルバに応答する必要のある問い合わせのことです。「再帰」という言葉どおり、問い合わせた結果が「再び帰ってくる」というのがポイントです。
反復問い合わせは最終回答を探すための問い合わせであり、再帰問い合わせは最終的な回答を返す問い合わせとなります。
DNSサーバーの種類
DNSサーバーには、DNSキャッシュサーバーとDNSコンテンツサーバー2つの種類があります。
DNSキャッシュサーバーは、クライアントから再帰問い合わせを受け付け、その結果をしばらくキャッシュします。通常、インターネット接続する際、プロバイダから付与されるDNSサーバーはこのキャッシュサーバーになります。(「ローカルサーバー」あるいは「フルリゾルバ」とも呼ばれます。)
対して、DNSコンテンツサーバーは、自身が管理するドメインを持つDNSサーバーになります。(ゾーン情報を持つことから「権威DNSサーバーとも呼ばれます。)
DNSキャッシュサーバーとDNSコンテンツサーバーを一台のDNSサーバーで兼用することも多くありますが、DNSの再帰的な問い合わせを使ったサービス不能攻撃(DNS amp攻撃)の踏み台にされることを防止する意味で、セキュリティ上、DNSサーバーをキャッシュサーバーとコンテンツサーバーで分離し、インターネット側からキャッシュサーバーに問い合わせできないようにするなどの対策を取ることが望ましいと言えます。