2026年6月14日

2026年6月14日

Knot DNS のセカンダリ構成方法|Knot をプライマリにして複数のセカンダリへ配信する設定

Knot DNS をプライマリにしてセカンダリへゾーンを配るには、配信先を remote に登録し、acl で「その相手にだけゾーン転送を許可」し、zone に notify を書いて更新を知らせます。この記事では、Knot DNS を配信元(プライマリ)とする2台以上のセカンダリ構成を、転送の許可、更新の流し方、差分転送(IXFR)、ゾーンの増減を自動で伝えるカタログゾーンまで順に説明します。

Knot DNS を受け取る側(セカンダリ)にして、BIND などの既存プライマリからゾーンを取得する設定は別の話題なので、ここではプライマリ側に絞ります。設定項目名は Knot DNS 3.x 系を前提にしています(2026年10月現在)。項目名や既定値はバージョンで変わることがあるため、knotd --version で確認したうえで公式マニュアルの該当バージョンを参照してください。

構成例と設計の考え方

例として次の構成を使います。

  • プライマリ:192.0.2.1(Knot DNS。ゾーンの編集と DNSSEC 署名はここで行う)
  • セカンダリ1:198.51.100.2
  • セカンダリ2:203.0.113.3

セカンダリは Knot 同士でなくても構いません。BIND、NSD、PowerDNS など標準のゾーン転送に対応したサーバーであれば受け取れます。

よく使われる形に「隠しプライマリ」があります。プライマリを NS レコードにも登録事業者にも載せず、外部からの問い合わせはセカンダリだけが受ける構成です。プライマリへの攻撃や負荷を避けられ、編集用のサーバーを止めてもサービスは止まりません。この場合、プライマリは外部に開く必要がなく、セカンダリとの間の TCP/UDP 53 番だけ通せば足ります。

手順1:TSIG 鍵とセカンダリの登録

転送と NOTIFY には TSIG 鍵で署名を付けます。セカンダリごとに鍵を分けると、1台を外すときに鍵の作り直しが他に波及しません。

keymgr -t sec1-key hmac-sha256
keymgr -t sec2-key hmac-sha256

出力された key: セクションを knot.conf に貼り、同じ鍵をそれぞれのセカンダリにも設定します。秘密値はパスワードと同じ扱いで、設定ファイルの権限を絞り、共有の場に貼らないようにしてください。

手順2:プライマリの knot.conf

秘密値はダミーです。

server:
    listen: [ 192.0.2.1@53 ]

key:
  - id: sec1-key
    algorithm: hmac-sha256
    secret: your-base64-secret-1
  - id: sec2-key
    algorithm: hmac-sha256
    secret: your-base64-secret-2

remote:
  - id: secondary1
    address: 198.51.100.2@53
    key: sec1-key
  - id: secondary2
    address: 203.0.113.3@53
    key: sec2-key

acl:
  - id: xfr_secondary1
    address: 198.51.100.2
    key: sec1-key
    action: transfer
  - id: xfr_secondary2
    address: 203.0.113.3
    key: sec2-key
    action: transfer

template:
  - id: default
    storage: /var/lib/knot
    notify: [ secondary1, secondary2 ]
    acl: [ xfr_secondary1, xfr_secondary2 ]

zone:
  - domain: example.com
    file: example.com.zone
  - domain: example.net
    file: example.net.zone

ポイントは次のとおりです。

  • acl の action: transfer が「この相手にゾーン転送を許す」という意味です。acl に該当しない相手からの転送要求は拒否されるため、誰にでもゾーンの中身を渡してしまう事故を防げます。
  • notify は、更新時に NOTIFY を送る相手の remote です。
  • 共通の設定を template の default に置くと、ゾーンを増やすたびに同じ行を書かずに済みます。ゾーンごとに配信先を変えたいときは、zone 側で notify や acl を上書きします。
knotc conf-check
knotc reload

手順3:ゾーンの更新を流す

プライマリでの更新方法は大きく2通りあります。どちらでも、セカンダリはシリアル番号が増えたことを見て取り込むため、シリアルの扱いが要になります。

ゾーンファイルを編集する場合

ゾーンファイルを書き換えてシリアルを上げ、そのゾーンだけ読み直します。

knotc zone-check example.com    # 読み込めるか確認
knotc zone-reload example.com

シリアルを上げ忘れると、Knot は新しい内容を読み込んでもセカンダリへの配信が進みません。手作業での上げ忘れを避けたい場合、zone の zonefile-load に、ファイルとの差分を計算してシリアルを自動で進める設定値(difference-no-serial)があります。挙動がバージョンで異なる可能性があるため、検証環境で「編集→reload→セカンダリのシリアルが進む」流れを確かめてから使ってください。

knotc のトランザクションで編集する場合

ファイルを触らずに、コマンドで変更することもできます。

knotc zone-begin example.com
knotc zone-set example.com www 3600 A 192.0.2.10
knotc zone-commit example.com

commit の時点でシリアルが進み、差分がジャーナルに記録され、セカンダリへ NOTIFY が送られます。途中でやめたいときは knotc zone-abort example.com で破棄できます。この方法で変えた内容をゾーンファイルにも書き戻すかどうかは zonefile-sync の設定で決まるので、ファイルを正本として管理している場合は、両者がずれない運用を決めておきます。

手順4:差分転送(IXFR)を効かせる

レコードが多いゾーンで毎回全体転送(AXFR)をすると、転送量と時間がかさみます。Knot はゾーンの変更履歴をジャーナルに保存し、セカンダリから IXFR を求められると差分だけを返します。

差分を返せるのは、ジャーナルにその区間の履歴が残っている場合だけです。ジャーナルの容量上限に達して古い履歴が消えている、あるいはプライマリを作り直して履歴がない場合は、全体転送に切り替わります。動作としては正しいので、IXFR にならないこと自体は障害ではありません。

手順5:カタログゾーンでゾーンの増減を伝える

ゾーンが多くなると、プライマリにゾーンを足すたびに全セカンダリの設定にも同じゾーンを書き足す作業が負担になります。カタログゾーン(RFC 9432)は、「配信するゾーンの一覧」そのものを特別なゾーンとして転送する仕組みで、セカンダリは一覧を受け取って自動でゾーンを追加・削除します。Knot DNS は 3.1 系以降で対応しています。

プライマリ側では、一覧用のゾーンを生成役にし、配りたいゾーンをその一覧のメンバーにします。

zone:
  - domain: catalog.invalid
    catalog-role: generate
  - domain: example.com
    file: example.com.zone
    catalog-role: member
    catalog-zone: catalog.invalid

セカンダリが Knot の場合は、一覧を解釈する役にして、追加されたゾーンに使うテンプレート(どのプライマリから取るか)を指定します。次の例の primary(プライマリの remote)と notify_from_primary(プライマリからの NOTIFY を許す acl)は、セカンダリ側の knot.conf で別に定義しておく前提です。

template:
  - id: catalog-members
    master: primary
    acl: notify_from_primary

zone:
  - domain: catalog.invalid
    master: primary
    acl: notify_from_primary
    catalog-role: interpret
    catalog-template: catalog-members

注意点として、カタログゾーンへの対応状況や細かな挙動はソフトウェアとバージョンによって差があります。BIND や NSD をセカンダリに混ぜる場合は、それぞれのドキュメントで対応範囲を確認してください。また、一覧からゾーンが消えるとセカンダリ側でもそのゾーンが削除されるため、一覧の変更は検証環境で試してから本番に反映します。

動作確認

各サーバーの SOA シリアルを並べて比べるのが手早い方法です。

for ns in 192.0.2.1 198.51.100.2 203.0.113.3; do
  printf '%s ' "$ns"; kdig +short @"$ns" example.com SOA
done

全台でシリアルが一致していれば配信できています。プライマリのログ(journalctl -u knot)には、NOTIFY の送信や転送の開始・終了が記録されます。転送が拒否されている場合は、要求元のアドレスと鍵が acl と合っているか、TCP 53 番が通っているかを確認します。

あわせて、許可していない場所からゾーン転送ができないことも確かめておきます。

# セカンダリ以外のホストから実行し、拒否されることを確認する
kdig @192.0.2.1 example.com AXFR

運用上の注意

  • 設定やゾーンを変える前に、knot.conf、ゾーンファイル、storage のディレクトリをバックアップします。
  • DNSSEC を有効にする場合、署名はプライマリだけで行い、セカンダリには署名済みのゾーンを配ります。セカンダリ側で別に署名させると鍵が食い違います。
  • セカンダリの追加・撤去では、acl・notify・鍵の3か所と、NS レコード・登録事業者側のネームサーバー一覧をそろえて更新します。

まとめ

  • プライマリの Knot DNS では、remote にセカンダリを登録し、acl の transfer で転送を許可し、notify で更新を知らせます。
  • 共通設定は template にまとめると、ゾーンを増やしても設定が膨らみません。
  • 更新はゾーンファイルの編集か knotc のトランザクションで行い、どちらもシリアルが進むことが前提です。
  • ジャーナルが残っていれば IXFR で差分だけが転送されます。
  • ゾーンが多い場合は、カタログゾーンでセカンダリ側の設定作業を減らせます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲