・LAN 内のドメインについてのクエリは権威サーバーに転送する
・それ以外のクエリは反復問い合わせする
構成の例です。
環境
AlmaLinux 9.5
Knot Resoler 6.0.12
SELinux有効
192.168.182.10
上に以下記事同等の権威サーバーが構築されていることを前提とします。
インストール
今回は早期リリースの 6.0.12 を使用するので、公式が用意している Copr のリポを使用します。
stable なバージョンは epel から入手可能です。
# dnf install epel-release && dnf upgrade
# dnf copr enable @cznic/knot-resolver
# dnf install knot-resolver
設定
Knot Resolverの設定
Knot Resolver 6.0.0 から、定義ファイルの書式に YAML を使用するようになりました。
そのため、以前の lua 言語の定義ファイルとは書式が大幅に異なっています。
以下の定義ファイルを作成します。
workers: 1 #サーバーのCPUコア数に合わせる
logging:
level: info
network:
listen:
- interface: [ 127.0.0.1, 192.168.182.12 ]
do-ipv6: false
forward:
- subtree:
- example.com
- 182.168.192.in-addr.arpa
servers:
- 192.168.182.10
options:
authoritative: true # 転送先が権威サーバーなので true を指定
dnssec: false # DNSSEC 非対応のゾーンのため false を指定
views: # アクセス制限を設定
- subnets: [ 192.168.182.0/24, 192.168.207.0/24, 127.0.0.1 ] # 許可するサブネット
answer: allow
- subnets: [ 0.0.0.0/0 ] # 上記以外は拒否
answer: refused
組み込み以外のルートヒントファイルを使用する場合は、定義ファイルに以下を追加します。
+ lua:
+ script: |
+ modules = { 'hints > iterate' }
+ hints.root_file('<ルートヒントファイルの絶対パス>')
以下のコマンドで内容が正しいか確認します。
何も出力されなければ OK です。
# kresctl validate /etc/knot-resolver/config.yaml
起動
FW に通信許可を設定し、Knot Resolver を起動します。
# firewall-cmd --add-service=dns --permanent
# firewall-cmd --reload
# systemctl enable knot-resolver
# systemctl start knot-resolver
確認
以下の通り解決できます。
# dig @192.168.182.12 dns1.example.com.
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> @192.168.182.12 dns1.example.com.
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35143
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;dns1.example.com. IN A
;; ANSWER SECTION:
dns1.example.com. 3597 IN A 192.168.182.10
;; Query time: 0 msec
;; SERVER: 192.168.182.12#53(192.168.182.12) (UDP)
;; WHEN: Thu May 08 15:53:16 JST 2025
;; MSG SIZE rcvd: 61
# dig @192.168.182.12 -x 192.168.182.12
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> @192.168.182.12 -x 192.168.182.12
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62123
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;12.182.168.192.in-addr.arpa. IN PTR
;; ANSWER SECTION:
12.182.168.192.in-addr.arpa. 3600 IN PTR dns-r.example.com.
;; Query time: 9 msec
;; SERVER: 192.168.182.12#53(192.168.182.12) (UDP)
;; WHEN: Thu May 08 15:53:37 JST 2025
;; MSG SIZE rcvd: 87
# dig @192.168.182.12 google.com.
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> @192.168.182.12 google.com.
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43153
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 216.58.220.110
;; Query time: 50 msec
;; SERVER: 192.168.182.12#53(192.168.182.12) (UDP)
;; WHEN: Thu May 08 15:53:59 JST 2025
;; MSG SIZE rcvd: 55
DNSSEC 検証も正しく成功・失敗しています。
# delv @192.168.182.12 jprs.co.jp. +vtrace
;; fetch: jprs.co.jp/A
;; validating jprs.co.jp/A: starting
;; validating jprs.co.jp/A: attempting positive response validation
;; fetch: jprs.co.jp/DNSKEY
;; validating jprs.co.jp/DNSKEY: starting
;; validating jprs.co.jp/DNSKEY: attempting positive response validation
;; fetch: jprs.co.jp/DS
;; validating jprs.co.jp/DS: starting
;; validating jprs.co.jp/DS: attempting positive response validation
;; fetch: jp/DNSKEY
;; validating jp/DNSKEY: starting
;; validating jp/DNSKEY: attempting positive response validation
;; fetch: jp/DS
;; validating jp/DS: starting
;; validating jp/DS: attempting positive response validation
;; fetch: ./DNSKEY
;; validating ./DNSKEY: starting
;; validating ./DNSKEY: attempting positive response validation
;; validating ./DNSKEY: verify rdataset (keyid=20326): success
;; validating ./DNSKEY: marking as secure (DS)
;; validating jp/DS: in fetch_callback_dnskey
;; validating jp/DS: keyset with trust secure
;; validating jp/DS: resuming validate
;; validating jp/DS: verify rdataset (keyid=53148): success
;; validating jp/DS: marking as secure, noqname proof not needed
;; validating jp/DNSKEY: in fetch_callback_ds
;; validating jp/DNSKEY: dsset with trust secure
;; validating jp/DNSKEY: verify rdataset (keyid=35821): success
;; validating jp/DNSKEY: marking as secure (DS)
;; validating jprs.co.jp/DS: in fetch_callback_dnskey
;; validating jprs.co.jp/DS: keyset with trust secure
;; validating jprs.co.jp/DS: resuming validate
;; validating jprs.co.jp/DS: verify rdataset (keyid=13611): success
;; validating jprs.co.jp/DS: marking as secure, noqname proof not needed
;; validating jprs.co.jp/DNSKEY: in fetch_callback_ds
;; validating jprs.co.jp/DNSKEY: dsset with trust secure
;; validating jprs.co.jp/DNSKEY: verify rdataset (keyid=63574): success
;; validating jprs.co.jp/DNSKEY: marking as secure (DS)
;; validating jprs.co.jp/A: in fetch_callback_dnskey
;; validating jprs.co.jp/A: keyset with trust secure
;; validating jprs.co.jp/A: resuming validate
;; validating jprs.co.jp/A: verify rdataset (keyid=43611): success
;; validating jprs.co.jp/A: marking as secure, noqname proof not needed
; fully validated
jprs.co.jp. 300 IN A 117.104.133.165
jprs.co.jp. 300 IN RRSIG A 8 3 300 20250604023001 20250505023001 43611 jprs.co.jp. GNkmT72CLP6GLbPBoVCUNYDKJKdNQqEoT7mBgXr+L4sPVjh1K9oCttS6 eQrBrfBpwFQwSjOmJKk1VcN3aclxF2xd2s1UnOH8tmhKkj0tm16J1GY5 +oLQ+yOwI7MRDLZkevEnbdSjiYDI/EWOavyzEt707VizoD0JsaUTbdfF 2QI=
# delv @192.168.182.12 dnssec-failed.mufj.jp. +vtrace
;; fetch: dnssec-failed.mufj.jp/A
;; resolution failed: SERVFAIL
補足
フォワーダーとして使用する場合は以下のようにします。(Google Public DNS に転送する例)
(前略)
forward:
+ - subtree:
+ - .
+ servers:
+ - 8.8.8.8
- subtree:
- example.com
- 182.168.192.in-addr.arpa
servers:
- 192.168.182.10
options:
authoritative: true
dnssec: false
(後略)