先日、ioドメインの障害があったのだけど、自分がDNSの仕組みをよく分かっていないせいで、いまいちどういうことが起こっていたのか把握できなかった。そこで、DNSの仕組みについて軽く勉強したので、そのメモを残しておく。内容は間違っているかもしれないので、その場合は指摘してください。
DNSについて学んだこと
Software Design 2015/4のDNSの教科書が非常に勉強になった。また、 インターネット10分講座:DNSキャッシュ - JPNICも参考になる。
権威サーバとフルリゾルバ
まず、DNSサーバには権威サーバとフルリゾルバの二つの種類が存在する。
- 権威サーバ
- フルリゾルバ
- 名前解決要求を受け取り、権威サーバに問い合わせ、委任情報を受け取りながら再帰的に名前解決を行うサーバ
- 名前解決結果のキャッシュの役割も同時に担うことが多い
- 例) Google Public DNS(8.8.8.8)
この二つの役割のサーバが連動して、ドメインの名前解決は行われている。
DNS問い合わせはたらい回しの仕組みで、再帰的に権威サーバに問い合わせしている
DNSの教科書によると、DNS問い合わせは以下のような流れで進むと書いてある。スタブリゾルバというのは、名前解決のための単なるクライアントライブラリととりあえず思っておけば良い。ルートDNSサーバ、TLD DNSサーバ、組織のDNSサーバが上記した権威サーバである。
- 1. アプリケーションから名前解決要求を受け取ったスタブリゾルバーは、フルリゾルバーにDNS問い合わせを送る
- 2. フルリゾルバーはルートDNSサーバの情報を事前に設定されているため、スタブリゾルバーからの問い合わせと同じ内容をルートDNSサーバに問い合わせる
- 3. ルートDNSサーバはTLDへの委任情報だけを知っているため、委任情報を返す
- 4. フルリゾルバーはルートDNSサーバから得た委任情報に従い、スタブリゾルバーからの問い合わせと同じ内容をTLD DNSサーバに問い合わせる
- 5. TLD DNSサーバは組織ドメイン名の委任情報だけを知っているため、委任情報を返す
- 6. フルリゾルバーはTLD DNSサーバから得た委任情報に従い、スタブリゾルバーからの問い合わせと同じ内容を組織のDNSサーバに問い合わせる
- 7. 組織のDNSサーバは、問い合わせに対応する応答をフルリゾルバーに返す
- 8. フルリゾルバーは名前解決ができたことを判定し、スタブリゾルバーにその結果を返す
https://www.nic.ad.jp/ja/newsletter/No51/0800.htmlから図を引用すると以下のような感じ。
つまり、名前解決をしようとすると、一番上位の権威サーバへ問い合わせて、それは自分のゾーン管理下にないからこっちに聞いてねとたらい回しにされて、さらに次に聞きに行って、それはこっちに聞いてねとたらい回しにされて、という風にたらい回しの仕組みによって名前解決をしているということが分かる。
たらい回しにされながら再帰的に聞いていく役割はフルリゾルバが担い、次にどこに行くかの情報や実際に最後の結果を返すのは権威サーバが担うことになる。
digでいろいろ試してみる
ここまで理解してから、digでいろいろ試してみた。
存在するドメインの名前解決をする
まずはこのブログのblog.shibayu36.orgに対してdigを打ってみる。フルリゾルバにはGoogle Public DNSの8.8.8.8を指定してみる。
$ dig @8.8.8.8 blog.shibayu36.org ; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 blog.shibayu36.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43553 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;blog.shibayu36.org. IN A ;; ANSWER SECTION: blog.shibayu36.org. 3599 IN CNAME hatenablog.com. hatenablog.com. 59 IN A 13.112.5.107
blog.shibayu36.orgはCNAMEで別名としてhatenablog.comを返しているので、ANSWER SECTIONには最終的にhatenablog.comのIPアドレスが返って来ている。
では、これがどのような問い合わせになっているのか、+traceオプションを付けてdigを打ってみる。
$ dig @8.8.8.8 blog.shibayu36.org +trace ; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 blog.shibayu36.org +trace ; (1 server found) ;; global options: +cmd . 224784 IN NS a.root-servers.net. . 224784 IN NS i.root-servers.net. . 224784 IN NS d.root-servers.net. . 224784 IN NS l.root-servers.net. . 224784 IN NS f.root-servers.net. . 224784 IN NS c.root-servers.net. . 224784 IN NS k.root-servers.net. . 224784 IN NS j.root-servers.net. . 224784 IN NS m.root-servers.net. . 224784 IN NS g.root-servers.net. . 224784 IN NS e.root-servers.net. . 224784 IN NS h.root-servers.net. . 224784 IN NS b.root-servers.net. ;; Received 228 bytes from 8.8.8.8#53(8.8.8.8) in 359 ms org. 172800 IN NS a0.org.afilias-nst.info. org. 172800 IN NS a2.org.afilias-nst.info. org. 172800 IN NS b0.org.afilias-nst.org. org. 172800 IN NS b2.org.afilias-nst.org. org. 172800 IN NS c0.org.afilias-nst.info. org. 172800 IN NS d0.org.afilias-nst.org. ;; Received 438 bytes from 192.203.230.10#53(192.203.230.10) in 160 ms shibayu36.org. 86400 IN NS ns-351.awsdns-43.com. shibayu36.org. 86400 IN NS ns-591.awsdns-09.net. shibayu36.org. 86400 IN NS ns-1273.awsdns-31.org. shibayu36.org. 86400 IN NS ns-1628.awsdns-11.co.uk. ;; Received 189 bytes from 199.249.120.1#53(199.249.120.1) in 590 ms blog.shibayu36.org. 3600 IN CNAME hatenablog.com. shibayu36.org. 172800 IN NS ns-1273.awsdns-31.org. shibayu36.org. 172800 IN NS ns-1628.awsdns-11.co.uk. shibayu36.org. 172800 IN NS ns-351.awsdns-43.com. shibayu36.org. 172800 IN NS ns-591.awsdns-09.net. ;; Received 198 bytes from 205.251.196.249#53(205.251.196.249) in 26 ms
+traceオプションを付けるとblog.shibayu36.orgを名前解決するために再帰的な呼び出しをしている様子が見て取れて面白い(+traceを付けるとdigが再帰問い合わせしているけど、本当は8.8.8.8が再帰問い合わせすることに注意)。これを見ると
- まず最初に指定したフルリゾルバである8.8.8.8がルートサーバの位置を教えてくれる
- ルートサーバは13個あることが分かる
- 次にdigはこのルートサーバの中から一つ選んで、さらに問い合わせをする。今回はe.root-servers.net.に問い合わせている。これで、今度はorgドメインを管理している権威サーバの位置を教えてくれる。
- dig -x 192.203.230.10 すると、e.root-servers.netに問い合わせていることが分かる
- さらにorgドメインを管理しているb2.org.afilias-nst.org(199.249.120.1)に問い合わせる。これによりshibayu36.orgを管理する権威サーバを教えてくれる。shibayu36.orgはRoute53を使っているので、AWSのドメインが返っている
- 最後にns-1273.awsdns-31.org(205.251.196.249)に問い合わせ、CNAMEにhatenablog.comが入っていることを教えてくれる
という風に探索していることが分かる。実際のフルリゾルバはさらにCNAMEにhatenablog.comが入っていることを見つけたらもう一度hatenablog.comを名前解決をして、Aレコードを見つけることになる。これはdig hatenablog.com +traceを実行すれば様子が分かるだろう。
存在しないドメインの名前解決をする
では続いて存在しないドメインの名前解決をしたときの応答を見てみる。
例えば、wrong.shibayu36.orgというドメインは存在しない。これに対してdigを打つと
$ dig wrong.shibayu36.org ; <<>> DiG 9.8.3-P1 <<>> wrong.shibayu36.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 59271 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;wrong.shibayu36.org. IN A ;; AUTHORITY SECTION: shibayu36.org. 300 IN SOA ns-1628.awsdns-11.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400
のように、NXDOMAINという「ドメインが存在しない」という状態をSOAレコードとして返す。この応答のTTLは300になっているので、5分間はこの結果がキャッシュされることも分かる。
これを+trace付きで見ると
$ dig @8.8.8.8 wrong.shibayu36.org +trace ; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 wrong.shibayu36.org +trace ; (1 server found) ;; global options: +cmd . 12337 IN NS e.root-servers.net. . 12337 IN NS l.root-servers.net. . 12337 IN NS m.root-servers.net. . 12337 IN NS d.root-servers.net. . 12337 IN NS a.root-servers.net. . 12337 IN NS b.root-servers.net. . 12337 IN NS k.root-servers.net. . 12337 IN NS j.root-servers.net. . 12337 IN NS i.root-servers.net. . 12337 IN NS h.root-servers.net. . 12337 IN NS c.root-servers.net. . 12337 IN NS f.root-servers.net. . 12337 IN NS g.root-servers.net. ;; Received 228 bytes from 8.8.8.8#53(8.8.8.8) in 70 ms org. 172800 IN NS b2.org.afilias-nst.org. org. 172800 IN NS c0.org.afilias-nst.info. org. 172800 IN NS a2.org.afilias-nst.info. org. 172800 IN NS a0.org.afilias-nst.info. org. 172800 IN NS b0.org.afilias-nst.org. org. 172800 IN NS d0.org.afilias-nst.org. ;; Received 439 bytes from 192.228.79.201#53(192.228.79.201) in 142 ms shibayu36.org. 86400 IN NS ns-351.awsdns-43.com. shibayu36.org. 86400 IN NS ns-591.awsdns-09.net. shibayu36.org. 86400 IN NS ns-1273.awsdns-31.org. shibayu36.org. 86400 IN NS ns-1628.awsdns-11.co.uk. ;; Received 190 bytes from 199.249.120.1#53(199.249.120.1) in 384 ms shibayu36.org. 900 IN SOA ns-1628.awsdns-11.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400 ;; Received 124 bytes from 205.251.193.95#53(205.251.193.95) in 99 ms
となり、Route53のサーバがNXDOMAINという結果を返していることが分かる。これはshibayu36.orgまでは存在して、wrong.shibayu36.orgが存在しないので、shibayu36.orgを管理しているRoute53がNXDOMAINを返しているようだ。
では続いて、blog.shibayu36hogehogehoge.orgというドメインを名前解決してみると
$ dig @8.8.8.8 blog.shibayu36hogehogehoge.org +trace ; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 blog.shibayu36hogehogehoge.org +trace ; (1 server found) ;; global options: +cmd . 193946 IN NS b.root-servers.net. . 193946 IN NS l.root-servers.net. . 193946 IN NS m.root-servers.net. . 193946 IN NS j.root-servers.net. . 193946 IN NS h.root-servers.net. . 193946 IN NS k.root-servers.net. . 193946 IN NS d.root-servers.net. . 193946 IN NS g.root-servers.net. . 193946 IN NS c.root-servers.net. . 193946 IN NS f.root-servers.net. . 193946 IN NS e.root-servers.net. . 193946 IN NS a.root-servers.net. . 193946 IN NS i.root-servers.net. ;; Received 228 bytes from 8.8.8.8#53(8.8.8.8) in 109 ms org. 172800 IN NS b2.org.afilias-nst.org. org. 172800 IN NS a0.org.afilias-nst.info. org. 172800 IN NS d0.org.afilias-nst.org. org. 172800 IN NS a2.org.afilias-nst.info. org. 172800 IN NS b0.org.afilias-nst.org. org. 172800 IN NS c0.org.afilias-nst.info. ;; Received 450 bytes from 192.228.79.201#53(192.228.79.201) in 197 ms org. 900 IN SOA a0.org.afilias-nst.info. noc.afilias-nst.info. 2012680558 1800 900 604800 86400 ;; Received 111 bytes from 199.19.57.1#53(199.19.57.1) in 202 ms
となり、orgドメインを管理している権威サーバがNXDOMAINを返していることが分かる。これはorgドメインはあるけど、shibayu36hogehogehoge.orgはないので、orgドメインを管理している権威サーバがNXDOMAINを返すわけである。
このように、ドメインが存在しないときは、そのゾーンを管理している権威サーバがNXDOMAINを返すということが分かった。
結局ioドメイン障害では何が起こっていたのか
以上を勉強してから、結局ioドメイン障害では何が起こっていたのかを自分なりに整理してみる。
起こっていたことは去年に起こった障害とほぼ近く、状況については .io ドメインがおかしくなったので dig で調べてみた(2016/10/28) - Qiita を見ると大体把握できる。また今回の状況は .IO TLD DNS issues and a day without Cloudflare に載っていたのだけど
The .IO TLD uses 7 different nameservers for its top level domain; a0.nic.io, ns-a3.io, c0.nic.io, ns-a2.io, b0.nic.io, ns-a1.io and ns-a4.io. 2 of those nameservers, ns-a2.io and ns-a4.io, started misbehaving and instead of returning with a correct set of nameservers for the domain you were requesting, started to reply with an NXDOMAIN result. Essentially declaring that the domain you were requesting, didn’t exist.
と書いていて、7つあるioドメインの権威サーバの内、2台(ns-a2.ioとns-a4.io)が、本当は存在するドメインに対してもNXDOMAINを返してしまっていたということだった。例えばblog.shibayu36.ioというドメインが存在するとした時、
- ルートサーバがioドメインを管理する権威サーバの位置を教えてくれる
- ioの権威サーバがshibayu36.ioを管理する権威サーバの位置を教えてくれる
- shibayu36.ioを管理する権威サーバがblog.shibayu36.ioのAレコードを教えてくれる
となるべきだったのに
- ルートサーバがioドメインを管理する権威サーバの位置を教えてくれる
- ioの権威サーバがshibayu36.ioを存在しない(NXDOMAIN)と返してしまう
ということが起こっていたという感じ。
さらに困ったことに、この結果をSOAレコードでTTL 900で返すため、フルリゾルバは900秒間この結果をキャッシュしてしまい、一度ns-a2.ioもしくはns-a4.ioに当たって、変な結果を貰ってしまったら、900秒間は名前解決に失敗し続けるという状況になっていた。
また、Google Public DNSは8.8.8.8の裏側に何台もフルリゾルバを配置している。このため、同じ8.8.8.8で名前解決をしようとすると
という風になり、確率的に名前解決に失敗しているように見える、という状況となっていた。
権威サーバが壊れるととにかく怖い!