logo
Published on

DNS

Authors

はじめに

この記事では、DNSの基本概念・名前解決の仕組み・DNSリソースレコード・digコマンドを用いた動作確認方法を解説します。

対象読者は、DNSに自信のないバックエンドエンジニアです。
DNSの設定内容の把握や、DNSに起因する不具合の原因特定に役立つはずです。

Table of Contents

DNSとは

DNS(Domain Name System)とは、Webサイトの「ドメイン名」と、インターネット上の住所にあたる「IPアドレス」を結びつける仕組みです。
よく「インターネット上の住所録」に例えられます。

本来、コンピューターはIPアドレスという数字の羅列で通信相手を識別しますが、人間には覚えにくいため、代わりに分かりやすいドメイン名(例: example.com)が使われています。

かつて、この対応関係は「HOSTSファイル」という一つのファイルで管理されていました。
しかし、インターネットが巨大化すると、一つのファイルで全てを管理することに限界がきます。

そこで、情報を階層構造にして世界中のサーバーで分散管理する、現在のDNSが開発されました。
この階層的・分散的な仕組みにより、膨大な数のドメイン名を効率的に管理できるのです。

それでは、どのようにドメイン名からIPアドレスを調べているのか、具体的な仕組みを見ていきましょう。

名前解決

名前解決とは、ドメイン名からIPアドレスを調べる一連の作業のことです。

構成要素

名前解決は、主に以下の3つの構成要素が連携して行われます。

  • スタブリゾルバー: PCやスマホのブラウザなどに組み込まれている機能です。名前解決要求1をフルリゾルバーに出します。
  • フルリゾルバー: スタブリゾルバーから依頼を受け、IPアドレスを実際に探しに行きます。目的のIPアドレスが見つかるまで、後述の権威サーバーへ問い合わせを繰り返します。一度調べた結果は一時的にキャッシュしておくため、同じ依頼が来た際はすぐに回答できます。
  • 権威サーバー: 特定のゾーン2のドメイン名とIPアドレスの対応情報を公式に管理しているサーバーです。フルリゾルバーからの問い合わせに対し、管理している情報の中から正しいIPアドレスを答えます。

名前解決の流れ

example.jpというドメイン名を名前解決する場合の流れを解説します。

名前解決の流れ
  1. スタブリゾルバーがフルリゾルバーに名前解決要求
  2. フルリゾルバーがルートサーバーに問い合わせ
    • DNSの階層構造の最上位にあるルートサーバーに対して、example.jpのIPアドレスを問い合わせます。
  3. ルートサーバーから.jpの権威サーバーへの案内を応答
    • ルートサーバーはexample.jpのIPアドレスを知らないので、.jpドメインの管理を委任されているTLD権威サーバーの情報をフルリゾルバーに応答します。
  4. フルリゾルバーがjpの権威サーバーに問い合わせ
    • ルートサーバーから教えてもらった.jpの権威サーバーに対して、再度example.jpのIPアドレスを問い合わせます。
  5. .jpの権威サーバーからexample.jpの権威サーバーへの案内を応答
    • .jpの権威サーバーはexample.jpのIPアドレスを知らないので、example.jpドメインの管理を委任されている権威サーバーの情報をフルリゾルバーに応答します。
  6. フルリゾルバーがexample.jpの権威サーバーに問い合わせ
    • .jpの権威サーバーから教えてもらったexample.jpの権威サーバーに対して、再度example.jpのIPアドレスを問い合わせます。
  7. example.jpの権威サーバーからexample.jpのIPアドレスを応答
    • example.jpの権威サーバーはexample.jpのIPアドレスを知っているので、example.jpに対応するIPアドレスをフルリゾルバーに応答します。
  8. フルリゾルバーがスタブリゾルバーにIPアドレスを返答
    • 同時に、フルリゾルバーはこのIPアドレス情報をキャッシュします。これにより、次回同じドメイン名への名前解決要求があった際に、ルートサーバーなどへの問い合わせを繰り返すことなく、迅速に情報を提供できるようになります。

ここまでで名前解決の仕組みを解説しました。
次に、権威サーバーが実際に管理している情報の形式について説明します。

DNSリソースレコード

DNSリソースレコードとは、ドメイン名に対応するIPアドレスなどの情報を示すためのデータ形式です。
基本的なフォーマットはドメイン名 TTL クラス タイプ データです。

  • ドメイン名: 問い合わせで指定したドメイン名です。
  • TTL: Time To Liveの略です。そのリソースレコードをキャッシュしてよい時間を秒単位で指定します。省略可能です。
  • クラス: ネットワークの種類です。インターネットを意味する「IN」がデフォルト値であり、省略可能です。
  • タイプ: 情報の種類です。どんな情報が知りたいかによって、ここの内容が変わります。
  • データ: クラスとタイプによって異なる、リソースレコードのデータです。
記述例
example.jp. 3600 IN A 192.0.2.1

タイプごとにもう少し詳しく見ていきましょう。

SOAリソースレコード

ゾーン頂点3に設定されるゾーンそのものに関する情報を示すリソースレコードです。
フォーマットはドメイン名 TTL IN SOA MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUMです。

  • MNAME: そのゾーンのプライマリサーバーのホスト名です。
  • RNAME: そのゾーンの管理者のメールアドレスです。「@」を「.」に置き換えたものを設定します。
  • SERIAL: ゾーンデータのシリアル番号です。セカンダリサーバーはこの値を見て、ゾーン転送を要求してゾーンデータを更新するかどうかを判断します。
  • REFRESH: ゾーンデータの更新を自発的に始めるまでの時間です。
  • RETRY: ゾーンデータの更新が失敗した際に、再度更新を試みるまでの時間です。
  • EXPIRE: ここで設定した時間をかけてもゾーンデータの更新が失敗した場合、持っているゾーンデータを期限切れにします。
  • MINIMUM: ネガティブキャッシュ4を保持してよい時間です。
記述例
example.jp. IN SOA ns1.example.jp. admin.example.jp. 2025061101 3600 900 604800 3600

NSリソースレコード

委任に関する情報を示すリソースレコードです。
具体的には権威サーバーのホスト名を指定します。
フォーマットはドメイン名 TTL IN NS 権威サーバーのホスト名です。

example.jpゾーンにおける記述例を示します。
ここで、sales.example.jpというサブドメインを作って委任しているとします。

記述例
example.jp.           IN NS ns1.example.jp.
example.jp.           IN NS ns2.example.jp.
ns1.example.jp.       IN A  192.0.2.11
ns2.example.jp.       IN A  198.51.100.21
sales.example.jp.     IN NS ns1.sales.example.jp.
sales.example.jp.     IN NS ns2.sales.example.jp.
ns1.sales.example.jp. IN A  192.0.2.31            ; グルーレコード
ns2.sales.example.jp. IN A  198.51.100.41         ; グルーレコード

委任先の権威サーバーのホスト名が委任先のゾーンのものである場合、NSリソースレコードに加えてそのIPアドレスを示すA/AAAAリソースレコードをグルーレコードとして設定する必要があります。
ns*.example.jp.は自分のゾーンの情報なので、対応するA/AAAAリソースレコードはグルーレコードではありません。

A/AAAAリソースレコード

ドメイン名とIPアドレスとの対応を示すリソースレコードです。
AリソースレコードはIPv4アドレスを、AAAAリソースレコードはIPv6アドレスを示します。
フォーマットはドメイン名 TTL IN A/AAAA IPv4アドレス/IPv6アドレスです。

記述例
www.example.jp. IN A    192.0.2.1
www.example.jp. IN AAAA 2001:db8::1

Webサイトを公開するときなどに使います。

CNAMEリソースレコード

ドメイン名の正式名を示すリソースレコードです。
フォーマットはドメイン名 TTL IN CNAME 正式名です。

記述例
www.sales.example.jp. IN CNAME cdn.example.com.

CDNなど外部サービスを自社ドメイン名で使うときなどに使います。

ちなみに、以下の点に注意が必要です。

  • CNAMEリソースレコードを設定したドメイン名には、CNAME以外のリソースレコードを設定してはならない。
  • あるドメイン名に複数のCNAMEリソースレコードを設定してはならない。

MXリソースレコード

そのドメイン名を宛先とするメールの配送先のメールサーバーを示すリソースレコードです。
フォーマットはドメイン名 TTL IN MX 優先度 メールサーバーのホスト名です。
優先度は数値で指定し、小さいほど優先度が高くなります。

記述例
example.jp. IN MX 10 mx1.example.jp.
example.jp. IN MX 20 mx2.example.jp.
mx1.example.jp. IN A 192.0.2.2
mx2.example.jp. IN A 192.0.2.3

メールアドレスを使えるようにするときなどに使います。

TXTリソースレコード

ドメイン名に対応する文字情報を示すリソースレコードです。
フォーマットはドメイン名 TTL IN TXT 任意の文字列です。

記述例
example.jp.        IN TXT "EXAMPLE Co., Ltd."                             ; 会社名
example.jp.        IN TXT "v=spf1 +mx -all"                               ; SPF
_dmarc.example.jp. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.jp" ; DMARC

なりすましメール対策などに使います。

ここまでで、DNSリソースレコードの種類と記述方法を解説しました。
次に、実際にDNSの動作状況を確認するためのツールであるdigコマンドについて説明します。

digコマンド

digコマンドはDNSの動作状況を確認するツールです。
フォーマットはdig [オプション] [@サーバー] ドメイン名 [タイプ] [クラス]です。

  • オプション: オプションを指定します。
  • @サーバー: 問い合わせ先のサーバー(権威サーバーやフルリゾルバーなど)をドメイン名またはIPアドレスで指定します。省略するとシステムに設定されているフルリゾルバーを使います。
  • ドメイン名: 問い合わせのドメイン名を指定します。
  • タイプ: 問い合わせのタイプを指定します。省略するとA(IPv4アドレス)が指定されます。
  • クラス: 問い合わせのクラスを指定します。省略するとIN(インターネット)が指定されます。

以下に出力例を示しますが、見方は後述です。

digコマンドの出力例
% dig @8.8.8.8 www.google.com IN A

; <<>> DiG 9.10.6 <<>> @8.8.8.8 www.google.com IN A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1277
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.google.com.			IN	A

;; ANSWER SECTION:
www.google.com.		266	IN	A	172.217.161.68

;; Query time: 18 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Jun 12 15:44:05 JST 2025
;; MSG SIZE  rcvd: 59

オプション

  • +recurseまたは+rec(デフォルト): 名前解決要求の有効化
  • +norecurseまたは+norec: 名前解決要求の無効化
  • +edns(デフォルト): EDNS05の有効化
  • +noedns: EDNS0の無効化
  • +dnssec: 問い合わせのDNSSEC OK(DO)ビット6をセット
  • +tcp: TCPで問い合わせ
  • +trace: ルートから委任情報をトレース
  • -x: 指定されたIPアドレスを逆引き用ドメイン名に変換
  • multilineまたはmulti: 複数行形式で出力

DNSメッセージ

DNSメッセージは、以下のようなセクションからなります。

  • Headerセクション: 各種制御情報を含むヘッダ部
  • Questionセクション: 問い合わせるドメイン名や、探す情報のタイプなど
  • Answerセクション: 応答データ
  • Authorityセクション: 権威サーバーの情報
  • Additionalセクション: 問い合わせや応答に追加される情報

Headerセクションに含まれる各種情報とその意味をまとめます。

  • ID: DNSトランザクションID。
  • QR: 問い合わせか応答かを示します。問い合わせが0、応答が1です。
  • OPCODE: 問い合わせの種類。通常の問い合わせが0、NOTIFYが4、UPDATEが5です。
  • AA: 応答で使われる。1なら管理権限を持つ応答であることを示します。
  • TC: 応答で使われる。1なら応答が切り詰められたことを示します。
  • RD: 0なら権威サーバーへの問い合わせ、1ならフルリゾルバーへの問い合わせ(名前解決要求)を示します。
  • RA: 名前解決要求を受け付けられることを示します。0なら非サポート、1ならサポート。
  • Z: 将来のために予約。常に0。
  • AD: 問い合わせ時に1なら、応答のADビットを理解できることを示します。応答時に1なら、DNSSEC検証が成功したことを示します。
  • CD: 問い合わせで使われる。1ならDNSSEC検証を無効にする。
  • RCODE: 応答コード。NOERROR(通常応答)、SERVFAIL(サーバー側の異常で名前解決に失敗した)、NXDOMAIN(いずれのリソースレコードも存在しない)、REFUSED(リクエストを拒否した)などがあります。
  • QDCOUNT: Questionセクションのレコード数で常に1です。
  • ANCOUNT: Answerセクションのリソースレコード数です。
  • NSCOUNT: Authorityセクションのリソースレコード数です。
  • ARCOUNT: Additionalセクションのリソースレコード数です。

出力を読み解く

上記出力例を読み解いてみましょう。

Headerセクションの出力例
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1277
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

statusflagが重要です。

statusには応答コードが入ります。

flagにはQR、RD、RAが入っています。
RDがあるのでフルリゾルバー(Google Public DNS)への名前解決要求が行われたこと、RAがあるので名前解決要求が可能であることがわかります。

Questionセクションの出力例
;; QUESTION SECTION:
;www.google.com.			IN	A

問い合わせのドメイン名とタイプがそのままコピーされています。

Answerセクションの出力例
;; ANSWER SECTION:
www.google.com.		266	IN	A	172.217.161.68

www.google.com.というドメイン名のAレコードが1つあり、IPアドレスが172.217.161.68であることがわかります。

digコマンドの基本的な使い方と出力の見方を理解したところで、実際にDNSサーバーの動作確認を行ってみましょう。

DNS動作確認

権威サーバーの動作確認

問い合わせのポイントは、+norecオプションを指定することです。
フルリゾルバーへの名前解決要求ではないので、名前解決要求を無効にする必要があるからです。

jprs.co.jpを管理する権威サーバー202.11.16.49に、jprs.co.jpのAリソースレコードを問い合わせてみます。

権威サーバーの動作確認
% dig +norec @202.11.16.49 jprs.co.jp A

; <<>> DiG 9.10.6 <<>> +norec @202.11.16.49 jprs.co.jp A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49462
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 9

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;jprs.co.jp.			IN	A

;; ANSWER SECTION:
jprs.co.jp.		300	IN	A	117.104.133.165

;; AUTHORITY SECTION:
jprs.co.jp.		86400	IN	NS	ns4.jprs.co.jp.
jprs.co.jp.		86400	IN	NS	ns3.jprs.co.jp.
jprs.co.jp.		86400	IN	NS	ns1.jprs.co.jp.
jprs.co.jp.		86400	IN	NS	ns2.jprs.co.jp.

;; ADDITIONAL SECTION:
ns1.jprs.co.jp.		86400	IN	A	202.11.16.49
ns2.jprs.co.jp.		86400	IN	A	202.11.16.59
ns3.jprs.co.jp.		86400	IN	A	203.105.65.178
ns4.jprs.co.jp.		86400	IN	A	203.105.65.181
ns1.jprs.co.jp.		86400	IN	AAAA	2001:df0:8::a153
ns2.jprs.co.jp.		86400	IN	AAAA	2001:df0:8::a253
ns3.jprs.co.jp.		86400	IN	AAAA	2001:218:3001::a153
ns4.jprs.co.jp.		86400	IN	AAAA	2001:218:3001::a253

;; Query time: 38 msec
;; SERVER: 202.11.16.49#53(202.11.16.49)
;; WHEN: Thu Jun 12 18:37:22 JST 2025
;; MSG SIZE  rcvd: 303

出力結果で確認する点は以下です。

  • Headerセクション
    • statusがNOERRORであること
    • 問い合わせされたドメイン名の情報に対する管理権限を持つことを示すAAビットがセットされていること
  • Answerセクションに目的のAリソースレコードがあること
  • Authorityセクションにjprs.co.jpの権威サーバーの正しいNSリソースレコードセットが設定されていること
  • Additionalセクションに権威サーバーのA/AAAAリソースレコードが設定されていること

次に、フルリゾルバーとして動作していないことを確認します。
問い合わせのポイントは、先ほどとは逆に+norecオプションを指定しないことです。

先ほどの権威サーバーが管理していないドメイン名www.google.comを問い合わせてみます。

フルリゾルバーとして動作していないことを確認
% dig @202.11.16.49 www.google.com A

; <<>> DiG 9.10.6 <<>> @202.11.16.49 www.google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 55170
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.google.com.			IN	A

;; Query time: 22 msec
;; SERVER: 202.11.16.49#53(202.11.16.49)
;; WHEN: Fri Jun 13 00:38:06 JST 2025
;; MSG SIZE  rcvd: 43

出力結果で確認する点は以下です。

  • Headerセクション
    • statusがREFUSEDであること
    • 名前解決要求を処理可能であることを示すRAビットが設定されていないこと

フルリゾルバーの動作確認

問い合わせのポイントは、+norecオプションを指定しないことです。
フルリゾルバーへの名前解決要求なので、名前解決要求を有効にする必要があるからです。

システムに設定されているフルリゾルバーに、www.google.comのAリソースレコードを問い合わせてみます。

フルリゾルバーの動作確認
% dig www.google.com A

; <<>> DiG 9.10.6 <<>> www.google.com A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26457
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.google.com.			IN	A

;; ANSWER SECTION:
www.google.com.		38	IN	A	142.250.196.132

;; Query time: 16 msec
;; SERVER: 240b:12:4241:5500:fab7:97ff:fe6d:c408#53(240b:12:4241:5500:fab7:97ff:fe6d:c408)
;; WHEN: Fri Jun 13 00:48:45 JST 2025
;; MSG SIZE  rcvd: 59

出力結果で確認する点は以下です。

  • Headerセクション
    • statusがNOERRORであること
    • 名前解決要求を処理可能であることを示すRAビットが設定されていること
  • Answerセクションに目的のAリソースレコードがあること

まとめ

  • DNSとはドメイン名とIPアドレスを結びつける仕組み
  • 名前解決とはドメイン名からIPアドレスを調べる一連の作業
  • DNSリソースレコードとはドメイン名に対応するIPアドレスなどの情報を示すためのデータ形式
  • digコマンドはDNSの動作状況を確認するツール
  • 権威サーバーとフルリゾルバーそれぞれに確認観点がある

参考文献

Footnotes

  1. 「私の代わりに名前解決をして、◯◯のIPアドレスを教えてください」という依頼のこと

  2. ドメイン名の管理単位のこと

  3. ゾーンカット(委任により分割されたゾーンの境目)のドメイン名

  4. 目的のリソースレコードが存在しなかったという結果のキャッシュ

  5. 「Extension Mechanisms for DNS 0」の略で、DNSメッセージがUDPの512バイトの制限を超えるような大きなサイズを扱えるようにするための仕組みです。

  6. DNSSEC(DNSサーバーからの応答の真正性と完全性を検証するための拡張メカニズム)対応のクエリを発行するためのフラグです。