2026年6月9日

2026年6月9日

Unbound から PowerDNS へ移行する手順|Recursor への置き換えと、内部ゾーンを Authoritative に分ける方法

Unbound はキャッシュと再帰問い合わせを行うリゾルバーです。PowerDNS にはこれに当たる「PowerDNS Recursor」と、ゾーンを配る権威サーバーの「PowerDNS Authoritative Server」という別々のソフトウェアがあり、Unbound の役割を引き継ぐのは Recursor のほうです。この記事では、Unbound の設定を棚卸しして Recursor の設定に置き換え、並行稼働で答えを比べてから切り替える手順と、Unbound で持っていた内部向けの名前を Authoritative Server に分ける場合の構成を説明します。

内容は PowerDNS Recursor 5.x 系、Authoritative Server 4.x 以降を前提にしています(2026年10月現在)。Recursor は 5.x 系で YAML 形式の設定ファイルが導入され、従来の key=value 形式の設定ファイルは段階的に廃止される方向です。手元の版のドキュメントで、どちらの形式が使えるかを確認してから作業してください。

最初に役割を確認する

移行で最も多い失敗は、「PowerDNS」をひとまとめに考えて、Authoritative Server に Unbound の代わりをさせようとすることです。Authoritative Server は再帰問い合わせを行わないため、インターネット上の任意の名前を解決する用途には使えません。

Unbound で何をしていたかによって、移行先は次のように分かれます。

  • 社内やサーバー内のキャッシュリゾルバー:Recursor へ移します。この記事の中心です。
  • 特定のドメインだけ社内 DNS へ転送:Recursor の転送設定へ移します。
  • **local-data や local-zone で内部の名前を返す**:件数が少なければ Recursor にゾーンファイルとして読ませます。件数が多い、API で更新したいなどの場合は Authoritative Server に分け、Recursor からそのドメインだけ転送します。
  • **auth-zone でゾーンを配る**:配る相手がインターネット上なら Authoritative Server へ移します。

Unbound の設定を棚卸しする

移行の前に、今の Unbound が実際に何をしているかを一覧にします。設定ファイルを読むだけでなく、稼働中の状態も取り出しておくと漏れが減ります。

unbound-checkconf
unbound-control list_forwards
unbound-control list_stubs
unbound-control list_local_zones
unbound-control list_local_data
unbound-control stats_noreset > unbound-stats-before.txt

一覧にした項目は、次の観点で移行先を決めます。

Unbound の設定 用途 Recursor での扱い(YAML のキー)
interface / port 待ち受け incoming.listen / incoming.port
access-control 問い合わせを許す相手 incoming.allow_from
num-threads スレッド数 recursor.threads
forward-zone 別のリゾルバーへ転送 recursor.forward_zones_recurse
stub-zone 権威サーバーへ直接問い合わせ recursor.forward_zones
local-data / local-zone 内部の名前 recursor.auth_zones(ゾーンファイル)
auto-trust-anchor-file DNSSEC 検証 dnssec.validation

表の YAML のキーは代表的なものです。名前や階層は版によって異なることがあるため、手元の版の設定リファレンスで確認してください。直接対応する設定が見当たらない項目(たとえば応答から私設アドレスを取り除く private-address など)は、なぜその設定を入れたのかを確認し、Recursor の Lua スクリプトや別の仕組みで代わりにするか、不要なら移さないかを判断します。

転送の設定は「再帰あり」と「再帰なし」を区別する

Recursor の転送には2種類あり、取り違えると名前解決が失敗します。

  • **forward_zones**:転送先を権威サーバーとして扱い、再帰を求めない問い合わせを送ります。Unbound の stub-zone に近いものです。
  • **forward_zones_recurse**:転送先をリゾルバーとして扱い、再帰を求めて問い合わせます。Unbound の forward-zone に近いものです。

社内の Active Directory の DNS や別のリゾルバーに転送していたなら forward_zones_recurse、社内の権威サーバーに直接聞いていたなら forward_zones を使います。

Recursor の設定例

Recursor をインストールしたら(ディストリビューションのパッケージか、PowerDNS が提供するリポジトリを使います)、最初は Unbound と衝突しない別のアドレスで待ち受けて並行稼働させます。設定ファイルの場所はパッケージによって異なり、/etc/powerdns/recursor.yml などです。

incoming:
  listen:
    - 192.0.2.54
  allow_from:
    - 127.0.0.0/8
    - 10.0.0.0/8
    - 192.168.0.0/16

recursor:
  threads: 2
  forward_zones_recurse:
    - zone: corp.example
      forwarders:
        - 10.0.0.53
  forward_zones:
    - zone: dev.example
      forwarders:
        - 10.0.1.10
  auth_zones:
    - zone: home.arpa
      file: /etc/powerdns/zones/home.arpa.zone

dnssec:
  validation: process

allow_from は、問い合わせを受け付ける相手を自分のネットワークに限るための設定です。インターネット全体に開いたリゾルバーは増幅攻撃に悪用されるため、Unbound の access-control と同じ範囲に絞ります。

auth_zones で読ませるファイルは通常のゾーンファイル形式です。Unbound の local-data は1行ごとにリソースレコードの形で書かれているので、SOA と NS を加えれば、ほぼそのままゾーンファイルにできます。

$ORIGIN home.arpa.
@    3600 IN SOA ns.home.arpa. hostmaster.home.arpa. 2026101801 3600 600 604800 300
@    3600 IN NS  ns.home.arpa.
ns   3600 IN A   192.168.1.53
nas  3600 IN A   192.168.1.10

設定を書いたら Recursor を起動し、ログにエラーが出ていないか、応答しているかを確認します。

systemctl restart pdns-recursor
journalctl -u pdns-recursor -n 50
rec_control ping
dig @192.0.2.54 www.example.com A

サービス名もパッケージによって異なることがあります。systemctl list-unit-files | grep -i recursor で確認してください。

並行稼働で答えを比べる

切り替えの前に、実際に使われている名前の一覧で、Unbound と Recursor の答えを比べます。Unbound のログや監視の記録から、よく問い合わせられる名前と内部の名前を抜き出して names.txt に1行ずつ書きます。

#!/bin/bash
# 旧: Unbound / 新: Recursor
OLD=192.0.2.53
NEW=192.0.2.54
while read -r name type; do
  type=${type:-A}
  a=$(dig +short @"$OLD" "$name" "$type" | sort)
  b=$(dig +short @"$NEW" "$name" "$type" | sort)
  if [ "$a" != "$b" ]; then
    echo "DIFF $name $type"
    echo "  old: $a"
    echo "  new: $b"
  fi
done < names.txt

CDN を使う名前は、問い合わせのたびや問い合わせ元によって答えが変わるため、差が出ても異常とは限りません。差が出た名前は、内部の名前か、転送先のドメインか、DNSSEC の検証に関わるものかを見て判断します。DNSSEC の検証に失敗した名前は SERVFAIL になるので、dig +dnssec や +cd を付けた問い合わせと比べると原因を切り分けやすくなります。

内部ゾーンを Authoritative Server に分ける場合

内部の名前が多い、Web 画面や API で更新したい、といった場合は、Authoritative Server を同じホストの別ポートで動かし、Recursor からそのドメインだけ転送します。

# /etc/powerdns/pdns.conf の例
launch=gsqlite3
gsqlite3-database=/var/lib/powerdns/pdns.sqlite3
local-address=127.0.0.1:5300

SQLite のデータベースは、パッケージに同梱されているスキーマのファイルから作ります。ファイルの場所はパッケージによって異なります。ゾーンファイルからの取り込みと検査は pdnsutil で行います。

pdnsutil load-zone home.arpa /etc/powerdns/zones/home.arpa.zone
pdnsutil check-zone home.arpa

新しい版の pdnsutil ではコマンドの体系が整理されている場合があるため、pdnsutil --help で手元の書き方を確認してください。Recursor 側では auth_zones から外し、forward_zones に 127.0.0.1:5300 を転送先として書きます。権威サーバーへの転送なので、再帰なしの forward_zones を使います。

切り替えと切り戻し

  1. クライアントが参照する DNS サーバーの設定(DHCP で配る値、サーバーの /etc/resolv.conf、ルーターの設定など)を確認し、切り替える順番を決めます。影響の小さい一部の端末から始めます。
  2. 待ち受けのアドレスを入れ替える方法もあります。Unbound を止めてから Recursor の incoming.listen を元のアドレスに変えると、クライアント側の設定を変えずに済みます。同じアドレスとポートで両方を同時に動かすことはできません。
  3. 切り替え後は、rec_control get-all でキャッシュのヒット率や SERVFAIL の数を確認し、Unbound の頃の統計と比べます。
  4. Unbound の設定とパッケージはしばらく残しておき、問題が出たら待ち受けを戻せるようにします。

まとめ

  • Unbound の代わりになるのは PowerDNS Recursor です。Authoritative Server は再帰問い合わせを行いません。
  • 移行前に unbound-control で転送・スタブ・ローカルデータを一覧にし、移行先を決めます。
  • Unbound の forward-zone は forward_zones_recurse、stub-zone は forward_zones に近く、取り違えると解決に失敗します。
  • 別アドレスで並行稼働させ、名前の一覧で答えを比べてから、一部の端末から切り替えます。

お気軽にご相談ください

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