逆引きDNSSECのスタートアップガイド
BIND9を用いて逆引きDNSSECを始める方法をご紹介します。
設定ファイルおよびゾーンファイル
Linuxのnamed.confのデフォルトの設置場所は以下の通りです。 なおディストリビューションのバージョンによって場所が異なる可能性があります。
- Debian/Ubuntu
- /etc/bind/named.conf
- Fedora/CentOS
- /etc/named.conf
ゾーンファイルのデフォルトの設置場所は以下の通りです。
- Debian/Ubuntu
- /var/cache/bind/
- Fedora/CentOS
- /var/named/
このガイドではUbuntu16.04を例に説明します。 なお、以下のコマンドや設定は一例であり、 実環境にはそぐわない場合があります。
設定の変更
named.conf の "options" ディレクティブに以下の設定を記述することで DNSSECの機能が有効になります。 (デフォルトで有効です)
options {
...
dnssec-enable yes;
}
KSK/ZSKの生成
鍵の保存場所を作成し移動します。 ディレクトリ名は任意ですが、 このガイドでは /etc/bind/keys とします。
# mkdir /etc/bind/keys
# cd /etc/bind/keys
ZSK鍵を作成します。 どのゾーンに利用するかコマンドの末尾にゾーン名を指定します。 このガイドでは 2.0.192.in-addr.arpa とします。 またDNSSECアルゴリズムをRSASHA256、 鍵長を1024ビットに指定しています。
# dnssec-keygen -a RSASHA256 -b 1024 -n ZONE 2.0.192.in-addr.arpa
Generating key pair................++++++ .++++++
K2.0.192.in-addr.arpa.+008+04686
続いてKSKを作成します。鍵長を2048ビットに指定しています。
# dnssec-keygen -a RSASHA256 -b 2048 -n ZONE -f KSK 2.0.192.in-addr.arpa
Generating key pair.............++++++ ..........................++++++
K2.0.192.in-addr.arpa.+008+47341
上記二つのコマンドでファイルが四つ作成されます。 *.keyが公開鍵、*.privateが秘密鍵にあたります。 以下の例では鍵IDが4686の鍵ペア(ZSK)、 鍵IDが47341の鍵ペア(KSK)ができています。
例: K2.0.192.in-addr.arpa.+008+04686.key K2.0.192.in-addr.arpa.+008+04686.private K2.0.192.in-addr.arpa.+008+47341.key K2.0.192.in-addr.arpa.+008+47341.private
鍵を失わないようアクセス制限やバックアップをしておきましょう。
ゾーンファイルの署名
上記で生成したKSK/ZSKを用いて署名をします。 ゾーンファイルのあるディレクトリに移動します。
# cd /var/cache/bind
dnssec-signzone コマンドで署名をします。 鍵の明示的な指定が不要なsmart signingを使用します。
# dnssec-signzone -S -K /etc/bind/keys 2.0.192.in-addr.arpa
Fetching KSK 47341/RSASHA256 from key repository.
Fetching ZSK 4686/RSASHA256 from key repository.
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
2.0.192.in-addr.arpa.signed
署名されたゾーンファイルは *.signed という名前で出力されます。 また同時に署名に用いたKSKに対応するDSレコードの入ったファイルが dsset-<ゾーン名>という名前で出力されます。
署名したゾーンファイルの公開
ゾーンを公開します。 ゾーンファイルの指定を署名後のファイル名に変更します。
named.conf
zone "2.0.192.in-addr.arpa" {
...
type master;
file "/var/cache/bind/2.0.192.in-addr.arpa.signed";
};
サーバの設定ファイルを再読込します。
# service bind9 reload
DNSSECのレコードが引けるか確認します。
# dig @localhost 2.0.192.in-addr.arpa DNSKEY +dnssec +multi
問題がなければDNSKEYおよびRRSIGが応答されます。
セカンダリサーバの設定
named.confの"options"ディレクティブにdnssec-enableの設定を記述することでDNSSECの機能が有効になります。
options {
...
dnssec-enable yes;
}
サーバのゾーンファイルの名前を変更します。
zone "2.0.192.in-addr.arpa." IN {
...
type slave;
file "2.0.192.in-addr.arpa.signed";
};
サーバの設定ファイルを再読込します。
# service bind9 reload
応答を確認します。
# dig @localhost 2.0.192.in-addr.arpa DNSKEY +dnssec +multi
DSレコードの登録
ゾーンの準備ができましたので次にDSレコードをJPNICに登録します。 IPレジストリシステムにログインし、 「逆引きネームサーバ追加・削除」画面を表示します。 ページ中の「DSレコード情報」に dsset-* ファイルの内容を入力し、 申請してください。
DSレコードの確認
DSレコードは他の申請と同様に半日程度で登録されます。 しばらく時間を置いたあと、 DSレコードが引けるかどうか確認します。
# dig 2.0.192.in-addr.arpa DS
...
;; ANSWER SECTION:
2.0.192.in-addr.arpa. 4701 IN DS 47341 8 1 599EBDD7C279A81B672629051EBB09A47A03B3A5
2.0.192.in-addr.arpa. 4701 IN DS 47341 8 2 C3E44FABE12B899C113E273C6FE6D6806EAE256FA7188EFAA221C65D 51DF0B52
動作確認
DSレコードの登録完了後であればDNSSECを利用可能です。 dig等を用いてADビットが立っているかどうか確認してください。
# dig @8.8.8.8 2.0.192.in-addr.arpa SOA
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28963
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5
...
また、確認サイトも利用できます。
ゾーンファイルの再署名
DNSSECの署名は有効期限があります(dnssec-signzoneではデフォルトで30日)。 そのため、 ゾーンに変更がなくても有効期限が切れる前に再署名する必要があります。 手動でdnssec-signzoneを実行しても良いのですが、 うっかり忘れないように自動化することをおすすめします。 以下は自動で再署名するためのスクリプトの例です。
/etc/cron.weekly/dnssec-sign.sh
#!/bin/bash
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
cd /var/cache/bind
serial=$(named-checkzone 2.0.192.in-addr.arpa 2.0.192.in-addr.arpa|awk '/serial/ {print $5}')
serialp1=$(($serial+1))
#シリアル値以外を変更する可能性あり
sed -i -e "s/$serial/$serialp1/" 2.0.192.in-addr.arpa
dnssec-signzone -S -K /etc/bind/keys 2.0.192.in-addr.arpa
service bind9 reload
鍵の更新
SSL/TLSサーバ証明書の更新と同様に、 DNSSECでも鍵ペアの更新を定期的に行うことが推奨されます。 更新間隔は特に決まっていませんが、 公開鍵暗号の危殆化に備えて適宜更新しましょう。
鍵更新(key-rollover)の方法
DNSSECでの公開鍵はDNSKEYレコードに記述され、 これを更新することになります。 更新の際には署名データであるRRSIGレコード、 またKSKの場合親ゾーンに登録しているDSレコードとの整合性をとりながら作業する必要があります。 また、DNSはキャッシュの仕組みがありますので、 手元のゾーンファイルを単に書き換えるだけではなく、 インターネット上のリゾルバがどのようなレコードをキャッシュしているかを考慮しながら鍵を更新する必要もあります。
安全に鍵を更新する方法としては、 RFC6781 で紹介されているPre-PublishやDouble-Signatureといった方法があります。 本ガイドでは、ZSKをPre-Publishで、 KSKをDouble-Signatureで更新する方法をご紹介します。
Pre-PublishによるZSKの鍵更新
Pre-PublishによるZSKの鍵更新は、以下のように行います。
- 新しいZSKを作成し現在のZSKとあわせて公開
- リソースレコードへの署名は現在の鍵で行う
- DNSKEYのTTL以上待つ
- リソースレコードを新しいZSKで署名する
- ゾーン内レコードの最大TTL以上待つ
- 元のZSKを削除する
BINDではsmart signingという機能があり、 鍵のデータファイルに保存されている日付を元に、 鍵の追加や削除、 署名をする・しないを指定することができます。 日付の設定はdnssec-settimeコマンドで行います。
まずdnssec-settimeコマンドで現在のZSK鍵の利用期間を設定します。 以下の例では、 現在の鍵による署名を現在時刻から20日後にやめ(inactivate、 ゾーンに含まれるが署名に使用しない状態)、 30日後にゾーンから鍵を削除(delete)するようにしています。
# cd /etc/bind/keys # dnssec-settime -I +20d -D +30d K2.0.192.in-addr.arpa.+008+04686.key ./K2.0.192.in-addr.arpa.+008+04686.key ./K2.0.192.in-addr.arpa.+008+04686.private
次に新しいZSKをdnssec-keygenコマンドを用いて生成します。 以下の例では、 現在のZSKのinactive時間と同時に利用開始となるように時間を調整し(-S)、 ゾーンの署名鍵として利用を開始するまでのインターバル、 すなわち鍵の公開時間(publish)を1209600秒(14日)になるようにしています(-i)。
# cd /etc/bind/keys # dnssec-keygen -S K2.0.192.in-addr.arpa.+008+04686 -i 1209600
smart signingを利用して再署名します。 デフォルトではSOAシリアル値は元のゾーンファイルの値が使用されるので、 適宜変更します。 (注: dnssec-signzoneコマンドにはシリアル値を自動的に変更することができる機能がありますが、 ここでは割愛します)
# cd /var/cache/bind # vi 2.0.192.in-addr.arpa (シリアル値増加) # dnssec-signzone -S -K /etc/bind/keys 2.0.192.in-addr.arpa Fetching ZSK 4686/RSASHA256 from key repository. Fetching KSK 47341/RSASHA256 from key repository. 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 2.0.192.in-addr.arpa.signed
署名に成功したらゾーンをリロードします。
# rndc reload
以後再署名を適宜実施することで、 指定した日時にそってZSKが更新されます。
Double-SignatureによるKSKの鍵更新
Double-SignatureによるKSKの鍵更新は、以下のように行います。
- 新しいKSKを作成、対応するDSも作成
- 現在のKSK、新しいKSK両方でDNSKEYを署名
- ゾーン内レコードの最大TTL以上待つ
- 新しいDSを親ゾーン(JPNIC)に登録、古いDSを同時に削除(DSを上書きする)
- DSが親ゾーンで公開された後、DSのTTL以上待つ
- 元のKSKを削除する
まず新しいKSKを生成します。
# cd /etc/bind/keys # dnssec-keygen -a RSASHA256 -b 2048 -f KSK -n ZONE 2.0.192.in-addr.arpa Generating key pair.................................................+++ ..............................................................................................................+++ K2.0.192.in-addr.arpa.+008+07810
KSKに対応するDSレコードはdnssec-dsfromkeyコマンドで生成できます。 このDSレコードを親ゾーンに登録することになります。
# dnssec-dsfromkey K2.0.192.in-addr.arpa.+008+07810 2.0.192.in-addr.arpa. IN DS 7810 8 1 25BB37DCD13D2D9977B4A4EC3DDADD6105F6EA13 2.0.192.in-addr.arpa. IN DS 7810 8 2 21C0AE9B9C2A2382C4FAF99A1A04CF0CDAF6BB7A2BDB42781DDABD3F26913DC4
次に、現在の鍵と新しい鍵の両方でゾーンを署名します。 現在の鍵と新しい鍵は使用期限を指定していないため両方とも署名に使用されます。 "KSKs: 2 active"と出力されます。
# vi 2.0.192.in-addr.arpa (シリアル値増加) # dnssec-signzone -S -K /etc/bind/keys 2.0.192.in-addr.arpa Fetching ZSK 4686/RSASHA256 from key repository. Fetching KSK 47341/RSASHA256 from key repository. Fetching KSK 7810/RSASHA256 from key repository. Verifying the zone using the following algorithms: RSASHA256. Zone fully signed: Algorithm: RSASHA256: KSKs: 2 active, 0 stand-by, 0 revoked ZSKs: 1 active, 0 stand-by, 0 revoked 2.0.192.in-addr.arpa.signed # rndc reload
ゾーン内のすべてのレコードのうち最大のTTL以上待ち、 新しい鍵と署名がキャッシュされたら新しい鍵のDSレコードを親ゾーンに登録します。 元のDSレコードは削除(登録解除)します。
親ゾーンで新しいDSレコードが公開されるのを確認します。 その後DSレコードのTTL以上待ち、キャッシュされるのを待ちます。
十分に時間が経っていれば元のKSKをゾーンから除くことができます。
ゾーンから元のKSKを取り除くには、鍵の利用期間を制限します。 以下ではすぐに鍵をinactivateにし、7日後にゾーンからdeleteする例です。
# dnssec-settime -I +1 -D +7d K2.0.192.in-addr.arpa.+008+47341
鍵の利用期間を設定した後、再署名します。"KSKs: 1 active"となります。
# vi 2.0.192.in-addr.arpa (シリアル値増加) # dnssec-signzone -S -K /etc/bind/keys 2.0.192.in-addr.arpa Fetching ZSK 4686/RSASHA256 from key repository. Fetching KSK 47341/RSASHA256 from key repository. Fetching KSK 7810/RSASHA256 from key repository. 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 2.0.192.in-addr.arpa.signed # rndc reload
以上で鍵の更新は終了です。
鍵が正しく更新できたかどうか確認するには、 署名検証を行っているリゾルバ(バリデータ)を用いてdigコマンド等でADビットが立っているか確認するか、 もしくは以下のサイトで確認できます。
# dig 2.0.192.in-addr.arpa SOA +dnssec ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38304 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
http://dnsviz.net/
https://dnssec-debugger.verisignlabs.com/
以上