DNS
インターネットの電話帳。名前を入れると、アドレスが出てくる。小さな 1 データグラムで。
質問
example.com の A レコードを尋ねる 29 バイトです。ASCII の行で文字が読み取れます。
フレーム全体
AB CD 01 00 00 01 00 00 00 00 00 00 07 65 78 61 6D 70 6C 65 03 63 6F 6D 00 00 01 00 01: 「example.com の IPv4 アドレスは?」を 29 バイトで尋ねます。1 つの UDP データグラムに収まる小ささです。
| フィールド | 位置 | 例の値 | 意味 |
|---|---|---|---|
| トランザクション ID | 0–1 バイト目 | 0xABCD | クライアントが選ぶ乱数で、応答にそのまま写されます。答えと質問の対応づけに使い、攻撃者がこれを推測する必要もあります。 |
| フラグ | 2–3 バイト目 | 0x0100 = query, recursion desired | 16 ビットの制御欄です。質問か応答か、オペコード、権威、切り詰め、再帰の要求/可否、応答コード。 |
| 質問数 | 4–5 バイト目 | 1 | 続く質問の数。ほぼ常に 1。 |
| 回答数 | 6–7 バイト目 | 0 | 続く回答レコードの数。質問では 0。 |
| 権威レコード数 | 8–9 バイト目 | 0 | 権威セクションのネームサーバレコード数(ここでは未使用)。 |
| 追加レコード数 | 10–11 バイト目 | 0 | 追加の補助レコード数(ここでは未使用)。 |
| ラベル長 | 12 バイト目 | 7 | 名前は「長さ + 文字列」のラベルの並びで格納します。'example' は 7 文字です。 |
| ラベル "example" | 13–19 バイト目 | example | ASCII の文字です。線上にドットはなく、example.com のドットは長さバイトに置き換わっています。 |
| ラベル長 | 20 バイト目 | 3 | 次のラベル。'com' は 3 文字です。 |
| ラベル "com" | 21–23 バイト目 | com | トップレベルドメインです。 |
| 名前の終端 | 24 バイト目 | 0 | 長さ 0 のラベルが名前の終わりです(ルートを表します)。 |
| クエリタイプ | 25–26 バイト目 | 1 = A | 欲しいレコードの種類。1 = A(IPv4 アドレス)、28 = AAAA(IPv6)、15 = MX(メール)、5 = CNAME、16 = TXT、2 = NS。 |
| クエリクラス | 27–28 バイト目 | 1 = IN | 1 = IN(インターネット)。ほかのクラスは歴史的なものです。 |
概要
DNS は、人が覚える名前(example.com)を、機械が使うアドレスに変換します。質問と答えは同じ二進レイアウトを共有します。12 バイトのヘッダ、続いて質問、続いて回答レコードです。たいていはポート 53 の UDP データグラム 1 つで運ばれます。
名前はドットではなく、長さ付きのラベル(7 'example' 3 'com' 0)で格納され、回答レコードはメッセージ内へのポインタで名前の繰り返しを避けます。
基本情報
- トランスポート
- UDP/53(大きな応答は TCP/53)
- ヘッダ
- 12 バイト
- ラベル上限
- ラベル 63 バイト、名前全体 253 バイト
- 主なタイプ
- A, AAAA, CNAME, MX, TXT, NS
- キャッシュ
- TTL に従い、リゾルバとクライアントで
- 規格
- RFC 1035
応答
質問がそのまま戻り、そのあとに、名前を繰り返さずポインタで指す回答レコードが続きます。
フレーム全体
応答は質問をそのまま繰り返し、回答レコードを 1 つ足します。「example.com は 203.0.113.50。300 秒覚えておいて」。
| フィールド | 位置 | 例の値 | 意味 |
|---|---|---|---|
| トランザクション ID | 0–1 バイト目 | 0xABCD | クライアントが選ぶ乱数で、応答にそのまま写されます。答えと質問の対応づけに使い、攻撃者がこれを推測する必要もあります。 |
| フラグ | 2–3 バイト目 | 0x8180 = response, recursion available, no error | 16 ビットの制御欄です。質問か応答か、オペコード、権威、切り詰め、再帰の要求/可否、応答コード。 |
| 質問数 | 4–5 バイト目 | 1 | 続く質問の数。ほぼ常に 1。 |
| 回答数 | 6–7 バイト目 | 1 | 続く回答レコードの数。質問では 0。 |
| 権威レコード数 | 8–9 バイト目 | 0 | 権威セクションのネームサーバレコード数(ここでは未使用)。 |
| 追加レコード数 | 10–11 バイト目 | 0 | 追加の補助レコード数(ここでは未使用)。 |
| ラベル長 | 12 バイト目 | 7 | 名前は「長さ + 文字列」のラベルの並びで格納します。'example' は 7 文字です。 |
| ラベル "example" | 13–19 バイト目 | example | ASCII の文字です。線上にドットはなく、example.com のドットは長さバイトに置き換わっています。 |
| ラベル長 | 20 バイト目 | 3 | 次のラベル。'com' は 3 文字です。 |
| ラベル "com" | 21–23 バイト目 | com | トップレベルドメインです。 |
| 名前の終端 | 24 バイト目 | 0 | 長さ 0 のラベルが名前の終わりです(ルートを表します)。 |
| クエリタイプ | 25–26 バイト目 | 1 = A | 欲しいレコードの種類。1 = A(IPv4 アドレス)、28 = AAAA(IPv6)、15 = MX(メール)、5 = CNAME、16 = TXT、2 = NS。 |
| クエリクラス | 27–28 バイト目 | 1 = IN | 1 = IN(インターネット)。ほかのクラスは歴史的なものです。 |
| 名前(ポインタ) | 29–30 バイト目 | 0xC00C → example.com | 名前の圧縮です。上位 2 ビットが 11 なら「ポインタ」で、名前はこのメッセージの 0x0C(12 バイト目)、つまり質問の中にあります。レコードごとに example.com を繰り返さずに済みます。 |
| タイプ | 31–32 バイト目 | 1 = A | この回答のレコードタイプ。A。 |
| クラス | 33–34 バイト目 | 1 = IN | IN。 |
| TTL | 35–38 バイト目 | 300 seconds | キャッシュがこの答えを保持してよい秒数です。300 秒 = 5 分。短い TTL は素早い変更に、長い TTL は負荷の軽減に向きます。 |
| データ長 | 39–40 バイト目 | 4 | 続くデータのバイト数。IPv4 アドレスは 4。 |
| アドレス | 41–44 バイト目 | 203.0.113.50 | 答えそのものです。このデモでの example.com の IPv4 アドレス(ドキュメント用アドレス)。 |
キャッシュ付きの名前解決
誰が誰に尋ね、答えがどこに記憶されるか。
やり取りの全体
質問が 1 つ、答えが 1 つ、TTL の間はキャッシュ。インターネット上の名前解決は、どれもこのような短い会話で、たいていは UDP で行われます。
1ノート PC がリゾルバに尋ねる
ノート PC は自分でインターネットを探しません。設定されたリゾルバ(ルータや ISP のことが多い)に尋ね、RD(再帰を要求)を立てます。
2リゾルバが持ち主に尋ねる
キャッシュにありません。実際にはリゾルバは、ルートサーバ、.com のサーバ、example.com 自身のネームサーバと 3 回続けて問い合わせます。ここでは 1 ステップにまとめて描いています。
3権威ある答え
ゾーンを持つサーバが、レコードと TTL を返します。AA は「権威ある回答」の印です。
4リゾルバがノート PC に答える
同じ答えを、RA を立てて中継します。以後 300 秒間は、このリゾルバに尋ねた人にキャッシュから即座に答えが返ります。
使われる場面
- あらゆる Web リクエストは DNS の名前解決から始まります
- メールの配送先(MX)、ドメイン所有の証明(TXT)、サービス探索(SRV)
- DNS over HTTPS/TLS は同じメッセージを暗号化して運びます
つまずきやすい点
- 「原因はいつも DNS」。変更したのに反映されない場面の多くは、古いキャッシュと TTL で説明がつきます。
- 普通の DNS は暗号化も認証もなく、トランザクション ID とポートだけがなりすましを防いでいます(DNSSEC は署名を足します)。
- 512 バイト(EDNS0 では 1232 バイト)を超える答えは 1 データグラムに収まらず、TCP にフォールバックします。
出典・規格
- RFC 1035: Domain Names - Implementation and Specification