slave な NSD は refresh のとき serial を見てくれない

スポンサーリンク

前回の記事で、PowerDNS と NSD を組み合わせて DNS を構築した。

その後、検証のために大量のゾーンを突っ込んでみたところ、困った現象に遭遇したのでまとめておく。

その現象とはこの記事のタイトルの通りで、slave として動く NSD は refresh するとき master の serial 値を確認してくれないということだ。

master と slave の同期について

本題に入る前に、DNS の master と slave の同期についておさらいしておく。

あるゾーン example.com において refresh 時間が経過したとき、slave は master との再同期を試みる。master と slave の同期については RFC 1034 の 4.3.5. Zone maintenance and transfers で定義されており、要約すると次のようなことが書かれてある (と思う)。

  1. slave から master に example.comSOA を問い合わせる。
  2. master は slave に serial 他の情報を答える。
  3. slave は「master から返ってきた serial 値」と「自身が持つ serial 値」を比較する。
  4. serial が更新されていないなら処理を終了する。更新されていれば、slave は master にゾーン転送 (AXFR) を TCP で要求する。
  5. master は slave にゾーンを転送する。

この動作については、次の記事の図がわかりやすい。

再同期において、1〜2 の通信は UDP で行なわれ、serial が更新されていなければその後のゾーン転送は行なわれないため、さほど負荷はかからないはずだ。

観測した事象

refresh300 に設定したゾーンを4万件程度投入して master 側 (PowerDNS) のホストのリソースを見守っていたところ、激しく負荷がかかっていた。

原因

原因を調べるために tcpdump でゾーン同期の様子を眺めてみたところ、どうやら NSD は上記の 1〜3 をすっ飛ばしていきなり 4 から始めているようだった。ML の過去ログを漁ってみたところ、次のような投稿が見つかった。

An AXFR initiated by the built-in transfer process will not start with a SOA query at all.

この通り、refresh 時の serial 比較機能は NSD に実装されていないようだ。

BIND の場合

BIND 9.8.1 を slave にして同様の確認をしたところ、きちんと上記の流れで動作しており、高負荷は見られなかった。そして BIND 9.7.2 からは、NSD と同様に動的にゾーンを追加、削除できるようになっている。ということで NSD は諦めて BIND を使うか……。

スポンサーリンク

参考ページ

コメント

タイトルとURLをコピーしました