ネームサーバ移行　〜虎の巻〜

仕事では幾度もやっているので、それっぽくナチュラルに個人サイトのもやった際、移設元のサービスの仕様の問題でDNS障害を引き起こしてしまいました。そこで、ネームサーバを移行する際に気をつけるべき事、また、それに関連する仕組みをまとめます。

## ネームサーバの移行って？
ドメインを取得している場合、 **WHOISでも見れるように、各ドメイン毎にネームサーバ（NSレコード）が設定されます。**例えばRoute53を使いたくなったとか、そういった場合にネームサーバを移行したくなる事があります。

このときの手続きそのものは、 **あらかじめ移行先のネームサーバに必要なレコードを登録した上で、ドメインの管理事業者側でネームサーバの変更手続きをするだけ**です。

## そもそもなんでネームサーバを移設したかったの？
低価格サービスではTTLの変更が出来ないことが多いです。TTLが変更できないと、レコードを書き換えてから反映完了するまでの時間が長くなるので、サーバ移設等でのサービス停止時間が長くなります。

まずは具体的なドメインでAレコードを見てみましょう。

```bash:dig_ameba_jp
$ dig ameba.jp

; <<>> DiG 9.8.3-P1 <<>> ameba.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16407
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ameba.jp.			IN	A

;; ANSWER SECTION:
ameba.jp.	1200	IN	A	180.233.142.60

;; Query time: 21 msec
;; SERVER: x.x.x.x#53(x.x.x.x)
;; WHEN: Sun Sep 15 10:11:23 2013
;; MSG SIZE  rcvd: 42
```

ANSWER SECTIONのINの左側にあるのがTTLです。このサンプルでは **TTLは1200になっているので、 クライアントは1回DNS問い合わせをしたら1200秒の間は再度問い合わせをしません。**なので、仮にこのサーバを移設しようとすると、1200秒の間は新旧いずれかのサーバに接続されてしまうことになります。タイミングがいいユーザは移設した瞬間に新しいサーバに接続しにいきますが、移設直前に接続しようとしていたユーザなんかは、1200秒丸々待たされる格好です。低価格サービスではこのTTLが比較的長めで取られているので都合が悪い訳です。

とはいえ、やるべきことははっきりしていて、Aレコードを変更（サーバ移転）する場合は、 **TTLの分だけメンテナンス時間を確保する**だけです。

で、このTTLをなんとかしたい場合は、ネームサーバを移転し、TTLが変更できるようにしておく必要があります。

## Aレコードとかじゃなくて、ネームサーバを移転する場合は？
世の中一般的にあるのは、 **伝播が完了するまで最大数日程度かかるので、新旧ネームサーバを並行稼働をさせる**というやつですよね。これでNGとなるケースはあまり無いので現実的にはこれでいいのですが、今回まずここではまりました。使っていた事業者は[某事業者](http://muumuu-domain.com)ですが、 **なんと、ネームサーバの向き先を変更した瞬間、旧ネームサーバ側のレコードが全て消去されました。**別に指定事業者を変更した訳ではないので、これは酷い仕打ちです。

なので、ネームサーバを移転するときにネームサーバそのものの管理権限を持っていない場合は、移設元のネームサーバが正しく動いているかを確認した方が良さそうです。ここではキャッシュを排除したいので、普段基本的に引かないであろうSOAレコードを引いてみます。

```bash:dig_to_old_nameserver
$ dig @old.dns-server.local ameba.jp SOA

; <<>> DiG 9.8.1-P1 <<>> ameba.jp soa
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28137
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ameba.jp.			IN	SOA

;; ANSWER SECTION:
ameba.jp.		1200	IN	SOA	ns01.ameba.jp. root.ns01.ameba.jp. 2013091001 10800 3600 604800 600

;; Query time: 16 msec
;; SERVER: x.x.x.x#53(x.x.x.x)
;; WHEN: Sun Sep 15 10:39:29 2013
;; MSG SIZE  rcvd: 72
```

この場合だと無事に動いていることになります。（厳密には、各レコードをDNSキャッシュをクリアした上で引くべき）
今回の某事業者のケースであれば、ここでレコードが返らないので、ここで気付けます。消えちゃってる場合は、なんとか旧ネームサーバを直しましょう。それ以外に方法ないので。


## 急いで切り戻しをしたけど繋がらないんだけど
すぐに気付ければ実質的に問題にならないですが、少し時間が経ってしまった場合はこれになります。新旧ネームサーバはちゃんと動くようにしたんだけれど、それでも繋がらない。この時の原因は **ネガティブキャッシュ**です。つまり、そのFQDNが存在しないことをキャッシュしちゃってます。
これそのものは、ネガティブキャッシュを削除してもらう他ないのですが、これがどれくらいなのかは先に挙げたSOAレコードに書かれていますので、知ることが出来ます。

```bash:soa_answer
ameba.jp.       1200    IN  SOA ns01.ameba.jp. root.ns01.ameba.jp. 2013091001 10800 3600 604800 600
```
一番後ろの数字の並びがそれで、一番最後の600がネガティブキャッシュです。なので、このケースだと600秒間は、問い合わせに失敗（存在しないレコードを検索）したら、再問い合わせを行いません。ちなみに他の3つのものは、DNSサーバ内で使うもの（スレーブサーバ）なので、ユーザから見るとほぼほぼ関係ありません。

なので、移設前にSOAレコードのネガティブキャッシュを小さくしておくのは有効ですが、SOAレコード自体にもTTLがあるので（この場合はINの左の1200）それ以上の時間の余裕を持って、事前対処しておく必要があります。

## うまくいってるみたいだけど、いつまで新旧並行？
**数日待ちましょう**ではなくて、ちゃんと調べることが出来ます。

まずは使っているドメインのルートサーバを確認します。

```bash:dig_root_server
$ dig jp ns

; <<>> DiG 9.8.3-P1 <<>>  jp ns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51643
;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;jp.				IN	NS

;; ANSWER SECTION:
jp.			21600	IN	NS	g.dns.jp.
jp.			21600	IN	NS	f.dns.jp.
jp.			21600	IN	NS	e.dns.jp.
jp.			21600	IN	NS	a.dns.jp.
jp.			21600	IN	NS	d.dns.jp.
jp.			21600	IN	NS	c.dns.jp.
jp.			21600	IN	NS	b.dns.jp.

;; Query time: 89 msec
;; SERVER: x.x.x.x#53(x.x.x.x)
;; WHEN: Sun Sep 15 10:58:31 2013
;; MSG SIZE  rcvd: 136
```

どれでもいいので、そこに対象ドメインのNSレコードを問い合わせます。

```bash:dig_to_root_server
$ dig @g.dns.jp ameba.jp ns

; <<>> DiG 9.8.3-P1 <<>> @g.dns.jp ameba.jp ns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43740
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;ameba.jp.			IN	NS

;; AUTHORITY SECTION:
ameba.jp.		86400	IN	NS	ns1-168.akam.net.
ameba.jp.		86400	IN	NS	use3.akam.net.
ameba.jp.		86400	IN	NS	eur5.akam.net.
ameba.jp.		86400	IN	NS	usw2.akam.net.
ameba.jp.		86400	IN	NS	use5.akam.net.
ameba.jp.		86400	IN	NS	usc4.akam.net.
ameba.jp.		86400	IN	NS	ns1-16.akam.net.
ameba.jp.		86400	IN	NS	use1.akam.net.

;; Query time: 8 msec
;; SERVER: 203.119.40.1#53(203.119.40.1)
;; WHEN: Sun Sep 15 11:02:01 2013
;; MSG SIZE  rcvd: 191
```

ここで出てくるTTL（INの左）がネームサーバを変更した場合に待たされる時間です。このケースだと **86400秒（1日）がネームサーバを移転した場合に伝播しきるまでに必要な時間**になります。この数字で注意しないといけないのは、これを設定しているのは各ドメイン（.jpとか）のルートサーバ側なので、これを変更する手段はありません。

ちなみに、gtldドメインで同じ事をするとこのようになります。

```bash;dig_to_gtld_server
$ dig @h.gtld-servers.net amebame.com

; <<>> DiG 9.8.3-P1 <<>> @h.gtld-servers.net amebame.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48223
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 11
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;amebame.com.			IN	A

;; AUTHORITY SECTION:
amebame.com.		172800	IN	NS	usw2.akam.net.
amebame.com.		172800	IN	NS	use1.akam.net.
amebame.com.		172800	IN	NS	ns1-16.akam.net.
amebame.com.		172800	IN	NS	ns1-168.akam.net.
amebame.com.		172800	IN	NS	use3.akam.net.
amebame.com.		172800	IN	NS	usc4.akam.net.
amebame.com.		172800	IN	NS	eur5.akam.net.
amebame.com.		172800	IN	NS	use5.akam.net.

;; ADDITIONAL SECTION:
usw2.akam.net.		172800	IN	A	184.26.161.64
use1.akam.net.		172800	IN	A	72.246.46.2
ns1-16.akam.net.	172800	IN	A	193.108.91.16
ns1-16.akam.net.	172800	IN	AAAA	2600:1401:2::10
ns1-168.akam.net.	172800	IN	A	193.108.91.168
ns1-168.akam.net.	172800	IN	AAAA	2600:1401:2::a8
use3.akam.net.		172800	IN	A	204.2.179.179
usc4.akam.net.		172800	IN	A	96.6.112.196
eur5.akam.net.		172800	IN	A	23.74.25.64
use5.akam.net.		172800	IN	A	2.16.40.64
use5.akam.net.		172800	IN	AAAA	2600:1401:1::64

;; Query time: 415 msec
;; SERVER: 192.54.112.30#53(192.54.112.30)
;; WHEN: Sun Sep 15 11:05:25 2013
;; MSG SIZE  rcvd: 406
```

こちらは172800秒（2日）となっています。

だから、世の中的にはDNSが伝播するまで数日かかると言われ、実際にそういう挙動を示すわけです。


## まとめ
というわけで、ネームサーバ移行時のポイント

- 新旧ネームサーバに同じ設定を入れる
- 移行後に改めて新旧双方の稼働をちゃんと確認する
- それでも事故ったら切り戻し１択
- （可能なら）SOAのネガティブキャッシュは事前に小さくしておく
- 完了までの期間は実はルートサーバで見れる