nsd でセカンダリDNSを構成しなおす

unbound でセカンダリ DNS を構築したものの、

今回の例だと、unbound 自身はほんと最低限の動けばいいレベルでしか設定していないので、実運用時はもう少し考える必要があるので、ご注意を。

[From unboundをbind9のスレーブとして設定してみる - Soukaku's HENA-CHOKO Blog]

設定面に不安もあったし、「なんで unbound なの?オープリゾルバにしたいの?」といったご指摘も頂いたので、いろいろ調べ直して、 nsd をセカンダリとして使うように構成を変更したので、そのメモ。

nsd は

NSD (Name Server Daemon) は高性能で簡単なオープンソースの権威ネームサーバです。

[From NSD 4 – 日本Unboundユーザー会]

と謳い文句にある通り、DNS コンテンツサーバに特化している DNS サーバの実装の一つです。

インストールと基本的な設定

インストールするのは、 unbound をスレーブとして設定した自宅側のサーバ。

HomeNetwork_DNS-20190121.png

これを unbound ではなく nsd に置き換える、と…。(正確には、ちょっと違うので、その点については後述。)


インストール自体は、apt コマンドなり、 aptitude コマンドなりで一発で終了。

nexus01:~# apt install nsd
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
nsd
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 3 個。
433 kB のアーカイブを取得する必要があります。
この操作後に追加で 1,848 kB のディスク容量が消費されます。
取得:1 http://debian-mirror.sakura.ne.jp/debian sid/main amd64 nsd amd64 4.1.25-2 [433 kB]
433 kB を 0秒 で取得しました (1,007 kB/s)
以前に未選択のパッケージ nsd を選択しています。
(データベースを読み込んでいます ... 現在 186747 個のファイルとディレクトリがインストールされています。)
.../nsd_4.1.25-2_amd64.deb を展開する準備をしています ...
nsd (4.1.25-2) を展開しています...
nsd (4.1.25-2) を設定しています ...
Created symlink /etc/systemd/system/multi-user.target.wants/nsd.service → /lib/systemd/system/nsd.service.
systemd (239-9) のトリガを処理しています ...
man-db (2.8.5-1) のトリガを処理しています ...
nexus01:~#

この時点では、 unbound が port53 を掴んでいるので、nsd は起動に失敗しているので、

nexus01:~# grep nsd /var/log/daemon.log | grep -v systemd
Jan 20 18:09:43 nexus01 nsd[9567]: nsd starting (NSD 4.1.25)
Jan 20 18:09:43 nexus01 nsd[9567]: [2019-01-20 18:09:43.475] nsd[9567]: notice: nsd starting (NSD 4.1.25)
Jan 20 18:09:43 nexus01 nsd[9567]: [2019-01-20 18:09:43.475] nsd[9567]: error: can't bind udp socket: Address already in use
Jan 20 18:09:43 nexus01 nsd[9567]: [2019-01-20 18:09:43.475] nsd[9567]: error: server initialization failed, nsd could not be started
Jan 20 18:09:43 nexus01 nsd[9567]: can't bind udp socket: Address already in use
Jan 20 18:09:43 nexus01 nsd[9567]: server initialization failed, nsd could not be started

その点は無視して、基本的な設定をしていきます。
まず、/etc/nsd/nsd.conf.d/local.conf に待ち受けるインタフェースの IP アドレスやマスタからゾーン転送されてきたデータを格納するためディレクトリなどの設定を記述。

server:
interface: 127.0.0.1
interface: ::1
interface: 218.219.149.234
interface: 2001:470:24:94::234

zonesdir: /etc/nsd/zone

verbosity: 2
log-time-ascii: yes

次に /etc/nsd/nsd.conf.d/slave_zones.conf に、ゾーンデータを保尊するファイルの名前や、マスタの IP アドレスなどを記述。下の記載例では一つしか書いてませんが、ゾーンは複数書くことが出来ます。

zone:
name: "downtown.jp"
allow-notify: 153.120.6.47 NOKEY
allow-notify: 2401:2500:102:2120:153:120:6:47 NOKEY
request-xfr: 153.120.6.47 NOKEY
request-xfr: 2401:2500:102:2120:153:120:6:47 NOKEY
zonefile: "downtown.jp"

合わせて、ソーンデータの格納ディレクトリを作って、パーミッションを nsd ユーザが読み書きできるようにしておきます。

nexus01:~# ls -ld /etc/nsd/zone/
drwxr-xr-x 2 nsd nsd 4096 Jan 21 09:51 /etc/nsd/zone/

さて、これで準備完了したので、すでに起動している unbond を停止して、nsd を起動します。

nexus01:~# systemctl stop unbound && systemctl start nsd
nexus01:~# systemctl status nsd
● nsd.service - Name Server Daemon
Loaded: loaded (/lib/systemd/system/nsd.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2019-01-22 23:36:32 JST; 34s ago
Docs: man:nsd(8)
Main PID: 10634 (nsd)
Tasks: 3 (limit: 4915)
Memory: 114.9M
CGroup: /system.slice/nsd.service
├─10634 /usr/sbin/nsd -d
├─10635 /usr/sbin/nsd -d
└─10649 /usr/sbin/nsd -d

1月 22 23:36:33 nexus01 nsd[10634]: zone 232.149.219.218.in-addr.arpa serial 0 is updated to 2010061618.
1月 22 23:36:33 nexus01 nsd[10634]: [2019-01-22 23:36:33.486] nsd[10634]: info: zone 232.149.219.218.in-addr.arpa serial 0 is updated to 201006
1月 22 23:36:33 nexus01 nsd[10634]: [2019-01-22 23:36:33.486] nsd[10634]: info: zone 4.9.0.0.4.2.0.0.0.7.4.0.1.0.0.2.ip6.arpa serial 0 is updat
1月 22 23:36:33 nexus01 nsd[10634]: [2019-01-22 23:36:33.486] nsd[10634]: info: zone downtown.jp serial 0 is updated to 1271791428.
1月 22 23:36:33 nexus01 nsd[10634]: zone 4.9.0.0.4.2.0.0.0.7.4.0.1.0.0.2.ip6.arpa serial 0 is updated to 1382886305.
1月 22 23:36:33 nexus01 nsd[10634]: zone downtown.jp serial 0 is updated to 1271791428.
1月 22 23:36:39 nexus01 nsd[10634]: new control connection from 127.0.0.1
1月 22 23:36:39 nexus01 nsd[10634]: [2019-01-22 23:36:39.414] nsd[10634]: info: new control connection from 127.0.0.1
1月 22 23:36:39 nexus01 nsd[10634]: control cmd: zonestatus
1月 22 23:36:39 nexus01 nsd[10634]: [2019-01-22 23:36:39.451] nsd[10634]: info: control cmd: zonestatus

nsd の起動直後に、そのステータスを確認してみると、正常に起動されたことがわかります。
ゾーン転送が行われたかどうか、nsd-control zonestatus を実行して確認してみると

nexus01:~# nsd-control zonestatus
zone: 232.149.219.218.in-addr.arpa
state: ok
served-serial: "2010061618 since 2019-01-22T23:36:32"
commit-serial: "2010061618 since 2019-01-22T23:36:32"
wait: "10543 sec between attempts"
zone: 4.9.0.0.4.2.0.0.0.7.4.0.1.0.0.2.ip6.arpa
state: ok
served-serial: "1382886305 since 2019-01-22T23:36:32"
commit-serial: "1382886305 since 2019-01-22T23:36:32"
wait: "10425 sec between attempts"
zone: opt2.biz
state: ok
served-serial: "1272962323 since 2019-01-22T23:36:31"
commit-serial: "1272962323 since 2019-01-22T23:36:31"
wait: "9782 sec between attempts"
zone: downtown.jp
state: ok
served-serial: "1271791428 since 2019-01-22T23:36:32"
commit-serial: "1271791428 since 2019-01-22T23:36:32"
wait: "10358 sec between attempts"

すべてのゾーンで、ステータス OK となっているのと、マスタ側から転送されてきたゾーンのシリアルを確認することが出来ます。(起動状態を確認したときに表示されるログを注意深く見ると、そこにもゾーンのシリアルが変わったことを示すログが出力されている場合もあります。)
ただ、この時点では、転送されてきたゾーンデータは、 /var/lib/nsd/nsd.db にバイナリ形式で格納されているので、これをテキスト形式のソーンファイルとして出力するために nsd-control write を実行すると、 /etc/nsd/nsd.conf.d/local.confzonesdir: で指定したディレクトリに出力されます。

あとは、設定したゾーンの名前解決が出来て、それ以外は失敗することが確認できれば、基本的な設定は完了です。

nexus01:~# dig @localhost downtown.jp SOA

; <<>> DiG 9.11.5-P1-1-Debian <<>> @localhost downtown.jp SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62796
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;downtown.jp. IN SOA

;; ANSWER SECTION:
downtown.jp. 10800 IN SOA vps2.downtown.jp. root.downtown.jp. 1271791428 10800 3600 604800 86400

;; AUTHORITY SECTION:
downtown.jp. 10800 IN NS ns.edit.ne.jp.
downtown.jp. 10800 IN NS vps2.downtown.jp.
downtown.jp. 10800 IN NS nexus01.downtown.jp.

;; ADDITIONAL SECTION:
vps2.downtown.jp. 10800 IN A 153.120.6.47
nexus01.downtown.jp. 10800 IN A 218.219.149.234
vps2.downtown.jp. 10800 IN AAAA 2401:2500:102:2120:153:120:6:47
nexus01.downtown.jp. 10800 IN AAAA 2001:470:24:94::234

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jan 23 00:14:17 JST 2019
;; MSG SIZE rcvd: 235

nexus01:~# dig @localhost google.com SOA

; <<>> DiG 9.11.5-P1-1-Debian <<>> @localhost google.com SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 4793
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com. IN SOA

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jan 23 00:14:26 JST 2019
;; MSG SIZE rcvd: 39

んで、停止した unbound は、どうする?

コンテツサーバとしての nsd は設定できたのですが、このままだと自サーバ内で動作している デーモン、サービスが名前解決出来ずに正常な処理ができなくなるので、これを解決するために、 unbound の設定と、それに合わせて一部のデーモンの設定を変更していきます。
具体的には、unbound を port53 以外で使うように設定して起動させ、 unbound で指定した port に対して名前解決要求を行うようにデーモン側に追加設定をしてあげる、ということになります。

まず、 unbound は、使用するポートを明示に指定するのと、名前解決を受け付けるネットワークを制限する設定を追加します。(前回の設定だと、オープンリゾルバを推奨するような内容だったので。)

nexus01:~# diff -u /etc/unbound/unbound.conf.d/local.conf~ /etc/unbound/unbound.conf.d/local.conf
--- /etc/unbound/unbound.conf.d/local.conf~ 2019-01-16 00:46:27.445002169 +0900
+++ /etc/unbound/unbound.conf.d/local.conf 2019-01-20 18:43:59.951384220 +0900
@@ -1,7 +1,10 @@
server:
- interface: 0.0.0.0
- interface: ::
- access-control: 0.0.0.0/0 allow
+ port: 10053
+ interface: 127.0.0.1
+ interface: ::1
+ access-control: 127.0.0.0/8 allow
+ access-control: 218.219.149.232/29 allow
+ access-control: 2001:470:24:94::/64 allow

num-threads: 8
prefetch: yes

この設定で指定している port へは、ルータでフィルタしたり、 iptables 使ってアクセス制御しているので、外部からはアクセス出来ないようになっています。
設定を書き換えたら、 unbound を起動して、 dig コマンドで port を明示して名前解決ができるか確認します。

nexus01:~# dig -p 10053 @localhost google.com SOA

; <<>> DiG 9.11.5-P1-1-Debian <<>> -p 10053 @localhost google.com SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37375
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com. IN SOA

;; ANSWER SECTION:
google.com. 43 IN SOA ns1.google.com. dns-admin.google.com. 230319200 900 900 1800 60

;; Query time: 0 msec
;; SERVER: 127.0.0.1#10053(127.0.0.1)
;; WHEN: Wed Jan 23 00:36:49 JST 2019
;; MSG SIZE rcvd: 89

デーモン側で 名前解決に使う port を指定する例ですが、 rspamd だと /etc/rspamd/local.d/options.inc に以下の内容を追加後に、 systemctl restart rspamd で完了、っと。

dns {
        nameserver = [ "[::1]:10053", "127.0.0.1:10053" ]
}

ところで、 /etc/resolv.conf の内容を参照して名前解決を行うものなどがあるので、それはどうするかということなのですけど、いろいろ調べてみたんですが、 resolve.conf では

nameserver 127.0.0.1:10053

とポートを明示しても、ポート指定が効かない。
ということで、resolv.conf では VyOS 動かしているルータを nameserver として指定。VyOS の設定で、

# show service dns
forwarding {
listen-address 218.219.149.233
listen-address 2001:470:24:94::233
name-server 172.16.0.11
name-server 2001:470:24:94:8000::11
}
[edit]

という感じで、内部サーバ(ここで unbound が動いている)に問い合わせをフォワードするように設定して回避しています。
このあたりの自ホスト内の名前解決のさせ方は課題として残ってしまったので、他にいいやり方がないか調べてみますかね…。

とりあえず、現時点では、ここまで。

トラックバック(0)

コメントする