- 1 はじめに
- 2 検証環境
- 3 インストール方法
- 4 ポート番号の開放
- 5 プライマリーサーバの設定
- 6 セカンダリーサーバの設定
- 7 設定ファイル、ゾーンファイルの構文チェック
- 8 セカンダリサーバ起動時のシーケンス
- 9 セカンダリサーバ起動後のシーケンス
- 10 ゾーンファイル編集後のシーケンス
- 11 ゾーンファイルの転送確認
- Y 参考図書
- Z 参考情報
1 はじめに
DNSの運用では、複数の権威DNSサーバを用意するのが一般的です。複数の権威DNSサーバを運用する場合、全ての権威DNSサーバでゾーンファイルを一致させる必要があります。管理者がこれを手作業で行うのは手間がかかり、ミスも発生します。このため、DNSでは複数の権威DNSサーバでゾーンファイルを同期するゾーン転送という仕組みがあります。ゾーンファイルを管理する権威DNSサーバをプライマリーサーバと呼び、ゾーン転送によってゾーンファイルのコピーを受け取り運用するサーバをセカンダリーサーバと呼びます。なお、検証に使うドメイン名は、RFC 2606 - Reserved Top Level DNS Namesで以下のように記述されているので、abc.testとします。
".test" is recommended for use in testing of current or new DNS related code.
DNSの名前解決の様子は、digコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
2 検証環境
3 インストール方法
プライマリーサーバとセカンダリーサーバで bindパッケージ、bind-utilsパッケージをインストールします。なお、dnfコマンドの使い方は、dnfコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
[root@primary ~]# dnf -y install bind bind-utils
BINDの版数を確認します。
[root@primary ~]# named -v BIND 9.16.23-RH (Extended Support Version) <id:fde3b1f>
4 ポート番号の開放
ゾーン転送に使うTCP/UDPのポート番号53を解放します。なお、firewall-cmdの使い方は、firewall-cmdの使い方 - hana_shinのLinux技術ブログを参照してください。
4.1 プライマリーサーバのポート番号開放
[root@primary ~]# firewall-cmd --add-port=53/tcp success [root@primary ~]# firewall-cmd --add-port=53/udp success
開放したポート番号を確認します。
[root@primary ~]# firewall-cmd --list-ports 53/tcp 53/udp
4.2 セカンダリーサーバのポート番号開放
[root@secondary ~]# firewall-cmd --add-port=53/tcp success [root@secondary ~]# firewall-cmd --add-port=53/udp success
開放したポート番号を確認します。
[root@secondary ~]# firewall-cmd --list-ports 53/tcp 53/udp
5 プライマリーサーバの設定
5.1 設定ファイルの編集
設定ファイル編集前後の差分を確認するため、バックアップファイルを作成します。
[root@primary ~]# cp /etc/named.conf /etc/named.conf.org
設定ファイルの差分を確認します。
[root@primary ~]# vi /etc/named.conf [root@primary ~]# diff -Nur /etc/named.conf.org /etc/named.conf --- /etc/named.conf.org 2023-05-21 20:12:04.638427807 +0900 +++ /etc/named.conf 2023-05-27 19:59:22.375933433 +0900 @@ -8,7 +8,7 @@ // options { - listen-on port 53 { 127.0.0.1; }; + listen-on port 53 { 192.168.122.16; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; @@ -16,7 +16,7 @@ memstatistics-file "/var/named/data/named_mem_stats.txt"; secroots-file "/var/named/data/named.secroots"; recursing-file "/var/named/data/named.recursing"; - allow-query { localhost; }; + allow-query { any; }; /* - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion. @@ -28,7 +28,7 @@ attacks. Implementing BCP38 within your network would greatly reduce such attack surface */ - recursion yes; + recursion no; dnssec-validation yes; @@ -57,3 +57,9 @@ include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; +zone "abc.test" IN { + type master; + file "abc.test.db"; + allow-transfer { 192.168.122.213; }; + notify yes; +};
設定変更したステートメントの意味を以下に示します。
ステートメント | 意味 |
---|---|
listen-on | DNSサーバが問い合わせを受け付けるIPアドレスを設定します。 |
allow-query | DNSクエリーを受け付けるDNSクライアントのIPアドレスを設定します。ここでは、全てのDNSクライアントからのDNSクエリを受け付けるanyを設定します。 |
recursion | 再帰問い合わせを受け付けるかどうかを設定します。DNS権威サーバは再帰クエリは受け付けないのでnoを設定します |
type | DNSサーバがプライマリーサーバか、セカンダリーサーバなのかを設定します。プライマリーサーバはmaster、セカンダリーサーバはslave、DNSキャッシュサーバはhintを設定します。 |
file | ゾーンファイル名を設定します。ゾーンファイルは、directoryステートメントで指定したディレクトリ以下に格納されます |
allow-transfer | ゾーンファイルの転送を許可するセカンダリーサーバのIPアドレスを設定します。 |
notify | プライマリーサーバのゾーンファイルが更新された時、セカンダリーサーバに更新があったことを通知するかどうかを設定します。通知する場合はyes、通知しない場合はnoを設定します。 |
5.2 ゾーンファイルの作成
ゾーン転送の動作確認をするため、正引きのゾーンファイルのみを作成します。ゾーン転送はゾーンファイルのSOAレコードで制御されます。なお、SOAレコードのパラメータの意味は、digコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
[root@primary ~]# vi /var/named/abc.test.db [root@primary ~]# cat /var/named/abc.test.db $ORIGIN abc.test. $TTL 3600 @ IN SOA primary.abc.test. root.abc.test. ( 2023052801 ; serial 300 ; refresh 900 ; retry 3600 ; expire 3600 ) ; minimum NS primary.abc.test. primary A 192.168.122.16
6 セカンダリーサーバの設定
6.1 設定ファイルの編集
設定ファイル編集前後の差分を確認するため、バックアップファイルを作成します。
[root@secondary ~]# cp /etc/named.conf /etc/named.conf.org
設定ファイルの差分を確認します。
[root@secondary ~]# vi /etc/named.conf [root@secondary ~]# diff -Nur /etc/named.conf.org /etc/named.conf --- /etc/named.conf.org 2023-05-21 20:16:02.611164689 +0900 +++ /etc/named.conf 2023-05-21 20:18:38.335385768 +0900 @@ -8,7 +8,7 @@ // options { - listen-on port 53 { 127.0.0.1; }; + listen-on port 53 { 192.168.122.213; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; @@ -16,7 +16,7 @@ memstatistics-file "/var/named/data/named_mem_stats.txt"; secroots-file "/var/named/data/named.secroots"; recursing-file "/var/named/data/named.recursing"; - allow-query { localhost; }; + allow-query { any; }; /* - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion. @@ -28,7 +28,7 @@ attacks. Implementing BCP38 within your network would greatly reduce such attack surface */ - recursion yes; + recursion no; dnssec-validation yes; @@ -57,3 +57,8 @@ include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; +zone "abc.test" IN { + type slave; + file "slaves/abc.test.db"; + masters { 192.168.122.16; }; +};
7 設定ファイル、ゾーンファイルの構文チェック
設定ファイル、およびゾーンファイルの構文が正しいかどうかをチェックします。それぞれ、以下のコマンドでチェックすることができます。
・named-checkconf:設定ファイル(named.conf)の構文チェック
・named-checkzone:ゾーンファイルの構文チェック
7.1 プライマリーサーバ
named-checkconfコマンドを使って、プライマリーサーバの設定ファイルの構文をチェックします。named-checkconfコマンドが正常終了しているので、設定ファイルに誤りがないことがわかります。
[root@primary ~]# named-checkconf /etc/named.conf [root@primary ~]#
named-checkzoneコマンドを使って、プライマリーサーバのゾーンファイルの構文をチェックします。named-checkzoneコマンドが正常終了しているので、ゾーンファイルに誤りがないことがわかります。
[root@primary ~]# named-checkzone abc.test /var/named/abc.test.db zone abc.test/IN: loaded serial 2023052801 OK
8 セカンダリサーバ起動時のシーケンス
セカンダリサーバ起動時、プライマリサーバからセカンダリサーバにゾーンファイルが転送されます。その時の状況を確認してみます。
プライマリーサーバでnamedサービスを起動します。
[root@primary ~]# systemctl start named
セカンダリーサーバのゾーンファイルを確認すると、まだゾーンファイルが存在しないことがわかります。
[root@secondary ~]# ls -l /var/named/slaves 合計 0
セカンダリーサーバでnamedサービスを起動します。
[root@secondary ~]# systemctl start named
セカンダリーサーバでnamedサービスを起動すると、プライマリーサーバからセカンダリサーバにゾーンファイルが転送されたことがわかります。
[root@secondary ~]# ls -l /var/named/slaves/abc.test.db -rw-r--r--. 1 named named 203 5月 31 20:03 /var/named/slaves/abc.test.db
ゾーンファイルはバイナリファイルなので、named-compilezoneコマンドを使ってテキストファイルに変換します。
[root@secondary ~]# named-compilezone -f raw -F text -o /tmp/abc.test.db abc.test. /var/named/slaves/abc.test.db zone abc.test/IN: loaded serial 2023052801 dump zone to /tmp/abc.test.db...done OK
ゾーンファイルを確認すると、プライマリサーバのゾーンファイルが転送されたことがわかります。
[root@secondary ~]# cat /tmp/abc.test.db abc.test. 3600 IN SOA primary.abc.test. root.abc.test. 2023052801 300 900 3600 3600 abc.test. 3600 IN NS primary.abc.test. primary.abc.test. 3600 IN A 192.168.122.16
tcpdumpコマンドで採取したゾーン転送時のキャプチャファイルを以下に示します。
キャプチャファイルのシーケンスを以下に示します。まず、セカンダリサーバはUDPを使用してゾーンファイルの転送を要求します。そして、ゾーンファイルが存在する場合は、TCPコネクションを確立し、ゾーンファイルの転送を行います。ゾーンファイルの転送が完了すると、セカンダリサーバはTCPコネクションをクローズします。
プライマリーサーバ セカンダリーサーバ TCP/53 UDP/53 UDP/53 TCP/53 | | | | | |<----- DNS query ------------| | --- | | | | | <= ゾーンファイルの確認 | |------ DNS query response -->| | --- | | | | |<---------|------ TCP SYN --------------|----------| --- |----------|------ TCP SYN+ACK ----------|--------->| | <= TCPコネクションの確立 |<---------|------ TCP ACK --------------|----------| --- | | | | |<---------|------ DNS query ------------|----------| --- | | | | | <= ゾーンファイルの転送 |----------|------ DNS query response ---|--------->| --- | | | | |<---------|------ TCP FIN --------------|----------| --- |----------|------ TCP FIN+ACK ----------|--------->| | <= TCPコネクションのクローズ |<---------|------ TCP ACK --------------|----------| --- | | | |
9 セカンダリサーバ起動後のシーケンス
セカンダリサーバが起動した後、プライマリサーバとのパケットのやりとりを確認してみます。セカンダリサーバは定期的にプライマリサーバに対してゾーンファイルの更新があるかどうかをチェックします。このチェックはおおよそ4分の間隔で行われています。私はSOAレコードのrefreshで指定した間隔で行われると思っていたため、5分間隔で行われると考えていました。しかし、実際は違っていました。なぜ5分間隔でチェックが行われないのかについて、ご存じの方がいらっしゃいましたら、教えていただけませんか。
[root@secondary ~]# tcpdump -i eth0 host 192.168.122.16 and port 53 -v -nn dropped privs to tcpdump tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 21:46:00.719188 IP (tos 0x0, ttl 64, id 12655, offset 0, flags [none], proto UDP (17), length 69) 192.168.122.213.42212 > 192.168.122.16.53: 34635 [1au] SOA? abc.test. (41) 21:46:00.724449 IP (tos 0x0, ttl 64, id 27651, offset 0, flags [none], proto UDP (17), length 152) 192.168.122.16.53 > 192.168.122.213.42212: 34635*- 1/1/2 abc.test. SOA primary.abc.test. root.abc.test. 2023052801 300 900 3600 3600 (124) 21:49:53.730645 IP (tos 0x0, ttl 64, id 63337, offset 0, flags [none], proto UDP (17), length 69) 192.168.122.213.32943 > 192.168.122.16.53: 17190 [1au] SOA? abc.test. (41) 21:49:53.738170 IP (tos 0x0, ttl 64, id 14792, offset 0, flags [none], proto UDP (17), length 152) 192.168.122.16.53 > 192.168.122.213.32943: 17190*- 1/1/2 abc.test. SOA primary.abc.test. root.abc.test. 2023052801 300 900 3600 3600 (124) 21:54:36.741113 IP (tos 0x0, ttl 64, id 58342, offset 0, flags [none], proto UDP (17), length 69) 192.168.122.213.48592 > 192.168.122.16.53: 27517 [1au] SOA? abc.test. (41) 21:54:36.747100 IP (tos 0x0, ttl 64, id 32930, offset 0, flags [none], proto UDP (17), length 152) 192.168.122.16.53 > 192.168.122.213.48592: 27517*- 1/1/2 abc.test. SOA primary.abc.test. root.abc.test. 2023052801 300 900 3600 3600 (124) -snip-
10 ゾーンファイル編集後のシーケンス
ゾーンファイルを編集します。シリアル番号を1増やして、wwwサーバのリソースレコードを1つ追加します。
[root@primary ~]# vi /var/named/abc.test.db [root@primary ~]# diff -Nur /var/named/abc.test.db.org /var/named/abc.test.db --- /var/named/abc.test.db.org 2023-06-01 19:58:07.222806548 +0900 +++ /var/named/abc.test.db 2023-06-01 19:50:41.223070363 +0900 @@ -1,10 +1,11 @@ $ORIGIN abc.test. $TTL 3600 @ IN SOA primary.abc.test. root.abc.test. ( - 2023052801 ; serial + 2023052802 ; serial 300 ; refresh 900 ; retry 3600 ; expire 3600 ) ; minimum NS primary.abc.test. primary A 192.168.122.16 +www A 192.168.122.20
ゾーンファイルを編集したら、namedを再起動します。
[root@primary ~]# rndc reload server reload successful
tcpdumpコマンドを使って、ゾーン転送時のパケットをキャプチャします。
[root@secondary ~]# tcpdump -i eth0 host 192.168.122.16 and port 53 -v -nn dropped privs to tcpdump tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes -snip- 19:54:33.608079 IP (tos 0x0, ttl 64, id 14416, offset 0, flags [none], proto UDP (17), length 69) 192.168.122.213.36158 > 192.168.122.16.53: 52391 [1au] SOA? abc.test. (41) 19:54:33.612003 IP (tos 0x0, ttl 64, id 34989, offset 0, flags [none], proto UDP (17), length 152) 192.168.122.16.53 > 192.168.122.213.36158: 52391*- 1/1/2 abc.test. SOA primary.abc.test. root.abc.test. 2023052802 300 900 3600 3600 (124) 19:54:33.613313 IP (tos 0x0, ttl 64, id 59507, offset 0, flags [none], proto TCP (6), length 60) 192.168.122.213.34845 > 192.168.122.16.53: Flags [S], cksum 0x7665 (incorrect -> 0x89b9), seq 256144245, win 64240, options [mss 1460,sackOK,TS val 2617157140 ecr 0,nop,wscale 7], length 0 19:54:33.615881 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 192.168.122.16.53 > 192.168.122.213.34845: Flags [S.], cksum 0x5884 (correct), seq 62942961, ack 256144246, win 65160, options [mss 1460,sackOK,TS val 75478619 ecr 2617157140,nop,wscale 7], length 0 19:54:33.616054 IP (tos 0x0, ttl 64, id 59508, offset 0, flags [none], proto TCP (6), length 52) 192.168.122.213.34845 > 192.168.122.16.53: Flags [.], cksum 0x765d (incorrect -> 0x83e0), ack 1, win 502, options [nop,nop,TS val 2617157143 ecr 75478619], length 0 19:54:33.616912 IP (tos 0x0, ttl 64, id 59509, offset 0, flags [none], proto TCP (6), length 129) 192.168.122.213.34845 > 192.168.122.16.53: Flags [P.], cksum 0x76aa (incorrect -> 0xd6cf), seq 1:78, ack 1, win 502, options [nop,nop,TS val 2617157144 ecr 75478619], length 77 9258 [1n] IXFR? abc.test. (75) 19:54:33.619731 IP (tos 0x0, ttl 64, id 65243, offset 0, flags [DF], proto TCP (6), length 52) 192.168.122.16.53 > 192.168.122.213.34845: Flags [.], cksum 0x8388 (correct), ack 78, win 509, options [nop,nop,TS val 75478622 ecr 2617157144], length 0 19:54:33.621098 IP (tos 0x0, ttl 64, id 65244, offset 0, flags [DF], proto TCP (6), length 215) 192.168.122.16.53 > 192.168.122.213.34845: Flags [P.], cksum 0x486d (correct), seq 1:164, ack 78, win 509, options [nop,nop,TS val 75478624 ecr 2617157144], length 163 9258*- 5/0/0 abc.test. SOA primary.abc.test. root.abc.test. 2023052802 300 900 3600 3600, abc.test. NS primary.abc.test., primary.abc.test. A 192.168.122.16, www.abc.test. A 192.168.122.20, abc.test. SOA primary.abc.test. root.abc.test. 2023052802 300 900 3600 3600 (161) 19:54:33.621139 IP (tos 0x0, ttl 64, id 59510, offset 0, flags [none], proto TCP (6), length 52) 192.168.122.213.34845 > 192.168.122.16.53: Flags [.], cksum 0x765d (incorrect -> 0x82e7), ack 164, win 501, options [nop,nop,TS val 2617157148 ecr 75478624], length 0 19:54:33.623264 IP (tos 0x0, ttl 64, id 59511, offset 0, flags [none], proto TCP (6), length 52) 192.168.122.213.34845 > 192.168.122.16.53: Flags [F.], cksum 0x765d (incorrect -> 0x82e4), seq 78, ack 164, win 501, options [nop,nop,TS val 2617157150 ecr 75478624], length 0 19:54:33.625855 IP (tos 0x0, ttl 64, id 65245, offset 0, flags [DF], proto TCP (6), length 52) 192.168.122.16.53 > 192.168.122.213.34845: Flags [F.], cksum 0x82d6 (correct), seq 164, ack 79, win 509, options [nop,nop,TS val 75478629 ecr 2617157150], length 0 19:54:33.625906 IP (tos 0x0, ttl 64, id 59512, offset 0, flags [none], proto TCP (6), length 52) 192.168.122.213.34845 > 192.168.122.16.53: Flags [.], cksum 0x765d (incorrect -> 0x82db), ack 165, win 501, options [nop,nop,TS val 2617157153 ecr 75478629], length 0
named-compilezoneコマンドを使って、ゾーンファイルをテキストファイルに変換します。
[root@secondary ~]# named-compilezone -f raw -F text -o /tmp/abc.test.db abc.test. /var/named/slaves/abc.test.db zone abc.test/IN: loaded serial 2023052802 dump zone to /tmp/abc.test.db...done OK
ゾーンファイルを確認すると、シリアル番号が1つ増加したことと、wwwサーバのリソースレコードが追加されたことがわかります。
[root@secondary ~]# cat /tmp/abc.test.db abc.test. 3600 IN SOA primary.abc.test. root.abc.test. 2023052802 300 900 3600 3600 abc.test. 3600 IN NS primary.abc.test. primary.abc.test. 3600 IN A 192.168.122.16 www.abc.test. 3600 IN A 192.168.122.20
11 ゾーンファイルの転送確認
ゾーンファイルを転送したセカンダリーサーバに対して名前解決を要求してみます。まず、primary.abc.testのIPアドレスの解決を要求してみます。primary.abc.testのIPアドレスが192.168.122.16であることがわかります。
[root@primary ~]# dig @192.168.122.213 primary.abc.test +short 192.168.122.16
次に、www.abc.testのIPアドレスの解決を要求してみます。www.abc.testのIPアドレスが192.168.122.20であることがわかります。
[root@primary ~]# dig @192.168.122.213 www.abc.test +short 192.168.122.20
Y 参考図書
TECHNICAL MASTER はじめてのAlmaLinux 9 & Rocky Linux 9 Linuxサーバエンジニア入門編
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ
BIND 9 Administrator Reference Manual — BIND 9 9.19.22-dev documentation