DNSメモ
DNS(STD-13, RFC-1035)はドメイン名に紐づくデータを取得するツリー型のデータ管理サービスで、URLに対応するIPアドレスを解決したりすることに使われる。たとえばURLに含まれるドメインwww.yahoo.co.jpについて具体的にどこにアクセスすればいいかを解決する。 仕様
またLANでマルチキャストを利用して事前設定不要な名前解決プロトコルとしてmDNS(RFC-6762)がしばしば利用されているが平文マルチキャストを使うためなりすましが容易であるという欠点がある。 DNSではツリー構造でデータを管理している。
情報の管理を行うサーバーをネームサーバー(コンテンツサーバー)と呼ぶ。このネームサーバーに管理される範囲をゾーンと呼ぶ。ネームサーバーがどこにあるか? どこから別のゾーンなのか? といった情報もDNSによって提供される。そのため、www.yahoo.co.jpのIPv4アドレスを取得するといった仕事のためにはなんどもコンテンツサーバーにアクセスする必要がある。何度もリモートアクセスが発生すると時間がかかるし負荷も高いためキャッシュが使われる。このキャッシュを備えつつキャッシュミス時にコンテンツサーバーにアクセスするサーバーをフルサービスリゾルバと呼ぶ。
また単に静的にデータを提供するだけでなく、動的に提供することで負荷分散や可用性向上を実現することも行われている。
以降は下のような構成にする。
1. 提供されるデータの種類
2. 実際にIPアドレスを解決する論理的な流れ
3. 実際にIPアドレスを解決する物理的な流れ
4. スタブリゾルバの設定
5. 動的に提供される発展的な機能
6. 実装へのリンク
提供されるデータの種類
まずDNSで提供される主なレコード(情報)種別について整理する。下の表の2列目にコンテンツデータ・メタデータと書いたがこれは一般的な用語ではなく、ここでの説明のために導入した。
コンテンツデータはDNS外部のサービスに関する記述で、メタデータはツリーの分散管理などDNSの中で利用されている。
table: dns-records
A コンテンツデータ ターゲットドメインに与えられたIPv4アドレス
AAAA コンテンツデータ ターゲットドメインに与えられたIPv6アドレス
SRV コンテンツデータ ターゲットドメインで提供されるサービスのエントリポイント
MX コンテンツデータ ターゲットドメインで提供されるメール配送先ドメイン(別ドメイン)
CNAME メタデータ ターゲットドメインの本名で別のドメイン名; エイリアス機能を提供している
NS メタデータ ターゲットドメイン配下を管理するネームサーバーのドメイン
SOA メタデータ ターゲットドメイン配下を管理するネームサーバーが所属するドメイン群
実際にIPアドレスを解決する論理的な流れ
ここでは具体的に www.yahoo.co.jp を解決することで流れを確認する。さっきキャッシュ機構があると述べたがここでは探索開始時には全くキャッシュに載っていない前提で書く。もちろん何も知らないと解決できないので、ルートサーバーについては知っている。
1. www.yahoo.co.jp.についてIPv4アドレスを調べることにする: target.1
2. Q. とりあえずルートサーバー(.)にwww.yahoo.co.jp.のSOAレコードを問い合わせる
3. A. jp.のネームサーバー情報(NSレコードと関連するAレコード)を返してくる
4. Q. jp.のネームサーバーにwww.yahoo.co.jp.のSOAレコードを問い合わせる
5. A. yahoo.co.jpのネームサーバ(ns*.yahoo.co.jp.)の情報を返してくる(運用上の理由でco.jp.が飛ばされる)
6. Q. ns*.yahoo.co.jp.にwww.yahoo.co.jp.のAレコードを問い合わせる
7. A. CNAMEとしてedge12.g.yimg.jp.を得る: target.1の部分解(CNAME)が得られた
8. edge12.g.yimg.jp.のIPv4アドレスを知りたいのでAレコードを調べることにする: target.2
9. Q. jp.のネームサーバーにedge12.g.yimg.jp.のSOAレコードを問い合わせる
10. A. yimg.jpのネームサーバ(ns*.yahoo.co.jp.)を返してくる(運用上の理由でco.jp.が飛ばされる)
11. Q. ns*.yahoo.co.jp.にedge12.g.yimg.jp.のSOAレコードを問い合わせる
12. A. g.yimg.jp.のNS(gns*.yahoo.co.jp.)の情報を得る
13. Q. gns*.yahoo.co.jp.にedge12.g.yimg.jp.のAレコードを問い合わせる
14. A. edge12.g.yimg.jp.のAレコード182.22.16.251などを得る(target.2が完了)
大雑把な流れはこのような感じ。コンテンツサーバーは問われたドメインに最長マッチする委譲先のゾーンに関する情報を提供し、問い合わせ元は窓口を変えて似たことを繰り返す。委譲されたゾーンのトップレベルドメインも得られるので足りない場合にSOAを探してNSを特定する。
実際にIPアドレスを解決する物理的な流れ
Linuxのdigはresolve用の子プロセスを生成して、子プロセスがDNSと通信している。スタブリゾルバはユーザー空間で動くライブラリ。下のようにしてシステムコールの呼び出しを追って大雑把な動きを確認した。
code:dig-yahoo.co.jp.sh
strace -f dig yahoo.co.jp |& less
多くの場合、/etc/hostsを用いて解決を試みてから/etc/resolve.confのserverに設定されたサーバーに問い合わせる。また通信はUDP/53に向けて行われるが問い合わせが長いとパケットが分割されてしまうのでTCP/53を使うように切り替わる。
対象IPはDNSフォワーダなどを経てフルサービスリゾルバに到達する。
フルサービスリゾルバが論理的な流れで行ったような問い合わせを出来るだけキャッシュを利用して実行し得られた回答をスタブリゾルバに回答する。
https://gyazo.com/2575f7a093560e09a9fd6ad5a572496c
code: dns-root-server.txt
dig -n NS .
; <<>> DiG 9.10.6 <<>> -n NS .
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47494
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 27
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 3046 IN NS j.root-servers.net.
.......
. 3046 IN NS i.root-servers.net.
. 3046 IN NS c.root-servers.net.
;; ADDITIONAL SECTION:
m.root-servers.net. 3257 IN A 202.12.27.33
m.root-servers.net. 961 IN AAAA 2001:dc3::35
.......
スタブリゾルバの設定
systemd-resolvedなどが設定ファイルに基づいて/etc/resolv.confを変更している。
発展的な機能や注意点
DNSラウンドロビン
古典的な負荷分散の実装。同一ドメインにA/AAAAレコードを複数設定することで実現する。静的なコンテンツサーバーで実現可能。
GSLB
賢い負荷分散の実装。同一ドメインに対してリクエスト元IPや候補先IPの負荷・死活状況などに基づいてA/AAAAレコードの内容を変更する。DNSはキャッシュを前提としたシステムなため有効活用するために対象となるゾーンのSOAレコードに書かれているTTL(キャッシュの有効期限)を短めに設定する。
Zone APEX
ゾーンのトップレベルドメインを指す。NSレコードが必要であるためCNAMEを設定することができません。
設定してしまうとCNAME先で解決が試みられてしまうため対象ゾーンがインターネット内に存在できなくなります。これについてはRFC-1912で言及されています。 標準ではZone APEXにCNAMEを設定できないため、yahoo.co.jpに対する問い合わせにwww.yahoo.co.jpのIPアドレスを提供するなどができません。そこで各DNSサービスは動的にA/AAAAレコードを返すことで類似機能を提供しています。
ベンダーによってAlias, CNAME flatteningと呼び方が違うけど、機能としてはほぼ同じ。
ref.
DoT, DoH, DNSSEC
分散データベースなので部分的導入に止まることもあるし、スタブ・フルリゾルバ間で利用されたら安全というわけでもないのでセキュリティ的な要件と擦り合わせて評価する必要がある。
ref.
mDNS/DNS-SD
両者ともにAppleが提案したプロトコル。Google Homeなどが勝手に発見できる仕組みがこれ。
実装へのリンク