test.com ゾーン転送の DNSSEC 対応

balaeniceps-rex DNS

test.com のゾーンデータに対する DNSSEC の署名を自動で行います。

※ここでは実際に設定、動作したものを掲載していますが、内容について保証するものではありません。流用される場合は各自の責任でお願いします。

構築する環境の要件等については「ローカル環境にDNS問い合わせの仕組みを構築」をご参照ください。

全体の構築作業は以下のとおりですが、今回は「⑤ test.com ゾーン転送の DNSSEC 対応」を実施します。

権威サーバとキャッシュサーバの構築
権威サーバの DNSSEC 対応
test.com ゾーンの追加とゾーン転送の設定
test.com ゾーン転送の TSIG 対応
⑤ test.com ゾーン転送の DNSSEC 対応

今回の構築範囲は下図のとおりです。

dns-structure-physical-5

以下のようなゾーン転送を行う DNS サーバが構成済みの想定です。

master(BIND) ⇒ 中継(Knot) ⇒ slave(BIND)

今回、ゾーン転送の最中に DNSSEC 署名を自動的に行う設定を追加します。

  • master(BIND)は test.com のゾーンデータの原本を管理します。ここでは署名処理は行いません。
  • 中継(Knot)は master(BIND)からゾーンデータを受け取り、署名処理後、ゾーンデータ(署名済み)を slave(BIND)に転送します。
  • slave(BIND)は中継(Knot)からゾーンデータ(署名済み)を受け取ります。
  • ゾーンデータの署名時、DS レコード (*1) が生成されます。DS レコードは上位ドメイン(com)の NS に登録します。

*1 ゾーンデータは ZSK 秘密鍵で署名され、署名の検証は ZSK 公開鍵で行われます。さらに ZSK 公開鍵は KSK の秘密鍵で署名され、署名の検証は KSK の公開鍵で行われます。DS レコードは KSK の公開鍵をハッシュ化したものです。

master と slave(いずれも BIND)の設定

BIND のコンフィグ設定

BIND の named.conf について、わかる範囲で解説します。

DNSSEC に対応するため、options で dnssec-enable と dnssec-validation を yes にします。options での設定はデフォルトの設定となります。(view(TEST.COM-SLAVE1 および TEST.COM-SLAVE2)への個別の設定は行いません)ただし、master は DNSSEC 署名を行わないため、view(TEST.COM-MASTER)内で dnssec-enable と dnssec-validation を no とします。

options {
  …
  dnssec-enable     yes;
  dnssec-validation yes;
  …
};

view "TEST.COM-MASTER" {
  …
  dnssec-enable     no;
  dnssec-validation no;
  …
};

編集後、コンフィグをチェックします。(→ 何も出力がなければ問題ありません)

[root@auth ~]# named-checkconf
[root@auth ~]#

中継(Knot)の設定

Knot のコンフィグ設定

Knot の knot.conf について、わかる範囲で解説します。

policy: では、DNSSEC の署名ポリシーを定義します。
nsec3: on は、リソースレコードの不在証明に NSEC3 レコードを使用することを指定しています。nsec3: のデフォルトは off です。その場合、 NSEC レコード(古い不在証明)を使用することになります。

参考:NSEC3 についての補足
DNSSEC ではリソースレコードの署名で正当性を検証しますが、リソースレコードが存在しない場合、署名も存在しないため、”存在しないこと”の検証ができません。つまり、悪意のあるサーバから、”該当するリソースレコードは存在しない”と応答があった場合、それが正しいかどうかを判断できません。
そのため、DNSSECでは存在しないリソースレコードについては、NSEC レコード (*1) およびその署名で”存在しないこと”を検証します。
ですが、この仕組みによりゾーン内の全てのドメイン名が外部から確認できてしまいます。これを避けるため、NSEC レコードのドメイン名をハッシュ化した NSEC3 レコードが規定されています。

*1 NSEC レコードは存在しないリソースレコードの範囲を示します。例えば、”ドメイン名 A の次は F、なのでその間の B ~ E は存在しない”みたいな内容になっています。
policy:
  - id: nsec3
    nsec3: on

template: では、ゾーン(zone: で定義)に適用するためのテンプレート(通信条件をまとめたもの)を定義しています。id: が default のテンプレートは、ゾーンにデフォルトで適用されるため、zone: での明示的な指定はありません。今回 DNSSEC に対応するため、dnssec-signing:、dnssec-policy:、serial-policy: を追加しています。

template:
  - id: default
    …
    dnssec-signing: on
    dnssec-policy: nsec3
    serial-policy: unixtime
(補足)
dnssec-signing : on を指定することでゾーンの自動署名を有効にします。
dnssec-policy : policy: で定義した、id: nsec3 を指定しています。
serial-policy : ゾーンのシリアル番号の採番方式に unix-time(エポックタイム)を指定しています。(*1)

*1 unix-time 以外に increment(シリアル番号をインクリメント)、dateserial(日付フォーマット(YYYYMMDDnn))が指定可能です。
参考:親ゾーンの DS レコード更新について

ゾーンの署名に使用した鍵(ZSK)の正当性は親ドメインに保証してもらいます。
具体的には、ゾーンデータを鍵(ZSK)で署名し、ZSK を鍵(KSK)で署名し、KSK 公開鍵のハッシュを DS レコードとして親ゾーンに登録します。

Knot では DNSSEC 署名の際に、DS レコードの更新を親ゾーンにリクエストする機能があります。親ゾーンが CDS に対応していれば自動的に DS レコードが更新されます。

今回 Knot では、親ゾーン(com)へのリクエストを設定していますが、本環境の com ドメインは CDS に対応していない(単に設定方法を確認できていないだけですが)ため、com ゾーンに登録している DS レコードの自動更新は行われません。

以下、親ゾーンへのリクエストに関する設定です。(自動更新に対応しない場合は以下の設定は不要です)

通信相手の定義です。172.18.1.12 は com NS のアドレスです。

remote:
  …
  - id: auth_com
    address: 172.18.1.12
    via: 172.18.1.21

以下も DS レコードの自動更新に必要な定義らしいです。(勉強不足のためどのような機能かは理解していません)

submission:
  - id: ds_submission
    parent: auth_com

policy:
  - id: nsec3
    …
    ksk-submission: ds_submission

編集後にコンフィグをチェックします。

[root@auth ~]# knotc conf-check
Configuration is valid

test.com の疎通確認

中継(Knot)への疎通を確認します。(→ NOERROR / do(dnssec ok) であれば正常)

[root@auth ~]# dig @172.18.1.21 test.com soa +dnssec +multi +norec | grep -E 'status|flags|RRSIG'
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26266
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
; EDNS: version: 0, flags: do; udp: 1232
test.com.               604800 IN RRSIG SOA 13 2 604800 (

slave への疎通を確認します。(→ NOERROR / do(dnssec ok) であれば正常)

; slave1
[root@auth ~]# dig @172.18.1.22 test.com soa +dnssec +multi +norec | grep -E 'status|flags|RRSIG'
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62818
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5
; EDNS: version: 0, flags: do; udp: 1232
test.com.               604800 IN RRSIG SOA 13 2 604800 (
test.com.               604800 IN RRSIG NS 13 2 604800 (
ns1.test.com.           604800 IN RRSIG A 13 3 604800 (
ns2.test.com.           604800 IN RRSIG A 13 3 604800 (

; slave2
[root@auth ~]# dig @172.18.1.23 test.com soa +dnssec +multi +norec | grep -E 'status|flags|RRSIG'
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21316
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5
; EDNS: version: 0, flags: do; udp: 1232
test.com.               604800 IN RRSIG SOA 13 2 604800 (
test.com.               604800 IN RRSIG NS 13 2 604800 (
ns1.test.com.           604800 IN RRSIG A 13 3 604800 (
ns2.test.com.           604800 IN RRSIG A 13 3 604800 (

各ゾーンファイルは以下のとおり。master 以外のゾーンファイルはゾーン転送後、自動署名されています。

機能ゾーンファイル
mastertest.com.zone
中継(Knot)test.com.zone
slave1test.com.zone1
slave2test.com.zone2

上位ドメインへの DNSSEC 署名連鎖の設定

test.com ゾーンデータの署名は ZSK 公開鍵で検証し、ZSK の署名は KSK 公開鍵で検証しますが、KSK 公開鍵の正当性は、親ドメイン(com)に保証してもらいます。そのために KSK 公開鍵のハッシュである DS レコードを com ゾーンに登録する必要があります。

以下に手順を示します。

DS レコードをファイルに出力します。(dsset-test.com. 以外のファイルは「権威サーバの DNSSEC 対応」で作成されたファイルです)

[root@auth ~]# keymgr test.com ds > /var/named/keys/dsset-test.com.
[root@auth ~]# cat /var/named/keys/dsset-test.com.
test.com. DS 55474 13 2 f6e90004c7822ebb1eadcdebfa3d20c03e308dd3e5c5e0d04a536a692ea1b0e6
test.com. DS 55474 13 4 939736fa9e96a2e58bab97b05d9eb743c0a367811f2a1b7b052c662c7e0ce2e031eb01fe6ce763ea2c2a2445bfa4b176
[root@auth ~]# ls -l /var/named/keys/dsset-*
-rw-r--r--. 1 root root 147 Oct  3 10:08 /var/named/keys/dsset-.
-rw-r--r--. 1 root root 151 Oct  3 10:04 /var/named/keys/dsset-com.
-rw-r--r--. 1 root root 151 Oct  3 10:03 /var/named/keys/dsset-jp.
-rw-r--r--. 1 root root 165 Oct  3 09:59 /var/named/keys/dsset-test.co.jp.
-rw-r--r--. 1 root root 210 Oct  9 14:08 /var/named/keys/dsset-test.com.

親ドメインのゾーンファイル(com.zone)に test.com の委任情報と、DS レコードファイルの INCLUDE を追加します。

[root@auth ~]# vi /var/named/com.zone
[root@auth ~]# grep test.com /var/named/com.zone
test                IN NS   ns1.test.com.
test                IN NS   ns2.test.com.
ns1.test.com.       IN A    172.18.1.22
ns2.test.com.       IN A    172.18.1.23
$INCLUDE /var/named/keys/dsset-test.com.
[root@auth ~]#

ゾーンファイルをチェックします。(OK が出力されれば正常)

[root@auth ~]# named-checkzone com /var/named/com.zone
[root@auth ~]#
…
OK

com ドメインのゾーンを署名しなおします。(前回署名は「権威サーバの DNSSEC 対応」で行われています)

[root@auth ~]# cd /var/named/keys
[root@auth keys]# ComZskName=`cat zsk-com`; ComKskName=`cat ksk-com`; echo $ComZskName $ComKskName
Kcom.+008+44484 Kcom.+008+09944
[root@auth keys]# dnssec-signzone -H 3 -3 123ABC -N unixtime -k ${ComKskName} -o com /var/named/com.zone ${ComZskName}
Verifying the zone using the following algorithms: RSASHA256.
Zone fully signed:
Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                      ZSKs: 1 active, 0 stand-by, 0 revoked
/var/named/com.zone.signed

ゾーンファイルの所有者と権限を書き換えます。

[root@auth keys]# chown root.named /var/named/com.zone.signed
[root@auth keys]# chmod 640 /var/named/com.zone.signed
[root@auth keys]# ls -l /var/named/*.signed
-rw-r-----. 1 root named  4592 Oct  9 14:43 /var/named/com.zone.signed
-rw-r-----. 1 root named  9936 Oct  3 10:03 /var/named/jp.zone.signed
-rw-r-----. 1 root named 12637 Oct  3 10:08 /var/named/root.zone.signed
-rw-r-----. 1 root named  4138 Oct  3 09:59 /var/named/test.co.jp.zone.signed

BIND のコンフィグをリロードします。

[root@auth keys]# rndc reload
server reload successful

署名前後の com ドメインのゾーンファイルは以下のとおりです。

署名ゾーンファイル
com.zone
com.zone.signed

※ 今回、test.com ゾーンの dnssec 化に伴い、DS レコードを com のゾーンに新規登録したため、com ゾーンも署名しなおしましたが、さらに上位のゾーン(ルート(.))については再度の署名は行っていません。これは、com で使用している KSK については前回の署名時から変更しておらず、ルート(.) ゾーンに登録されている DS レコード(KSK 公開鍵のハッシュ)にも変更が無いためです。

動作確認

再帰問い合わせ(キャッシュサーバ経由での権威サーバへの問い合わせ)で名前が解決できることを確認します。(→ NOERROR かつ ad(Authentic Data=署名が検証できた正しいデータ)のフラグがあれば正常)

[root@cache ~]# dig @127.1 www.test.com a +dnssec

; <<>> DiG 9.11.36-RedHat-9.11.36-16.el8_10.2 <<>> @127.1 www.test.com a +dnssec
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24593
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: f8867463ad6da990963786e967062ad1ccc7a99dd292a84e (good)
;; QUESTION SECTION:
;www.test.com.                  IN      A

;; ANSWER SECTION:
www.test.com.           604781  IN      A       3.4.5.6
www.test.com.           604781  IN      RRSIG   A 13 3 604800 20241023025848 20241009012848 62503 test.com. iAId3UOW1vkd/1ouV42czZ1/PqvNbp4/MwpmPb+f8pNTSMu5LdU+4day h1BA8EJ3vCpsHAqhkOizTZqabxXfVQ==

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Oct 09 16:03:45 JST 2024
;; MSG SIZE  rcvd: 189

test.com ゾーンの Knot による自動署名後、DS レコードが変更されていないことを確認します。これは test.com のゾーンデータの編集の都度、com ゾーンに DS レコードを再登録する必要がないこと、かつ com ゾーンの再署名の必要がないことを確認するためです。

事前にシリアル番号を確認します。(master 以外は自動署名によりシリアル番号が unix-time になっています)

; master
[root@auth ~]# grep serial /var/named/test.com.zone
  0000000005    ; serial

; Knot
[root@auth ~]# grep SOA /var/lib/knot/test.com.zone | grep -v RRSIG
test.com.               604800  SOA     ns1.test.com. root.test.com. 1728442728 86400 3600 604800 2000000

; Slave
[root@auth ~]# grep serial /var/named/slaves/test.com.zone1
                                1728442728 ; serial
[root@auth ~]# grep serial /var/named/slaves/test.com.zone2
                                1728442728 ; serial

master のゾーンデータを変更(serial : 5 → 6)し、リロードします。

[root@auth ~]# vi /var/named/test.com.zone
[root@auth ~]# grep serial /var/named/test.com.zone
  0000000006    ; serial
[root@auth ~]# rndc reload
server reload successful

ゾーン転送先のシリアル番号が更新されていることを確認します。

; Knot
[root@auth ~]# grep SOA /var/lib/knot/test.com.zone | grep -v RRSIG
test.com.               604800  SOA     ns1.test.com. root.test.com. 1728457928 86400 3600 604800 2000000

; slave1
[root@auth ~]# grep serial /var/named/slaves/test.com.zone1
                                1728457928 ; serial
; slave2
[root@auth ~]# grep serial /var/named/slaves/test.com.zone2
                                1728457928 ; serial

自動署名の前後で DS レコードに変更がないことを確認します。

; 前
[root@auth ~]# cat /var/named/keys/dsset-test.com.
test.com. DS 55474 13 2 f6e90004c7822ebb1eadcdebfa3d20c03e308dd3e5c5e0d04a536a692ea1b0e6
test.com. DS 55474 13 4 939736fa9e96a2e58bab97b05d9eb743c0a367811f2a1b7b052c662c7e0ce2e031eb01fe6ce763ea2c2a2445bfa4b176

; 後
[root@auth ~]# keymgr test.com ds
test.com. DS 55474 13 2 f6e90004c7822ebb1eadcdebfa3d20c03e308dd3e5c5e0d04a536a692ea1b0e6
test.com. DS 55474 13 4 939736fa9e96a2e58bab97b05d9eb743c0a367811f2a1b7b052c662c7e0ce2e031eb01fe6ce763ea2c2a2445bfa4b176

タイトルとURLをコピーしました