・LAN 内のゾーンについてのクエリは権威サーバーに転送する
・それ以外のクエリは反復問い合わせする
構成の例です。
環境
サーバーIPアドレス: 192.168.182.12
AlmaLinux 9.5
PowerDNS Recursor 5.2.2
SELinux 有効
192.168.182.10
上に以下記事同等の権威サーバーが構築されていることを前提とします。
このサーバーの IP アドレスは 192.168.182.12
です。
インストール
公式のリポから stable な最新版をインストールします。
# dnf install epel-release && dnf upgrade
# curl https://repo.powerdns.com/repo-files/el-rec-52.repo -o /etc/yum.repos.d/powerdns-rec-52.repo
# dnf install pdns-recursor
設定
PowerDNS Recursor 5.00 から定義ファイルは YAML 形式になりました。
以下の定義ファイルを作成します。
DNSSEC を有効にしていない権威サーバーのゾーンに対してネガティブトラストアンカーを設定し、DNSEEC 検証を無効化しています。
PowerDNS Recursor 5.2.0 はRFC 5011 トラストアンカー自動更新に対応していないため、ルートゾーン KSK ロールオーバーの度にトラストアンカーを手動で更新する必要があります。
dnssec:
validation: validate # 常時 DNSSEC 検証を実行
negative_trustanchors:
- name: example.com
- name: 182.168.192.in-addr.arpa
incoming:
allow_from: # ACL を設定
- '127.0.0.0/8'
- '192.168.182.0/24'
- '192.168.207.0/24'
listen:
- '127.0.0.1'
- '192.168.182.12'
recursor:
forward_zones: # このゾーンのクエリは権威サーバーに転送
- zone: example.com
forwarders:
- 192.168.182.10
- zone: 182.168.192.in-addr.arpa
forwarders:
- 192.168.182.10
version_string:
組み込み以外のルートヒントファイルを使用する場合は以下のようにします。
(前略)
recursor:
+ hint_file: '/etc/pdns-recursor/recursor.d/named.root'
(後略)
起動
通信許可を設定し、PowerDNS Recursor を起動します。
# firewall-cmd --add-service=dns --permanent
# firewall-cmd --reload
# systemctl enable pdns-recursor
# systemctl start pdns-recursor
確認
以下の通り解決できます。
# 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: 38337
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;dns1.example.com. IN A
;; ANSWER SECTION:
dns1.example.com. 86064 IN A 192.168.182.10
;; Query time: 10 msec
;; SERVER: 192.168.182.12#53(192.168.182.12) (UDP)
;; WHEN: Thu May 01 11:53:50 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: 31820
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;12.182.168.192.in-addr.arpa. IN PTR
;; ANSWER SECTION:
12.182.168.192.in-addr.arpa. 86374 IN PTR dns-r.example.com.
;; Query time: 0 msec
;; SERVER: 192.168.182.12#53(192.168.182.12) (UDP)
;; WHEN: Thu May 01 11:54:06 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: 9691
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 172.217.175.14
;; Query time: 60 msec
;; SERVER: 192.168.182.12#53(192.168.182.12) (UDP)
;; WHEN: Thu May 01 11:55:08 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=783): 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 20250528011241 20250428011241 43611 jprs.co.jp. QFc/yz2CMLQ2yegyXMr59NjGCqR324jgvxtORFyouTzEA01qUT7BBUiT DeuE2A+VVa1NwJgz9ZKJbiLJLKOqSKuzwZ2DRZzY0qL9dvhA7/v5MAzO yZfDPPExND0hnC9G+NUYdZHrSpYQGFrAGTsAps9pWf1vZ3Ys8KFWktdx vnY=
# delv @192.168.182.12 dnssec-failed.mufj.jp. +vtrace
;; fetch: dnssec-failed.mufj.jp/A
;; resolution failed: SERVFAIL
補足
フォワーダーとして使用する場合は以下のようにします。(以下は Google Public DNS に転送する例)
(前略)
recursor:
forward_zones:
- zone: example.com
forwarders:
- 192.168.182.10
- zone: 182.168.192.in-addr.arpa
forwarders:
- 192.168.182.10
+ forward_zones_recurse: # 再帰問い合わせの転送先の指定
+ - zone: .
+ forwarders:
+ - 8.8.8.8
version_string: