忘れそうな DNS めも

はじめに

使える力が身に付く DNS がよくわかる教科書を読んだので、軽く自分が知らなかった点、忘れそうな点を残します。 DNS についてはネットワークスペシャリストや色々な教科書等で勉強はしていたものの、意外と知らない部分がありとても勉強になりました。

プライミング - フルサービスリゾルバはどのようにルートサバーの IP アドレスを知るか

フルサービスリゾルバによる権威 DNS サーバーへの反復問い合わせをするには、ルートの権威サーバー(.)の IP アドレス事前に知っている必要があります。 そのため、フルサービスリゾルバは、ヒントファイルと呼ばれる、ルートの権威サーバーの IP アドレス一覧を予め持っています。 これを使い、ルートの権威サーバーにルートの権威サーバーの NS レコードを問い合わせ、最新のルートの権威サーバーの情報を取得します。 上記 NS レコードの取得までの動作はプライミングと呼ばれます。 なお、ヒントファイルは次の URL で公開されています。

https://www.internic.net/domain/named.root

SOA レコード

@ IN SOA (
    ns1.example.jp. ; MNAME
    postmaster.example.jp. ; RENAME
    2003081901  ; SERIAL
    3600        ; REFRESH
    900        ; RETRY
    604800     ; EXPIRE
    3600      ; MINIMUM
    ) 

ゾーン転送

プライマリからスレーブへのゾーン転送はプライマリからの push とスレーブからの pull 両方のパターンがあります。

プライマリのゾーンデータが更新されると、プライマリからスレーブへ DNS NOTIFY と呼ばれる通知が行われます(インバウンド 53 番ポート)。 スレーブはこれを受け、プライマリに SOA レコードを問い合わせます。得られた SOA レコードの SERIAL が自身の値より大きい場合、更新されていると判断し、スレーブからプライマリへゾーン転送要求を行います。 これが push 型です。

一方で、pull 型は、SOA レコードの REFRESH の値を元に行います。 スレーブでは保持している SOA レコードの REFRESH の値を確認し、この値が経過している場合、自発的にプライマリへレコードの更新を確認します(SOA レコードの SERIAL の値の確認)。

EDNS0

DNS の通信は UDP で扱われますが、512 バイトを越えると TCP にフォールバックします。 EDNS0 は 512 バイトを超えた場合にも UDP で通信するために拡張機能です。

MTU の値よりデータが大きい場合、フラグメント化しますので、性能やデータの欠損が発生する可能性は否定できません。

EDNS0 の有効化(ヒントファイルを元に行われるプライミングを模倣) UDP で 4096 バイトまでを許容し、結果 811 バイトのレスポンスを取得している

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
$ dig +edns +norec @202.12.27.33 ns

; <<>> DiG 9.10.6 <<>> +edns +norec @202.12.27.33 ns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37250
;; flags: qr aa; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 27

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;.                              IN      NS

;; ANSWER SECTION:
(snip)

;; Query time: 9 msec
;; SERVER: 202.12.27.33#53(202.12.27.33)
;; WHEN: Sat Nov 09 11:23:56 JST 2019
;; MSG SIZE  rcvd: 811

グルーレコード

フルサービスリゾルバによる反復問い合わせの際に取得した NS レコードの A レコードが必要となる。 次のような場合、jprs.co.jp.ns1.jprs.co.jp. に委任されているとわかる。 このため、次には ns1.jprs.co.jp. に 対して問い合わせを行うことになるが、ns1.jprs.co.jp. の IP アドレスが必要となる。 しかし、ns1.jprs.co.jp. は、jprs.co.jp. の一部(サブドメイン)となるので、ns1.jprs.co.jp. の A レコードも自身が管理していることとなる。 結果、無限ループとなる。 NS レコードのドメインが取得したいドメインのサブドメインとなる構成を内部ドメインと呼ぶ。 内部ドメインでは DNS は ADDITIONAL SECTION に ns1.jprs.co.jp. の IP アドレスを付与してくれているのでこの値を信じて使用する。 ネームサーバの名前に対応する IP アドレスの情報をグルーレコードと呼ぶ。

ただし、NS レコードが内部ドメインでない場合、その値は信用できない(権威がないので)、その NS レコードに対してルートから名前解決を実施する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ dig @a.dns.jp jprs.co.jp A

; <<>> DiG 9.10.6 <<>> @a.dns.jp a jprs.co.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3227
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 9
;; WARNING: recursion requested but not available

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

;; AUTHORITY SECTION:
jprs.co.jp.             86400   IN      NS      ns1.jprs.co.jp.
jprs.co.jp.             86400   IN      NS      ns4.jprs.co.jp.
jprs.co.jp.             86400   IN      NS      ns2.jprs.co.jp.
jprs.co.jp.             86400   IN      NS      ns3.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: 9 msec
;; SERVER: 203.119.1.1#53(203.119.1.1)
;; WHEN: Sat Nov 09 11:37:07 JST 2019
;; MSG SIZE  rcvd: 287

dig のフラグオプション

フルサービスリゾルバに名前解決を依頼する(再起問合せをする)場合は、+recurse を付与する(デフォルト有効)。 再起問合せ可能であれば、レスポンスに RA ビットがセットされる。
一方で、権威 DNS サーバーに問い合わせる際には、+norecurse を付与する。 権威 DNS サーバーであれば、レスポンスに AA ビットがセットされる。

DNS ヘッダーのフラグについて - dig コマンドの結果

参考:

These bits are allocated from the must-be-zero Z field as follows:

                                     1  1  1  1  1  1
       0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                      ID                       |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    QDCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    ANCOUNT                    |>
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    NSCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |                    ARCOUNT                    |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+