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 で差分だけが転送されます。
- ゾーンが多い場合は、カタログゾーンでセカンダリ側の設定作業を減らせます。