#author("2020-10-17T13:47:10+09:00","default:nowsky","nowsky")
#author("2020-10-17T13:53:17+09:00","default:nowsky","nowsky")
*NSD [#g2acfc62]
権威DNSに特化したサーバアプリケーションであり、オランダ企業とRIPE NCCの共同開発が行われている。
RFCに準拠した最低限の機能のみ実装している為、脆弱性が少なく堅牢で応答速度も早いのが特徴となる。
最低限の機能しか無い為、&color(#ff0000){DNSクエリを取得出来ない};欠点がある。
また、NSDをslaveとして構築した際にserialの比較を行わない[[ケース:+https://blog.akagi.jp/archives/4152.html]]がある。
 
DNSルートサーバでも採用されており、グローバルの稼働実績も多い。
BINDとNSDのハイブリッド構成を取って脆弱性対策をするケースも多い上、
BIND脱却としてオールNSD構成を取る日本企業も増えてきた。
~
*参考サイト [#h7d17d85]
-[[NLnet Labs:+https://nlnetlabs.nl/]]
-[[NSD Documentation:+https://nlnetlabs.nl/documentation/nsd/]]
-[[日本Unboundユーザー会:+https://unbound.jp/nsd4/nsd-conf/]]
~
*構築環境 [#n7822bae]
OSはCentOSを利用。普通は出来ないDNSクエリ取得を実現すべくパッチを適用する為、
ソースコードからビルドを実施している。
- 共通環境
 OS    : CentOS 8.2.2004 x86_64
 NSD   : NSD v4.3.3
 user  : nsd
 group : nsd
 chroot: /var/nsd/chroot
~
*インストール [#k06c4a06]
-&size(16){&font(b){0. ソース改変};};
NSDでDNSクエリを取得する事は出来ないが、
下記サイトで公開している独自パッチを適用する事でログ取得が可能となる。
サポート外となるが、ログ取得が必要な時はソースコードを変更した上でビルドする。
#region(&color(#ff0000){変更部分};)

-参考サイト
[[あ~ゆ~どりま~:+http://ayd.jp/p_blog/archive-201410/article-1413696054.html]]
[[どさにっき:+http://ya.maya.st/d/201305b.html#s20130517_2]]
 

-NSD v4.3.3
 [root@server nsd-4.3.3]# diff -up query.c query.c-4.3.3
 --- query.c             2020-10-08 16:14:25.000000000 +0900
 +++ query.c-4.3.3       2020-10-10 14:20:49.000000000 +0900
 @@ -1406,6 +1406,7 @@ query_process(query_type *q, nsd_type *n
         nsd_rc_type rc;
         query_state_type query_state;
         uint16_t arcount;
 +       char address[128];
  
         /* Sanity checks */
         if (buffer_limit(q->packet) < QHEADERSZ) {
 @@ -1543,6 +1544,19 @@ query_process(query_type *q, nsd_type *n
                 return QUERY_PROCESSED;
         }
  
 +       /* Query logging. */
 +       addr2str(&q->addr, address, sizeof(address));
 +       log_msg(LOG_INFO, "client %s: query %s %s %s %s%s%s%s%s",
 +               address,
 +               q->qname ? dname_to_string(q->qname, NULL) : "(null)",
 +               rrclass_to_string(q->qclass),
 +               rrtype_to_string(q->qtype),
 +               RD(q->packet) ? "+" : "-",
 +               q->edns.status == EDNS_OK ? "E" : "",
 +               q->tcp ? "T" : "",
 +               q->edns.dnssec_ok ? "D" : "",
 +               CD(q->packet) ? "C" : "");
 +
         query_prepare_response(q);
  
         if (q->qclass != CLASS_IN && q->qclass != CLASS_ANY) {
#endregion
~
-&size(16){&font(b){1. インストール};};
systemdを用いるOSを使っている場合、configure時にオプション指定する事でfork対応する事が出来る。
だが、NSDのconfigureスクリプトに相性があり、必要なパッケージがインストール済みなのにも関わらず、
未インストールと判定されるケースがある。
その場合はsystemd有効化オプションを無効化し、起動スクリプトをsimple判定にする事で対応する。
今回は相性問題が発生した為、CentOSを用いているがsystemdを無効化している。
 # dnf install libevent-devel
 # ./configure --prefix=/usr/local/nsd-4.3.3 --enable-pie \
     --enable-relro-now --enable-ratelimit-default-is-off \
     --disable-nsec3 --disable-radix-tree
 # make
 # make install
 # vi /usr/lib/systemd/system/nsd.service
 ---
 [Unit]
 Description=Name Server Daemon
 After=network-online.target
 Wants=network-online.target
 
 [Service]
 Type=simple
 EnvironmentFile=-/etc/sysconfig/nsd
 ExecStartPre=/usr/local/nsd/sbin/nsd-checkconf /etc/nsd/nsd.conf
 ExecStart=/usr/local/nsd/sbin/nsd -d -c /etc/nsd/nsd.conf -t /var/nsd/chroot
 ExecReload=/usr/local/nsd/sbin/nsd-control -c /etc/nsd/nsd.conf reload
 ExecStop=/usr/local/nsd/sbin/nsd-control -c /etc/nsd/nsd.conf stop
 Restart=on-abort
 LimitNOFILE=1048576
 LimitNPROC=1048576
 
 [Install]
 WantedBy=multi-user.target
~
-&size(16){&font(b){2. ディレクトリ作成};};
NSDのデフォルト動作はchroot無しを想定しているので、chrootを含めた絶対パスで作成する。
リモート操作やローカルAPIを実行する為の公開鍵も作成し、chroot配下に配置する。
 # mkdir /var/nsd/chroot
 # mkdir /var/nsd/chroot/tmp
 # mkdir /var/nsd/chroot/etc/nsd
 # mkdir /var/nsd/chroot/var/log
 # mkdir /var/nsd/chroot/var/run
 # mkdir /var/nsd/chroot/var/db/nsd
 
 # ln -s /usr/local/nsd-4.3.3 /usr/local/nsd
 # ln -s /var/nsd/chroot/etc/nsd /etc/nsd
 # ln -s /var/nsd/chroot/var/log /var/log/nsd
 
 # groupadd nsd
 # useradd -g nsd -d /var/nsd -s /sbin/nologin nsd
 # chown -R nsd.nsd /var/nsd/chroot/tmp
 # chown -R nsd.nsd /var/nsd/chroot/var/run
 # chown -R nsd.nsd /var/nsd/chroot/var/log
 
 # /usr/local/nsd/sbin/nsd-control-setup
 # cp -a /usr/local/nsd/etc/nsd/* /var/nsd/chroot/etc/nsd/
 # vi /etc/logrotate.d/nsd
 ---
 /var/log/nsd/*.log {
     create 0644 nsd nsd
     missingok
     sharedscripts
     postrotate
         systemctl restart nsd > /dev/null 2>/dev/null || true
     endscript
 }
~
-&size(16){&font(b){3. 設定ファイル};};
サンプルでは、example.comをDNSゾーンマスター、example.netをDNSゾーンスレーブとしている。
LISTEN-IPは実際にDNSクエリに応答するグローバルIPと、
ゾーン転送用のプライベートIP(クラスA)を書いている。
 # vi /etc/nsd/nsd.conf
 ---
 ##
 ## Copyright (C) 2001-2020, NLnet Labs. All rights reserved.
 ##
 ## See LICENSE for the license.
 ##
 server:
     server-count: 1
     ip-address: 192.168.0.1
     ip-address: 203.0.113.1
     ip-address: 2001:db8::203:0:113:1
     port: 53
 
     username: nsd
     chroot: "/var/nsd/chroot"
     zonesdir: "/var/nsd/chroot/etc/nsd"
     zonelistfile: "/var/nsd/chroot/var/db/nsd/zone.list"
     database: "/var/nsd/chroot/var/db/nsd/nsd.db"
     logfile: "/var/nsd/chroot/var/log/nsd.log"
     pidfile: "/var/nsd/chroot/var/run/nsd.pid"
     xfrdfile: "/var/nsd/chroot/var/db/nsd/xfrd.state"
     xfrdir: "/var/nsd/chroot/tmp"
 
     version: "unknown"
     identity: "unknown"
     hide-version: yes
     hide-identity: yes
 
 
 remote-control:
     control-enable: yes
     control-interface: 127.0.0.1
     control-port: 8952
     server-key-file: "/var/nsd/chroot/etc/nsd/nsd_server.key"
     server-cert-file: "/var/nsd/chroot/etc/nsd/nsd_server.pem"
     control-key-file: "/var/nsd/chroot/etc/nsd/nsd_control.key"
     control-cert-file: "/var/nsd/chroot/etc/nsd/nsd_control.pem"
 
 
  zone:
     name: "example.com"
     zonefile: "master/example.com"
     # notify: 192.168.0.3@53 NOKEY
     # notify-retry: 5
     # provide-xfr: 53 NOKEY
 
 
 zone:
     name: "example.net"
     zonefile: "slave/example.net"
     allow-notify: 192.168.0.2 NOKEY
     request-xfr: 192.168.0.2@53 NOKEY
     allow-axfr-fallback: yes
     # outgoing-interface: 192.168.0.1

~
-&size(16){&font(b){4. 動作確認};};
NSDを実際に起動させて動作確認を行う。
今回はDNSクエリログ出力パッチを適用している為、BINDの様なDNSクエリログも出力される。
 # systemctl enable nsd
 # systemctl start nsd
 # cat /var/log/nsd.log
 ---
 [2020-10-XX 13:48:52.753] nsd[100080]: notice: nsd starting (NSD 4.3.3)
 [2020-10-XX 13:48:52.813] nsd[100081]: notice: nsd started (NSD 4.3.3), pid 100080
 [2020-10-XX 13:49:51.041] nsd[100083]: info: client 192.168.0.1: query example.com. IN A +E