LinuxでDNSを使った名前解決やレコードのTTLを調べてみた

DNSについて調べてみたときのメモ。
間違っている部分などあればご指摘ください！

# 参考

+ [3分間DNS基礎講座](http://www.amazon.co.jp/3%E5%88%86%E9%96%93DNS%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-%E7%B6%B2%E9%87%8E-%E8%A1%9B%E4%BA%8C/dp/4774138630/ref=sr_1_1?s=books&ie=UTF8&qid=1453758989&sr=1-1&keywords=DNS)
+ [JPNIC DNSキャッシュ](https://www.nic.ad.jp/ja/newsletter/No51/0800.html)
+ [DNS導入に向けての予備知識 (2/3)](http://www.atmarkit.co.jp/ait/articles/0201/19/news001_2.html)

# 調査環境

+ AWSのVPC環境
+ AmazonLinux2015.09.01

# そもそも名前解決とは

名前解決とはドメイン名からIPアドレスへ変換を行うこと

Linuxだと大きく分けて以下の2種類の方法がある

+ /etc/hostsに自分で記述する
+ /etc/resolv.confにネームサーバー(DNS)のIPアドレスを指定し、DNSに問い合わせを行って名前解決してもらう


今回は下に書いたDNSについて主に調査、確認メモ

なお、`nslookup`コマンドで名前解決をする場合は`/etc/hosts`の内容は利用しないので注意。(pingでは/etc/hostsの内容は利用する)

[Why is my /etc/hosts file not queried when nslookup tries to resolve an address?](https://askubuntu.com/questions/627906/why-is-my-etc-hosts-file-not-queried-when-nslookup-tries-to-resolve-an-address)

# ネームサーバー(DNS)のIPアドレスを確認する

`/etc/resolv.conf`を確認する。

```bash
$cat /etc/resolv.conf
; generated by /sbin/dhclient-script
search ap-northeast-1.compute.internal
nameserver 172.31.0.2
```

`nameserver xxxxx`という部分が利用するネームサーバー。上記の場合、172.31.0.2にネームサーバーがあって名前解決をする場合には172.31.0.2に問い合わせを行う


# 実際に名前解決してみる

試しにドメイン「yahoo.co.jp」について問い合わせをしてみると以下のような感じ。

```bash
$nslookup yahoo.co.jp
Server:         172.31.0.2
Address:        172.31.0.2#53

Non-authoritative answer:
Name:   yahoo.co.jp
Address: 182.22.59.229
Name:   yahoo.co.jp
Address: 183.79.135.206
```

+ 問い合わせを行ったネームサーバーはIPアドレスが172.31.0.2(/etc/resolv.confと同じ)
+ yahoo.co.jpというドメインの名前解決の結果として「182.22.59.229」と「183.79.135.206」の2件のIPアドレスが返却された
+ 返却が「Non-authoritative answer」となっており、レコード情報を持っていないネームサーバーがキャッシュ情報から名前解決を行った
+ レコード情報を持っていないネームサーバー=172.31.0.2ということであり、キャッシュサーバーとして機能している

キャッシュを保持したり、クライアントとやりとりするネームサーバーはフルサービスリゾルバというらしい。また、レコード情報を持つサーバーはコンテンツサーバーというらしい。ネームサーバーでも大きく分けてこの2種類があって、今回の場合、フルサービスリゾルバ(172.31.0.2)がコンテンツサーバーに対して名前解決を既に行っており、その結果がキャッシュとして残っていて、その内容を返却した。


# コンテンツサーバーに問い合わせを行ってみる

実際にレコード情報を持つネームサーバー(コンテンツサーバー)に問い合わせてみる

まず、`yahoo.co.jp`ドメインの情報を管理しているネームサーバー（コンテンツサーバー）を確認する

digコマンドでドメインに対してNSレコードを要求することで確認できる

``` bash
$dig yahoo.co.jp ns

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.43.amzn1 <<>> yahoo.co.jp ns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4844
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;yahoo.co.jp.                   IN      NS

;; ANSWER SECTION:
yahoo.co.jp.            276     IN      NS      ns02.yahoo.co.jp.
yahoo.co.jp.            276     IN      NS      ns11.yahoo.co.jp.
yahoo.co.jp.            276     IN      NS      ns12.yahoo.co.jp.
yahoo.co.jp.            276     IN      NS      ns01.yahoo.co.jp.

;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Mon Jan 25 07:14:38 2016
;; MSG SIZE  rcvd: 105

```

ANSER SECTIONが問い合わせに対する回答。yahoo.co.jpというドメインを管理するネームサーバーは4台あるらしい。（その他の部分の説明は後述）

次にレコード情報を持つネームサーバーに直接名前解決してみる

```bash
$nslookup
> server ns01.yahoo.co.jp
Default server: ns01.yahoo.co.jp
Address: 118.151.254.133#53
> yahoo.co.jp
Server:         ns01.yahoo.co.jp
Address:        118.151.254.133#53

Name:   yahoo.co.jp
Address: 183.79.135.206
Name:   yahoo.co.jp
Address: 182.22.59.229
```
実際にレコード情報を持つサーバーに問い合わせを行って名前解決すると「Non-authoritative」という表示はなくなる（キャッシュサーバーからの返却ではないので）

digコマンドで@を使って問い合わせ先のネームサーバーを指定する事も可能で、上記と同様のことができる

```bash
$dig @ns01.yahoo.co.jp yahoo.co.jp
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.43.amzn1 <<>> @ns01.yahoo.co.jp yahoo.co.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5236
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 4
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;yahoo.co.jp.                   IN      A

;; ANSWER SECTION:
yahoo.co.jp.            300     IN      A       183.79.135.206
yahoo.co.jp.            300     IN      A       182.22.59.229

;; AUTHORITY SECTION:
yahoo.co.jp.            900     IN      NS      ns12.yahoo.co.jp.
yahoo.co.jp.            900     IN      NS      ns11.yahoo.co.jp.
yahoo.co.jp.            900     IN      NS      ns02.yahoo.co.jp.
yahoo.co.jp.            900     IN      NS      ns01.yahoo.co.jp.

;; ADDITIONAL SECTION:
ns01.yahoo.co.jp.       900     IN      A       118.151.254.133
ns02.yahoo.co.jp.       900     IN      A       118.151.254.149
ns11.yahoo.co.jp.       900     IN      A       124.83.255.37
ns12.yahoo.co.jp.       900     IN      A       124.83.255.101

;; Query time: 2 msec
;; SERVER: 118.151.254.133#53(118.151.254.133)
;; WHEN: Mon Jan 25 07:09:
```

`nslookup`だと実際の問い合わせの情報の一部しか表示されないが、`dig`コマンドだとDNSメッセージの情報が表示される。

+ QUESTION SECTION->問い合わせを行った内容。今回の場合、ドメインyahoo.co.jpのAレコードについて問い合わせ
+ ANSWER SECTION->QUESTION SECTIONへの回答。今回はAレコードの情報を返却
+ AUTHORITY SECTION->問い合わせを行ったドメイン(yahoo.co.jp)にのレコード情報を持つネームサーバーの情報(多くの場合、NSレコード)
+ ADDITIONAL SECTION->「ANSWER SECTION」と「AUTHORITY SECTION」にAレコードとCNAMEレコードが入っている場合に対応するAレコードを記述。今回の場合、AUTHORITY SECTIONにNSレコードが入っているので対応するAレコードの情報を返却
+ SERVER->問い合わせに対応したネームサーバー。キャッシュ情報が返却された場合にはキャッシュ情報を返却したネームサーバーのIPアドレスとなる

# レコードのキャッシュ時間、TTLを確認する

以下を参考にした

[DNSのキャッシュ時間とTTLをdig コマンドで調べる](http://takuya-1st.hatenablog.jp/entry/2014/07/17/160735)


レコードの残りキャッシュ時間とTTLは確認する場合、digコマンドを使う

```bash
$dig yahoo.co.jp

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.43.amzn1 <<>> yahoo.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59636
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;yahoo.co.jp.                   IN      A

;; ANSWER SECTION:
yahoo.co.jp.            298     IN      A       183.79.135.206
yahoo.co.jp.            298     IN      A       182.22.59.229

;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Mon Jan 25 07:27:41 2016
;; MSG SIZE  rcvd: 61

```

上記QUESTION SECTIONの **298** となっているのがキャッシュサーバーでの残りキャッシュ時間(sec)。時間経過とともに徐々に数字が少なくなっていき、0になった後、コンテンツサーバーに再度取得しにいく。コンテンツサーバーに取得後、レコードに設定されたTTLの時間をキャッシュ時間ととして設定する。つまり、

なお、キャッシュされるので例えばコンテンツサーバーでAレコードを削除してもキャッシュとして残っている場合にはドメインとIPアドレスの解決ができてしまう

```bash
$dig tmp.toshihirock.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.43.amzn1 <<>> tmp.toshihirock.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56602
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;tmp.toshihirock.com.           IN      A

;; ANSWER SECTION:
tmp.toshihirock.com.    245     IN      A       52.192.183.38

;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Mon Jan 25 07:43:57 2016
;; MSG SIZE  rcvd: 53

##### DNS(Route53)からAレコードを削除

# キャッシュが残って継続して名前解決できてしまう
$dig tmp.toshihirock.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.43.amzn1 <<>> tmp.toshihirock.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3273
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;tmp.toshihirock.com.           IN      A

;; ANSWER SECTION:
tmp.toshihirock.com.    195     IN      A       52.192.183.38

;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Mon Jan 25 07:44:47 2016
;; MSG SIZE  rcvd: 53
```

watchコマンドで差分を表示しつつ、継続確認するとキャシュ時間が0になるとANSWER SECTIONがなくなるのが分かる（名前解決できなくなる）

```bash
$watch -d -n 1 dig tmp.toshihirock.com

Every 1.0s: dig tmp.toshihirock.com                                                                                                                                                        Mon Jan 25 07:49:11 2016


; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.43.amzn1 <<>> tmp.toshihirock.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 59828
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;tmp.toshihirock.com.           IN      A

;; AUTHORITY SECTION:
toshihirock.com.        56      IN      SOA     ns-195.awsdns-24.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Mon Jan 25 07:49:11 2016
;; MSG SIZE  rcvd: 115
```

Aレコードの参照先IPアドレスを変える場合などは一旦TTLを小さくしてなるべくキャッシュに保存させないようにして、変更後、再度TTLを徐々に大きくしていくようにするらしい