概要
これまで、PowerDNS Authoritative Serverを使った権威DNSサーバと、PowerDNS Recursorを使った名前解決サーバを構築した。
ただ、あくまでも単一ノード。障害やメンテナンスでDNSサーバが停止すると、当然ながら名前解決ができず、かなりつらいことになる。というわけで、DNSを冗長化することにする。
DNSの冗長化方式
DNSの冗長化は、権威DNSと再帰DNSを分けて考える必要がある。代表的な方式は次のとおり。
権威 DNS の冗長化方式
| 方式 | 概要 | ユースケース |
|---|---|---|
| Primary/Secondary | Primaryを原本とし、Secondaryへゾーン転送、障害時は複数のNSレコードを使って別の権威サーバへ問い合わせ | 構成をわかりやすく、ゾーンの更新経路を一方向にしたい場合 |
| Multi-Primary | 複数の権威サーバでゾーンを更新 | 複数拠点から更新したい場合。ただし競合やシリアル管理が複雑になる |
| マネージドDNS | クラウドやDNS事業者にゾーン管理と可用性を委託 | 運用負担を減らし、インターネット向けの可用性を重視する場合 |
名前解決 DNS の冗長化方式
| 方式 | 概要 | ユースケース |
|---|---|---|
| 複数サーバ指定 | クライアントやDHCPで複数の名前解決DNSサーバを配布 | 家庭内・ラボ・社内ネットワークなど、利用者側で接続先を指定できる場合 |
| Anycast | 同じIPアドレスを複数拠点から広告し、ネットワーク的に近い拠点へ到達させる | 大規模サービスや拠点障害への耐性を高めたい場合 |
| VIP/ロードバランサ | 仮想IPやロードバランサを接続先にし、背後の名前解決DNSを切り替え | クライアントの設定を1つに固定したい場合。ただしDNS向けのヘルスチェックとUDP/TCPの扱いが必要 |
設計方針
今回は、冗長化する上で最もシンプルな方式として、権威DNSに Primary/Secondary方式、再帰DNSに 複数サーバの指定を採用する。Primary/Secondary方式は、ゾーンの原本をPrimaryに集約し、NOTIFYとゾーン転送でSecondaryへ同期できるため、構成と更新経路が理解しやすい。再帰DNSはPrimaryとSecondaryの両方で提供し、クライアントがどちらにも問い合わせられるようにする。
障害発生から別のDNSサーバへ問い合わせるまでの時間はクライアント側の実装に依存するが、ラボ環境であり、ユーザもごく限られることから、そこまで厳密な切り替え制御は行わない。
Primary 権威サーバとSecondary 権威サーバは、それはそのまま Primary からSecondaryへゾーンを転送する構成にする。
PowerDNSでは、Primaryがゾーンの変更をSecondaryへNOTIFYで通知する。SecondaryはSOAシリアルを確認し、更新されていればAXFRでゾーンを取得する。また、NOTIFYを受信できなかった場合も、Secondaryが定期的にSOAシリアルを確認する。
用語整理
| 用語 | 正式名称 | 概要 |
|---|---|---|
| ゾーン | DNS Zone | DNS名前空間のうち、1つの管理単位として扱う範囲。この記事ではshakapon.comと、その配下のホスト名・DNSレコードをまとめたものを指す。 |
| NOTIFY | DNS NOTIFY | ゾーンが更新されたことを、PrimaryからSecondaryへ通知する仕組み。通知自体にはゾーンの内容は含まれない。 |
| AXFR | Authoritative Zone Transfer | ゾーンに含まれる全レコードを転送する方式。SecondaryがPrimaryからゾーン全体を取得するときに使用する。 |
| SOA | Start of Authority | ゾーンの管理情報を表すDNSレコード。Primaryの名前、管理者、シリアル番号、更新間隔などを保持する。 |
| SOAシリアル | Serial number | SOAレコードに含まれるゾーンの版数。SecondaryはPrimary側の値と比較し、大きくなっていればゾーンを更新する。 |
| DNSSEC | Domain Name System Security Extensions | 電子署名によってDNS応答の正当性と完全性を検証する仕組み。 |
| TSIG | Transaction Signature | 共有鍵によって特定のDNS通信を認証する仕組み。この記事ではPrimaryとSecondaryの間のNOTIFYとAXFRに使用する。 |
DNSSECとTSIG
どちらもDNS通信のなりすましや改ざんへの対策に使われるが、保護する対象と信頼の作り方が異なる。
| 比較項目 | DNSSEC | TSIG |
|---|---|---|
| 保護する対象 | ゾーン内のDNSレコード | PrimaryとSecondaryなど、特定の機器間でやり取りするDNSメッセージ |
| 主な用途 | 名前解決で受け取ったDNS応答が正当かをResolverが検証する | NOTIFY、AXFR、DNS UPDATEなどの送信元と完全性を相互に確認する |
| 鍵の方式 | 秘密鍵で署名し、公開鍵で検証する | 通信する機器同士で同じ共有鍵を保持する |
| 信頼関係 | 公開DNSでは親ゾーンのDSレコードをたどって信頼を確認する。ラボ内ではTrust Anchorを個別に設定することもできる | 事前に安全な方法で共有した鍵を信頼する。Root DNSやレジストラへの登録は不要 |
| 今回の記事 | ゾーンのDNSSEC署名は行わない | PrimaryとSecondaryの間のNOTIFYとAXFRを認証するために使用する |
DNSSECとTSIGは、どちらも鍵を使う暗号技術だが、DNSメッセージ本体を暗号化するものではない。DNSSECは電子署名によってDNSデータの出所と完全性を検証し、TSIGは共有鍵から生成したMACによって、特定の機器間でやり取りするDNSメッセージを認証して改ざんを検知する。問い合わせやゾーン転送の内容は平文のまま。ゾーン転送の内容自体を秘匿したい場合、TSIG だけでなく、XFR-over-TLS、VPN、IPsecなど別の暗号化手段が必要。
この記事では説明を簡単にするため、ゾーン転送元をIPアドレスで制限する。実運用では、後述するTSIGによるNOTIFYとゾーン転送の認証も設定する。
検証環境
| 役割 | ホスト名 | IPアドレス | Recursorの待受先 | Authoritativeの待受先 |
|---|---|---|---|---|
| Primary | dns.shakapon.com |
192.168.1.53 |
192.168.1.53:53 |
127.0.0.1:5300、192.168.1.53:5300
|
| Secondary | dns2.shakapon.com |
192.168.1.153 |
192.168.1.153:53 |
127.0.0.1:5300、192.168.1.153:5300
|
| 種別 | ソフトウェア | バージョン | 備考 |
|---|---|---|---|
| OS | Ubuntu Server | 26.04 | Primary、Secondary共通 |
| 権威DNSサーバ | PowerDNS Authoritative Server | 5.0.2-1build1 | Ubuntu公式リポジトリからインストール |
| 名前解決サーバ | PowerDNS Recursor | 5.3.5-1 | Ubuntu公式リポジトリからインストール |
| DBサーバ | PostgreSQL | 18.4 | 各DNSサーバに配置 |
既存記事と同様、クライアントからのDNS問い合わせはPowerDNS Recursorが53/tcp,udpで受け、内部ゾーンを同一ホストのAuthoritative Serverの5300/tcp,udpへ転送する。今回は、ゾーン転送のためにAuthoritative Serverの5300番ポートを相手サーバからも到達可能にする。
ゾーン転送では、NOTIFYやSOAの確認にUDP、AXFRにTCPを使用する。このため、PrimaryとSecondaryの間で5300番のTCPとUDPを許可する。
以降の手順では、設定やコマンドを実行するサーバを次のように明記する。
| 表記 | 実行場所 |
|---|---|
| Primaryで実行 |
192.168.1.53のサーバ |
| Secondaryで実行 |
192.168.1.153のサーバ |
| 任意の確認端末で実行 | 対象サーバへ通信でき、digを使用できる端末 |
Step by Step
1. Secondary 権威 DNS の構築
権威サーバの構築自体は基本的には以下の記事を参照。ここでは差分のみ記載。
1-1. Secondary 権威 DNS のpdns.conf 変更ポイント
/etc/powerdns/pdns.confを編集する。Secondaryとして動作させるため、secondary=yesを追加。
++ gpgsql-dnssec=yes
++ secondary=yes
-- local-address=127.0.0.1
++ local-address=127.0.0.1,192.168.1.153
gpgsql-dnssec=yesは、項番.6でTSIG鍵を使用するために事前に設定を仕込んでおく。
この設定だけではゾーンはDNSSEC署名されない。DNSSEC署名を行う場合、別途、ゾーンの署名鍵生成と署名設定が必要になる。今回の目的はDNSの冗長化のため、DNSSEC署名までは行わない。
local-addressには、同一ホストのRecursorから問い合わせを受ける127.0.0.1に加え、このSecondary自身のIPアドレスである192.168.1.153を指定する。local-addressは待ち受けるローカルIPアドレスの指定であり、PrimaryのIPアドレスや接続元を許可する設定ではない。PrimaryからのNOTIFYとゾーン転送を受け付ける制御は、ゾーンメタデータやファイアウォールで行う。
ゾーンメタデータ?
PowerDNS固有の概念の一つで、ゾーン単位で保持する追加設定のこと。通常のDNSレコードとは異なり、ゾーンの動作を制御するための設定値。例えば、以下がゾーンメタデータに該当する。
- ALLOW-AXFR-FROM:AXFRを許可する送信元
- ALSO-NOTIFY:NOTIFYの送信先
- TSIG-ALLOW-AXFR:AXFRで使用するTSIG鍵
- AXFR-MASTER-TSIG:SecondaryがPrimaryから取得するときのTSIG鍵
- DNSSEC関連の設定
1-2. bind.confの無効化
PowerDNS は複数のBackendを持つことができ、PostgreSQLを指定している。しかし、Ubuntu のデフォルトでは/etc/powerdns/pdns.d/bind.confも読み込まれ、launch+=bindによってBINDバックエンドが追加される場合がある。つまり、gpgsqlのほか、bindもbackend として持つことになる。
ここで PowerDNSは、1つのゾーンを1つのバックエンドで管理する構成を前提として動作する。今回の検証では、同じゾーンをBINDとgpgsqlの両方で扱うと、Secondary側でゾーン一覧への登録とAXFRによる同期が正常に進まなかった。Primary/Secondary 両者でbind.confを無効化することで事象回避できた。
無効化手順
sudo mv /etc/powerdns/pdns.d/bind.conf /etc/powerdns/pdns.d/bind.conf.disabled
ファイルを別名にし、読み込まれないようにする。
1-3. 設定反映
設定ファイルの文法を確認し、PowerDNSを起動する。
sudo pdns_server --config=check
sudo systemctl enable --now pdns
sudo systemctl status pdns
1-4. 正常性確認
5300番ポートで待ち受けていることを確認する。
sudo ss -luntp | awk 'NR == 1 || /:5300/'
1-4-1. コマンド実行例
shakapon@dns2:~$ sudo ss -luntp | awk 'NR == 1 || /:5300/'
Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp UNCONN 0 0 192.168.1.153:5300 0.0.0.0:* users:(("pdns_server",pid=16285,fd=6))
udp UNCONN 0 0 127.0.0.1:5300 0.0.0.0:* users:(("pdns_server",pid=16285,fd=5))
tcp LISTEN 0 128 127.0.0.1:5300 0.0.0.0:* users:(("pdns_server",pid=16285,fd=7))
tcp LISTEN 0 128 192.168.1.153:5300 0.0.0.0:* users:(("pdns_server",pid=16285,fd=8))
shakapon@dns2:~$
2. Primary 権威 DNS の設定変更
2-1. 権威サーバの待ち受け先変更
既存記事ではAuthoritative Serverを127.0.0.1:5300だけで待ち受けていた。このままではSecondaryからSOAを確認したりAXFRを要求したりできないため、Primaryの/etc/powerdns/pdns.confを次のように変更する。
++ gpgsql-dnssec=yes
++ primary=yes
-- local-address=127.0.0.1
++ local-address=127.0.0.1,192.168.1.53
primary=yesはPrimary機能を有効にする設定。PowerDNSではこの設定に加え、対象ゾーンの種別もPRIMARYにする必要がある。
Primaryのlocal-addressにも、同一ホストのRecursorから問い合わせを受ける127.0.0.1と、Primary自身のIPアドレスである192.168.1.53を指定する。SecondaryのIPアドレス192.168.1.153をここへ指定するのではない。SecondaryからのSOA確認とAXFRを許可する設定は、後述のALLOW-AXFR-FROMとファイアウォールで行う。
2-2. bind.confの無効化
Secondary 権威 DNSと同様、Primary 権威DNS でもbind.confを無効にする。
無効化手順
sudo mv /etc/powerdns/pdns.d/bind.conf /etc/powerdns/pdns.d/bind.conf.disabled
ファイルを別名にし、読み込まれないようにする。PowerDNS は拡張子が.conf であるファイルのみを読み込むため、別ファイル名にすればロードされない。
2-3. 設定反映
設定を確認して、PowerDNSを再起動する。
sudo pdns_server --config=check
sudo systemctl restart pdns
sudo systemctl status pdns
2-3-1. Secondary 権威 DNS の正常性確認
この時点では Primary 権威 DNS 側で明示的に見えることがあまりない。
このため Secondary 側の権威 DNS からPrimary 権威DNSへ問い合わせできることを確認する。
これは Secondaryで実行 することに注意。
dig +norecurse shakapon.com SOA @192.168.1.53 -p 5300
2-3-1-1. 正常性確認例
shakapon@dns2:~$ dig +norecurse shakapon.com SOA @192.168.1.53 -p 5300
; <<>> DiG 9.20.24-1ubuntu0.3-Ubuntu <<>> +norecurse shakapon.com SOA @192.168.1.53 -p 5300
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30807
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;shakapon.com. IN SOA
;; ANSWER SECTION:
shakapon.com. 3600 IN SOA a.misconfigured.dns.server.invalid. hostmaster.shakapon.com. 0 10800 3600 604800 3600
(SNIP)
status: NOERROR、flagsにaaが含まれること、およびSOAレコードが返ることを確認する。
この段階ではANSER SECTION でshakapon.com がa.misconfigured.dns.server.invalidとなっている。
2-4. NSレコードの追加
shakapon.comを管理する権威DNSサーバとしてSecondaryを追加する。
この操作は、ゾーンの正本を保持する Primaryでのみ実行。Secondary側のレコードは、後ほどAXFRによって自動的に作成されるため、Secondaryで実行しないこと。
2-4-1. 設定反映
sudo pdnsutil rrset add shakapon.com shakapon.com NS dns2.shakapon.com
sudo pdnsutil rrset add shakapon.com dns2.shakapon.com A 192.168.1.153
sudo pdnsutil zone increase-serial shakapon.com
コマンド実施例
shakapon@dns:~$ sudo pdnsutil rrset add shakapon.com dns2.shakapon.com A 192.168.1.153
Sep 21 05:08:57 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
New rrset:
shakapon@dns:~$
shakapon@dns:~$ sudo pdnsutil rrset add shakapon.com shakapon.com NS dns2.shakapon.com
Sep 21 05:08:50 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
New rrset:
shakapon.com. 3600 IN NS dns2.shakapon.com
dns2.shakapon.com. 3600 IN A 192.168.1.153
shakapon@dns:~$
shakapon@dns:~$ sudo pdnsutil zone increase-serial shakapon.com
Sep 21 05:10:15 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
SOA serial for zone shakapon.com set to 1
shakapon@dns:~$
2-4-2. 正常性確認
登録結果を確認する。
Primaryで実行
sudo pdnsutil zone list shakapon.com
sudo pdnsutil zone check shakapon.com
NSレコードにはポート番号を記録できない。この記事では通常の名前解決をRecursorの53番ポート、Authoritative Server間の通信を5300番ポートに分離しているため、NOTIFYの宛先は次の手順で明示する。
コマンド実施例
shakapon@dns:~$ sudo pdnsutil zone list shakapon.com
Sep 21 05:12:08 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
$ORIGIN .
(SNIP)
shakapon.com 3600 IN NS dns2.shakapon.com.
shakapon.com 3600 IN NS dns.shakapon.com.
shakapon.com 3600 IN SOA a.misconfigured.dns.server.invalid hostmaster.shakapon.com 1 10800 3600 604800 3600
shakapon@dns:~$
既存のPrimary NSレコード dns.shakapon.com は、既存記事の構築時点で登録済み。
今回新たに SecondaryのNSレコードだけを追加したdns2が表示されており、また SOAが0から1に上がっていることも確認できる。
shakapon@dns:~$ sudo pdnsutil zone check shakapon.com
Sep 21 05:12:22 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Checked 11 records of 'shakapon.com', 0 errors, 0 warnings.
errorsもwarningsも0なのでこちらもOK。
2-5. SOAレコードのMNAME変更
SOAレコードのMNAMEがデフォルト値のa.misconfigured.dns.server.invalid.になっているため、実際のPrimaryであるdns.shakapon.com.へ変更する。SOAシリアルは、項番2-3で1になった値から2へ増加させる。
2-5-1. 状態確認
現在のSOAレコードを確認する。pdnsutil 5.xにはrrset showがないため、ゾーン一覧からSOAレコードを検索する。
sudo pdnsutil zone list shakapon.com | grep -E '(^|[[:space:]])SOA([[:space:]]|$)'
コマンド実行例
shakapon@dns:~$ sudo pdnsutil zone list shakapon.com | grep -E '(^|[[:space:]])SOA([[:space:]]|$)'
Sep 21 05:37:16 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon.com 3600 IN SOA a.misconfigured.dns.server.invalid hostmaster.shakapon.com 1 10800 3600 604800 3600
shakapon@dns:~$
2-5-2. 設定変更
SOAレコードを置き換える。
sudo pdnsutil rrset replace shakapon.com shakapon.com SOA 3600 \
"dns.shakapon.com. hostmaster.shakapon.com. 2 10800 3600 604800 3600"
このコマンドは、shakapon.comゾーンのSOAレコードを指定した内容で置き換える。MNAMEをdns.shakapon.com.へ変更し、RNAMEをhostmaster.shakapon.com.、SOAシリアルを2に設定する。
コマンド実行例
shakapon@dns:~$ sudo pdnsutil rrset replace shakapon.com shakapon.com SOA 3600 \
"dns.shakapon.com. hostmaster.shakapon.com. 2 10800 3600 604800 3600"
Sep 21 05:42:19 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
All existing records for shakapon.com IN SOA will be replaced
New rrset:
shakapon.com. 3600 IN SOA dns.shakapon.com hostmaster.shakapon.com 2 10800 3600 604800 3600
shakapon@dns:~$
既存のSOAレコードが置き換えられ、新しいMNAME、RNAME、シリアルが表示されていることが分かる。
2-5-3. 正常性確認
変更後のSOAとゾーンを確認する。PowerDNS 5.xでは、4.x台であった単機能コマンドが削除されたため、少し見方が変わる。
sudo pdnsutil zone list shakapon.com | grep -E '(^|[[:space:]])SOA([[:space:]]|$)'
sudo pdnsutil zone check shakapon.com
dig +norecurse shakapon.com SOA @192.168.1.53 -p 5300 +short
1つ目のコマンドは、データベースに保存されたSOAレコードのMNAMEとシリアルを確認する。2つ目のコマンドは、ゾーン内のレコードに構文上のエラーや警告がないことを確認する。3つ目のコマンドは、PrimaryのAuthoritative Serverがネットワーク経由のDNS応答でも同じSOAを返すことを確認する。SOAのMNAMEがdns.shakapon.com.、シリアルが2になっていればよい。
コマンド実行例
shakapon@dns:~$ sudo pdnsutil zone list shakapon.com | grep -E '(^|[[:space:]])SOA([[:space:]]|$)'
Sep 21 05:42:58 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon.com 3600 IN SOA dns.shakapon.com hostmaster.shakapon.com 2 10800 3600 604800 3600
MNAMEがデフォルト値からdns.shakapon.comへ変わり、SOAシリアルが2になっていることが分かる。
shakapon@dns:~$ sudo pdnsutil zone check shakapon.com
Sep 21 05:43:04 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Checked 11 records of 'shakapon.com', 0 errors, 0 warnings.
ゾーン内の11レコードを検査し、エラーと警告がないことが分かる。
shakapon@dns:~$ dig +norecurse shakapon.com SOA @192.168.1.53 -p 5300 +short
dns.shakapon.com. hostmaster.shakapon.com. 2 10800 3600 604800 3600
shakapon@dns:~$
Primaryの5300番ポートへSOA問い合わせを行い、実際のDNS応答でもMNAMEとシリアルが正しく返ることが分かる。
2-6. ゾーン変更
既存記事のpdnsutil zone createで作成したゾーンはデフォルトの NATIVE。PrimaryとしてNOTIFYを送信させるため、ゾーンの種別をPRIMARYへ変更する。
2-6-1. 状態確認
sudo pdnsutil zone list-all native
sudo pdnsutil zone list-all primary
コマンド実行例
shakapon@dns:~$ sudo pdnsutil zone list-all native
Sep 20 14:16:23 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon.com
shakapon@dns:~$ sudo pdnsutil zone list-all primary
Sep 20 14:16:31 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon@dns:~$
2-6-2. 設定反映
sudo pdnsutil zone set-kind shakapon.com primary
sudo pdnsutil zone list-all primary
コマンド実行例
shakapon@dns:~$ sudo pdnsutil zone set-kind shakapon.com primary
Sep 21 05:23:02 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon@dns:~$ sudo pdnsutil zone list-all primary
Sep 21 05:23:06 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon.com
2-6-3. 正常性確認
sudo pdnsutil zone list-all native
sudo pdnsutil zone list-all primary
コマンド実行例
shakapon@dns:~$ sudo pdnsutil zone list-all native
Sep 21 05:23:16 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon@dns:~$ sudo pdnsutil zone list-all primary
Sep 21 05:23:20 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
shakapon.com
確かにnativeゾーンが消え、primaryゾーンにshakapon.comが移ったことが確認できる。
2-7. ゾーン転送とNOTIFYの宛先設定
ゾーン単位のALLOW-AXFR-FROMで、SecondaryからのAXFRだけを許可する。また、SecondaryのAuthoritative Serverが5300番ポートを使用しているため、ALSO-NOTIFYでポート番号を含む通知先を指定する。
2-7-1. 設定変更その1
sudo pdnsutil metadata set shakapon.com ALLOW-AXFR-FROM 192.168.1.153
sudo pdnsutil metadata set shakapon.com ALSO-NOTIFY 192.168.1.153:5300
sudo pdnsutil metadata get shakapon.com ALLOW-AXFR-FROM
sudo pdnsutil metadata get shakapon.com ALSO-NOTIFY
コマンド実行例
shakapon@dns:~$ sudo pdnsutil metadata set shakapon.com ALLOW-AXFR-FROM 192.168.1.153
Sep 21 05:47:50 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Set 'shakapon.com' meta ALLOW-AXFR-FROM = 192.168.1.153
shakapon@dns:~$ sudo pdnsutil metadata set shakapon.com ALSO-NOTIFY 192.168.1.153:5300
Sep 21 05:47:54 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Set 'shakapon.com' meta ALSO-NOTIFY = 192.168.1.153:5300
shakapon@dns:~$
shakapon@dns:~$ sudo pdnsutil metadata get shakapon.com ALLOW-AXFR-FROM
Sep 21 05:47:58 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Metadata for 'shakapon.com'
ALLOW-AXFR-FROM = 192.168.1.153
shakapon@dns:~$ sudo pdnsutil metadata get shakapon.com ALSO-NOTIFY
Sep 21 05:48:03 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Metadata for 'shakapon.com'
ALSO-NOTIFY = 192.168.1.153:5300
2-7-2. 設定変更その2
ALLOW-AXFR-FROMをゾーン単位で確実に適用するため、Primaryの/etc/powerdns/pdns.confに次の設定も追加する。
allow-axfr-ips=
これは、TSIGを使用しないAXFRに対するサーバ全体の許可リストを空= Default Denyとする。
そのうえでpdnutil metadataコマンドを用い、ゾーン単位で明示したアドレスだけを許可。
設定後、PowerDNSを再起動する。
2-7-3. 設定反映
sudo pdns_server --config=check
sudo systemctl restart pdns
3. Secondary 権威サーバへのゾーン転送
3-1. Secondaryゾーンの作成
Secondaryでshakapon.comをSecondaryゾーンとして作成し、PrimaryのAuthoritative Serverを指定する。PowerDNS 5.xではpdnsutil zone create-secondaryを使用する。
sudo pdnsutil zone create-secondary shakapon.com 192.168.1.53:5300
sudo pdnsutil zone list-all secondary
コマンド実行例
shakapon@dns2:~$ sudo pdnsutil zone create-secondary shakapon.com 192.168.1.53:5300
Sep 21 06:18:15 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
Creating secondary zone 'shakapon.com', with primaries '192.168.1.53:5300'
shakapon@dns2:~$ sudo pdnsutil zone list-all secondary
Sep 21 06:18:35 [bindbackend] Done parsing domains, 0 rejected, 0 new, 0 removed
通常は1分以内にゾーンが転送される。すぐに取得させたい場合は、Secondary DNS側で次のコマンドを実行する。
sudo pdns_control retrieve shakapon.com
コマンド実行例
shakapon@dns2:~$ sudo pdns_control retrieve shakapon.com
Added retrieval request for 'shakapon.com' from primary 192.168.1.53:5300
3-2. 正常性確認
転送されたレコードとサービスログを確認する。
sudo pdnsutil zone list shakapon.com
sudo journalctl -u pdns --since '5 minutes ago' --no-pager
コマンド実行例
shakapon@dns2:~$ sudo pdnsutil zone list shakapon.com
$ORIGIN .
(SNIP)
shakapon.com 3600 IN NS dns.shakapon.com.
shakapon.com 3600 IN NS dns2.shakapon.com.
shakapon.com 3600 IN SOA dns.shakapon.com hostmaster.shakapon.com 2 10800 3600 604800 3600
shakapon@dns2:~$
shakapon@dns2:~$ sudo journalctl -u pdns --since '5 minutes ago' --no-pager
(SNIP)
Sep 21 06:37:38 dns2 pdns_server[18336]: AXFR-in zone: 'shakapon.com', primary: '192.168.1.53', zone committed with serial 2
(SNIP)
ここのポイントでは、以下の2点を確認する。
- Primaryと同じレコードがSecondaryに登録されていること
-
zone committed with serial 2のように、ゾーンの反映完了を示すログが出力されていること
今回の場合、それぞれ以下のようであり、うまく行ったことが確認できた。
AXFR-in zoneは、SecondaryがPrimaryからAXFRを受信したことを示している。
zone committed with serial 2は、受信したゾーンをシリアル2としてDBへ反映したことを意味する。
4. Secondary 名前解決サーバ構築
ここまででSecondary 権威サーバへゾーンが転送されるようになった。続いて、クライアントからのDNS問い合わせを受け付けるPowerDNS RecursorをSecondaryにも構築する。
構築方法は既存のRecursorの記事と同じで。Primary 名前解決サーバ側との違いは、待受アドレスをSecondaryの192.168.1.153にする点だけ。
設定を確認して、Recursorを起動する。
Secondaryで実行
sudo pdns_recursor --config=check
sudo systemctl enable --now pdns-recursor
sudo systemctl status pdns-recursor
Recursorが192.168.1.153:53、Authoritative Serverが127.0.0.1:5300と192.168.1.153:5300で待ち受けていることを確認する。
Secondaryで実行
sudo ss -luntp | awk 'NR == 1 || /:53/ || /:5300/'
SecondaryのRecursor経由で、インターネット側と内部ゾーンの両方を名前解決できることを確認する。
任意の確認端末で実行
# インターネット側の名前を解決できること
dig www.google.com @192.168.1.153 +short
# Secondary Authoritative Serverへ転送されること
dig www.shakapon.com @192.168.1.153 +short
クライアントには、DNSサーバとしてPrimaryの192.168.1.53とSecondaryの192.168.1.153を設定する。どちらを優先するか、および応答がない場合にもう一方へ問い合わせるまでの時間は、クライアントOSやスタブリゾルバの実装に依存する。
5. 動作確認
5-1. PrimaryとSecondaryの応答比較
Primary/Seocndary 権威 Serverへ直接問い合わせ、両方からの回答が同じであることを確認する。
任意の確認端末で実行
dig +norecurse shakapon.com SOA @192.168.1.53 -p 5300 +short
dig +norecurse shakapon.com SOA @192.168.1.153 -p 5300 +short
dig +norecurse www.shakapon.com A @192.168.1.53 -p 5300 +short
dig +norecurse www.shakapon.com A @192.168.1.153 -p 5300 +short
PrimaryとSecondaryでSOAシリアル、およびwww.shakapon.comのAレコードが一致すれば、初回のゾーン転送は成功していることが確認できる。
5-2. レコード変更が反映されることの確認
Primaryで検証用レコードを追加する。
Primaryで実行
sudo pdnsutil rrset add shakapon.com secondary-test.shakapon.com A 192.0.2.2
sudo pdnsutil zone increase-serial shakapon.com
PowerDNSのGeneric SQLバックエンドはSOAシリアルの変化を検出し、PrimaryからSecondaryへNOTIFYを送信する。このため、レコードを変更した後にpdnsutil zone increase-serialでSOAシリアルを増加させる。Primaryから明示的に再通知したい場合は、次のコマンドも使用できる。
Primaryで実行
sudo pdns_control notify shakapon.com
実行例
shakapon@dns:~$ sudo pdns_control notify shakapon.com
Added to queue
5-3-1. DNSクライアントでの正常性確認
Secondaryへ問い合わせて、新しいレコードが返ることを確認する。
dig +norecurse secondary-test.shakapon.com A @192.168.1.153 -p 5300 +short
実行例
shakapon@dns2:~$ dig +norecurse secondary-test.shakapon.com A @192.168.1.153 -p 5300 +shor
192.0.2.2
5-3-2. Secondary 権威DNSでの正常性確認
Secondaryのログも確認する。
sudo journalctl -u pdns --since '5 minutes ago' --no-pager
実行例
shakapon@dns2:~$ sudo journalctl -u pdns --since '5 minutes ago' --no-pager
Sep 21 07:45:30 dns2 pdns_server[18336]: AXFR-in zone: 'shakapon.com', primary: '192.168.1.53', zone committed with serial 3
6. TSIG によるゾーン転送認証
項番5まででPrimary/Secondary 権威サーバ間でのゾーン転送は確立している。ゾーン転送元の制御もlocal-addressで行っており、ラボとは言え最低限のセキュリティ担保は確保してはいる。
ここではもう少しだけセキュリティ強化を狙い、TSIGによる共有鍵を使ってのNOTIFYとAXFRに認証を掛けてみる。
6-1. Primary 権威サーバでの TSIG 鍵作成
前の手順で、PrimaryとSecondaryの両方にgpgsql-dnssec=yesを設定している。
これを踏まえ、TSIG鍵を作成する。
sudo pdnsutil tsigkey generate shakapon-com-xfr hmac-sha256
sudo pdnsutil tsigkey list
sudo pdnsutil tsigkey activate shakapon.com shakapon-com-xfr primary
ここで、example-com-xfrはゾーン転送用のTSIG共有鍵の鍵の名前。名前自体は基本的に何でもよいが、PrimaryとSecondaryで同じ鍵名を指定する必要がある。
6-1-1. 実行例
shakapon@dns:~$ sudo pdnsutil tsigkey list
shakapon@dns:~$ sudo pdnsutil tsigkey generate shakapon-com-xfr hmac-sha256
Create new TSIG key shakapon-com-xfr hmac-sha256 XXXXXXXXXXXXXXXXXXXX
shakapon@dns:~$ sudo pdnsutil tsigkey list
shakapon-com-xfr. hmac-sha256. XXXXXXXXXXXXXXXXXXXXT
shakapon@dns:~$ sudo pdnsutil tsigkey activate shakapon.com shakapon-com-xfr primary
Enabled TSIG key shakapon-com-xfr for shakapon.com
6-2. Secondary 権威サーバでの TSIG 鍵登録
表示されたBase64形式の共有鍵を安全な方法でSecondaryへ渡し、Secondary側へ同じ鍵を登録する。次のBASE64_ENCODED_SECRETは、実際に生成された値へ置き換えること。
sudo pdnsutil tsigkey import shakapon-com-xfr hmac-sha256 'BASE64_ENCODED_SECRET'
sudo pdnsutil tsigkey activate shakapon.com shakapon-com-xfr secondary
sudo pdns_control retrieve shakapon.com
6-2-1. 実行例
shakapon@dns2:~$ sudo pdnsutil tsigkey import shakapon-com-xfr hmac-sha256 T5gg1VrWIw67DN976Asr0SeUSF3whkdJjfcoL6lMfBvVbx8186RLH1eF4RCaCAIjF1m+BNIWBNXzjMtY44mnMA==
Imported TSIG key shakapon-com-xfr hmac-sha256
shakapon@dns2:~$ sudo pdnsutil tsigkey activate shakapon.com shakapon-com-xfr secondary
Enabled TSIG key shakapon-com-xfr for shakapon.com
shakapon@dns2:~$ sudo pdns_control retrieve shakapon.com
Added retrieval request for 'shakapon.com' from primary 192.168.1.53:5300
6-3. 正常性確認
PrimaryではTSIG-ALLOW-AXFR、SecondaryではAXFR-MASTER-TSIGのゾーンメタデータが設定される。登録結果は次のコマンドで確認できる。
Primaryで実行
sudo pdnsutil metadata get shakapon.com TSIG-ALLOW-AXFR
正常性確認例
shakapon@dns:~$ sudo pdnsutil metadata get shakapon.com TSIG-ALLOW-AXFR
Metadata for 'shakapon.com'
TSIG-ALLOW-AXFR = shakapon-com-xfr
Secondaryで実行
sudo pdnsutil metadata get shakapon.com AXFR-MASTER-TSIG
正常性確認例
shakapon@dns2:~$ sudo pdnsutil metadata get shakapon.com AXFR-MASTER-TSIG
Metadata for 'shakapon.com'
AXFR-MASTER-TSIG = shakapon-com-xfr