= DNS/実装/python/dnslib/ゾーンサーバー = <> python/dnslibを利用して、簡単なゾーンサーバを作ってみる。-- ToshinoriMaeno <> ゾーンサーバで実現したい機能をまとめる。[[DNS/実装/ゾーンサーバ]] [[../server.py]] == ゾーンデータ == [[/zone.py]] ゾーンの読み込みと検査; 問い合わせに対する返答の作成 いわゆるゾーン形式のテキストを読み込んで、dnslib.RRタイプに変換する。 [[../usage]] {{{ >>> RR.fromZone("abc.com IN A 1.2.3.4") }}} 複数行からなるゾーンファイル形式でもよい。 必須のレコード: ゾーンの根にはSOAとNSは必須である。 ドメイン名はゾーン名をsuffixに持つこと。 == 構造化 == 最初にやることはドメイン名(owner)をキーにしたDictを作ることだ。 {{{  値はレコードタイプをキーにしたDict   そのDictの値は資源レコードセットとする。 }}} ゾーン外のowner名をもつレコードは捨てるのがよいが、 実際にはゾーン外の名前かどうかはSOAを見つけたあとでないとわからない。 また、delegateされた先に属する名前もわからない。 * 中間ノードに対するエントリーが存在しない場合は空エントリーを登録する。   さらに上位も確認すること。  (すでに存在しているノードの上位ノードは登録ずみのはず) * すでに存在しているノードについてはレコードを追加する。(面倒w)   === 登録時の検査 === レコードセットとしてまとめる。(名前とrtype) TTLが一致しているかの検査。(未実装) * 重複するレコードは捨てる。 NSレコードの登録: * rootノード: additional 用に保存する。 * root 以外は末端ノードであることを確認する。    NSレコード以外のレコードが存在しないこと。 * zone cutリストへの登録  CNAMEレコードの登録: * いまだ存在していない名前に対するものであることを確認する。    他のレコードが存在しないことは明らか。 CNAMEレコードが登録ずみでないことの確認:  あらたに登録するレコードがすでにCNAMEで定義されているものでないことも  確認する必要がある。 -- ToshinoriMaeno <> === 登録完了時の検査 === zone apexに必須のレコードの確認 * SOA: NXDomain返答用にsoa_recordとして保存 * NS: zone_cutとして保存 NSレコードを持つ末端ノードのリスト(zone cut; delegation判定用)  中間ノードにNSレコードがあったらエラーである。 (委譲)ゾーン内部の名前をNS値に指定しているならば、A/AAAAも確認すること。    また、これらのAレコードは本ゾーンには属さないので、直接の返答に使ってはいけない。 このあとで、ゾーン外の名前に属するレコードは削除することになるだろう。 CNAMEレコードのownerは他のレコードが登録されていないこと。 CNAMEレコードの一覧を作っておくのがいい。   ゾーン内部名を指すCNAMEの場合はその先の存在を確認しておく。 [[DNS/1/CNAME/レコード]]   CNAMEを指す名前(CNAME, NSなどがないか) == 検索 == 問い合わせの形式検査 [[/query-example]]  ゾーンに属するqueryであること。 === ゾーン内の名前の検索 === ==== 名前あり ==== レコードタイプの一致: 返答;     不一致の場合、CNAMEの存在を調べる。  CNAMEでなければ、NoData返答(SOA -> Auth.)   CNAMEならAnswerにいれて終了。(ターゲット名で検索を続行する必要はない。) ==== 一致する名前がなかった ==== delegation返答の必要があるか。(zone cut DBが欲しい)  zone cut より下の名前は存在しないはずなので、検索の順序はこれでいいはず。 wild card レコードが該当するかもしれない。(省略) NXDomain返答(SOAレコードをAuth. Sec. に入れる)  -- ToshinoriMaeno <>   == 返答生成 == minimal response policy delegation返答には真のglueを付ける。(additional section) -- ToshinoriMaeno <>