Debian 9 の nsd4 で DNSSEC してみるメモ

nsd4 で DNSSEC してみるメモです。無保証です。

・設定環境

Debian GNU/Linux 9 (stretch) + nsd 4.1.14-1 + bind9utils 1:9.10.3.dfsg.P4-12.3+deb9u4

前提としては、nsd4 でマスターサーバが普通に (DNSSEC を使用しない状態で) 駆動していること。
nsd4 を使っているのに、bind9utils を使うのは、dnssec-signzone で Smart signing が使えるため。
ゾーンへの署名は毎週、ZSK は 28 日で更新することを考えている。

・bind9utils をインストール

# apt-get install bind9utils

・DNSSEC で使う鍵を格納するディレクトリを作成

# mkdir -p /etc/nsd/keys/dnssec
# chmod 700 /etc/nsd/keys/dnssec

・ZSK (ゾーンファイル署名用の鍵) の作成 (すぐに利用する用)

dnssec-keygen -K 鍵の書き出しディレクトリ名 -3 -a 鍵のアルゴリズム \
-b 鍵のビット長 -P now -A now -I +28d -D +35d \
-n キーのオーナータイプ(DNSSECではZONEを指定) ゾーン名

※「-3」は NSEC3 を使うオプション
※「-P now -A now -I +28d -D +35d」は、ゾーン署名の際、キー生成時の時刻から、ゾーンへの出力は今すぐ、署名鍵として今すぐ使用、28 日後からは署名しないようにする、35 日後からはゾーンから削除。

# dnssec-keygen -K /etc/nsd/keys/dnssec -3 -a RSASHA256 -b 1024 \
-P now -A now -I +28d -D +35d -n ZONE example.com

/etc/nsd/keys/dnssec 以下の様に ZSK が生成される。

Kexample.com.+xxx+xxxxx.key が公開鍵
Kexample.com.+xxx+xxxxx.private が秘密鍵

・ZSK (ゾーンファイル署名用の鍵) の作成 (次 (4週間後) の署名に利用する用)

dnssec-keygen -K 鍵の書き出しディレクトリ名 -3 -a 鍵のアルゴリズム \
-b 鍵のビット長 -P +20d -A +27d -I +56d -D +64d \
-n キーのオーナータイプ(DNSSECではZONEを指定) ゾーン名

※「-P +20d -A +27d -I +56d -D +64d」は、ゾーン署名の際、キー生成時の時刻から、ゾーンへの出力は 20日後、27 日後に署名鍵として使用、56 日後からは署名しないようにする、64 日後からはゾーンから削除。(この辺り、最初の部分は手動でキーを生成しているので、若干余裕を見ている)

# dnssec-keygen -K /etc/nsd/keys/dnssec -3 -a RSASHA256 -b 1024 \
-P +20d -A +27d -I +55d -D +62d -n ZONE example.com

・KSK (ゾーンファイル公開鍵情報に署名する鍵) の作成

dnssec-keygen -K 鍵の書き出しディレクトリ名 -3 -a 鍵のアルゴリズム \
-b 鍵のビット長 -n キーのオーナータイプ(DNSSECではZONEを指定) \
-f KSK ゾーン名

※「-3」は NSEC3 を使うオプション
※「-f KSK」は DNSKEY レコードに KSK のフラグを立てるオプション

# dnssec-keygen -K /etc/nsd/keys/dnssec -3 -a RSASHA256 -b 2048 \
-n ZONE -f KSK example.com

/etc/nsd/keys/dnssec 以下の様に KSK が生成される。

Kexample.com.+xxx+xxxxx.key が公開鍵
Kexample.com.+xxx+xxxxx.private が秘密鍵

・ゾーンファイルに署名する

初めに、対象ゾーンファイルのシリアル値をインクリメントする。

dnssec-signzone -3 `echo -n $RANDOM | xxd -p |tr -d '\n'` -S \
-K 鍵を保存したディレクトリ名 -N increment -o ゾーン名 ゾーンファイル名

※「-3」は NSEC3 を使うオプション。seed は bash の $RANDOM から適当に生成
※「-S」は Smart signing を使うオプション
※「-N keep」はシリアル値を変更しない設定

# dnssec-signzone -3 `echo -n $RANDOM | xxd -p |tr -d '\n'` -S -K /etc/nsd/keys/dnssec -N keep -o example.com /etc/nsd/zones/example.com

・ゾーンを署名したものに切り替えてリロードする

nsd4 の設定ファイル、/etc/nsd/nsd.conf 内で、今回署名したゾーンのゾーンファイル指定を「zonefile: “example.com.signed”」の様にして、nsd をリスタートする。

# /etc/init.d/nsd restart

・権威サーバで確認

$ dig @権威サーバ ドメイン名 +norec +dnssec +multi

RRSIG レコードとかが付いているか確認する。

・レジストラで DS レコードを登録する

/etc/nsd/zones/dsset-example.com の内容を登録する。
もしくは、以下にて確認できる。

# dnssec-dsfromkey KSK公開鍵ファイル

・検証の確認

$ dig @8.8.8.8 ドメイン名 soa +dnssec +multi

flags に「ad」が出ていれば検証に成功している。(Google Public DNS を利用した例)
あるいは、「DNSSEC Analyzer」で確認する。

・DNSSEC をやめるとき

あらかじめ、レジストリのネームサーバから DS レコードの TTL 値を確認しておく。

$ dig com ns
$ dig @a.gtld-servers.net example.com ds +norec

TTL は 86400 だったので、レジストラで DS レコードを削除し、レジストリから自ドメインの DS レコードが消えて、1 日以上たってから、署名がないゾーンファイルに切り替える。

・ZSK のロールオーバと署名の自動化

下記の keygen.sh (必ず keygen.sh を先に実行する) と resign.sh を順番に 1 週間に 1 回実行することで、多分 ZSK のロールオーバーにも対応できるはず。(無保証)
dnssec.config ゾーン名とゾーンファイルをタブ区切りで 1 行ごとに記載する。(これらのスクリプトで参照する設定ファイル。)
なお、対象とするゾーンファイルは、「サンプルゾーンファイル」の様に SOA レコードのシリアル値の部分を「;SOASERIALSTART」と「;SOASERIALEND」でくくる。(この範囲のみ、置換対象としているため)
いずれも詳細はスクリプト参照。
手動でゾーンファイルを変更した場合でも、resign.sh を実行すればちゃんと署名されてゾーンがリロードされるはず。

・参考 URL

・履歴

  • 2018/05/12: シリアル値のみ確実に変更できる様に修正

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です