- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2020-10-25T00:11:42+09:00","default:nowsky","nowsky")
*NSD [#qa4dbf83]
権威DNSに特化したサーバアプリケーションであり、オランダ企業とRIPE NCCの共同開発が行われている。
RFCに準拠した最低限の機能のみ実装している為、脆弱性が少なく堅牢で応答速度も早いのが特徴となる。
最低限の機能しか無い為、&color(#ff0000){DNSクエリを取得出来ない};欠点がある。
また、NSDをslaveとして構築した際にserialの比較を行わない[[ケース:+https://blog.akagi.jp/archives/4152.html]]がある。
DNSルートサーバでも採用されており、グローバルの稼働実績も多い。
BINDとNSDのハイブリッド構成を取って脆弱性対策をするケースも多い上、
BIND脱却としてオールNSD構成を取る日本企業も増えてきた。
#author("2020-10-25T01:31:30+09:00","default:nowsky","nowsky")
*Knot DNS [#x03b5c41]
チェコで開発している権威DNSサーバ用アプリケーション。
KルートDNSで利用されておりチューニング次第でNSD相当の応答速度が出る。
Knotの特長として、DNSSECのKSK/ZSKロールオーバーを自動化する&color(#ff0000){Online DNSSEC signing};機能がある。
~
*参考サイト [#t68206d0]
-[[NLnet Labs:+https://nlnetlabs.nl/]]
-[[NSD Documentation:+https://nlnetlabs.nl/documentation/nsd/]]
-[[日本Unboundユーザー会:+https://unbound.jp/nsd4/nsd-conf/]]
*参考サイト [#p413258d]
-[[Knot DNS:+https://www.knot-dns.cz/]]
-[[Knot Documentation:+https://www.knot-dns.cz/documentation/]]
-[[IIJ Engineers Blog:+https://eng-blog.iij.ad.jp/archives/5739]]
~
*構築環境 [#ue5d480a]
OSはCentOSを利用。普通は出来ないDNSクエリ取得を実現すべくパッチを適用する為、
ソースコードからビルドを実施している。
*構築環境 [#dafbb252]
OSはCentOSを利用。今回はバックエンドでDNSゾーンへのDNSSEC署名付与と、
KSKロールオーバー・ZSKロールオーバー専用機として構築する。
OS標準パッケージで対応していない機能があるのでソースビルドが必須となる。
- 共通環境
OS : CentOS 8.2.2004 x86_64
NSD : NSD v4.3.3
user : nsd
group : nsd
chroot: /var/nsd/chroot
NSD : Knot v3.0.0
user : knot
group : knot
data : /var/knot/data
listen: 127.0.0.1
port : 20053
~
*インストール [#j15e4b9c]
-&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
~
*インストール [#k792398c]
-&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
KnotではGeoIPなど便利な機能が存在するが、
今回はDNSSEC専用のバックエンドとして構築するので不要な機能を無効化する。
# dnf install gnutls-devel userspace-rcu-devel lmdb-devel libedit-devel
# ./configure --prefix=/usr/local/knot-3.0.0 --disable-documentation \
--with-module-dnsproxy=no --with-module-geoip=no --with-module-dnstap=no \
--with-module-whoami=no --with-module-synthrecord=no
# make
# make install
# vi /usr/lib/systemd/system/nsd.service
# cp -a knot-3.0.0/distro/common/knot.tmpfiles /usr/lib/tmpfiles.d/knot.conf
# cp -a knot-3.0.0/distro/common/knot.service /usr/lib/systemd/system/knot.service
# vi /usr/lib/systemd/system/knot.service
---
[Unit]
Description=Name Server Daemon
After=network-online.target
Description=Knot DNS server
Wants=network-online.target
After=network-online.target
Documentation=man:knotd(8) man:knot.conf(5) man:knotc(8)
[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
Type=notify
PrivateTmp=false
User=knot
Group=knot
EnvironmentFile=-/etc/sysconfig/knot
ExecStartPre=/usr/local/knot/sbin/knotc -c /etc/knot.conf conf-check
ExecStart=/usr/local/knot/sbin/knotd -c /etc/knot.conf $KNOTD_ARGS
ExecReload=/usr/local/knot/sbin/knotc -c /etc/knot.conf reload
ExecStop=/usr/local/knot/sbin/knotc -c /etc/knot.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
自動署名を行う都合上、パーミッションを緩くしたディレクトリが必要となる。
ディレクトリを汚さない様にする為、chrootのディレクトリを作成しパスを変更する。
# mkdir /var/knot/data
# mkdir /var/knot/data/var/log
# mkdir /var/knot/data/run/knot
# mkdir /var/knot/data/lib/knot
# mkdir /var/knot/data/lib/knot/signed
# 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
# ln -s /usr/local/knot-3.0.0 /usr/local/knot
# ln -s /usr/local/knot/etc/knot/knot.conf /etc/knot.conf
# ln -s /var/knot/data/var/log /var/log/knot
# mv /usr/local/knot/etc/knot/knot.sample.conf /usr/local/knot/etc/knot/knot.conf
# 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
# groupadd knot
# useradd -g knot -d /var/knot -s /sbin/nologin knot
# chown -R knot.knot /var/knot/data/var/log
# chown -R knot.knot /var/knot/data/run/knot
# chown -R knot.knot /var/knot/data/lib/knot
# chown -R knot.knot /var/knot/data/lib/knot/signed
# /usr/local/nsd/sbin/nsd-control-setup
# cp -a /usr/local/nsd/etc/nsd/* /var/nsd/chroot/etc/nsd/
# vi /etc/logrotate.d/nsd
# vi /etc/logrotate.d/knot
---
/var/log/nsd/*.log {
create 0644 nsd nsd
/var/log/knot/*.log {
create 0644 knot knot
missingok
sharedscripts
postrotate
systemctl restart nsd > /dev/null 2>/dev/null || true
systemctl reload knot > /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
---
コンフィグの元ネタは、&font(b){[[IIJ Engineers Blog:+https://eng-blog.iij.ad.jp/archives/5739]]};を参照。
DNSゾーン編集用のローカルDNSサーバ(127.0.0.1:10053)からDNSゾーンを受け取り、
KnotでDNSSEC署名を施した物を、フロントエンドのDNSサーバ(127.0.0.1:53)にゾーン転送させる。
また、サブミッション設定を行い上位の権威DSNにDSレコードが追加されたかを自動判定させる。
サブミッション確認用キャッシュDNSはプロバイダの物などを設定する。
#region(&color(#ff0000){サンプル};)
## Knot DNS Config
##
## 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
version: "unknown"
rundir: "/var/knot/data/run/knot"
user: knot:knot
listen: 127.0.0.1@20053
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"
database:
storage: "/var/knot/data/lib/knot"
version: "unknown"
identity: "unknown"
hide-version: yes
hide-identity: yes
log:
- target: "/var/knot/data/var/log/knot.log"
any: info
remote:
- id: backend
address: 127.0.0.1@10053
- id: frontend
address: 127.0.0.1@53
- id: resolv
address: [ 8.8.8.8, 8.8.4.4 ]
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"
acl:
- id: acl_backend
address: 127.0.0.1
action: notify
- id: acl_frontend
address: 127.0.0.1
action: transfer
submission:
- id: sub_resolv
parent: resolv
zone:
name: "example.com"
zonefile: "master/example.com"
# notify: 192.168.0.3@53 NOKEY
# notify-retry: 5
# provide-xfr: 53 NOKEY
policy:
- id: nsec3
algorithm: ecdsap256sha256
nsec3: on
ksk-submission: sub_resolv
template:
- id: default
master: backend
notify: frontend
storage: "/var/knot/data/lib/knot/signed"
acl: [ acl_backend, acl_frontend ]
dnssec-signing: on
dnssec-policy: nsec3
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
- domain: example.com
file: "example.com.zone"
#endregion
~
-&size(16){&font(b){4. 動作確認};};
NSDを実際に起動させて動作確認を行う。
今回はDNSクエリログ出力パッチを適用している為、BINDの様なDNSクエリログも出力される。
# systemctl enable nsd
# systemctl start nsd
# cat /var/log/nsd.log
*DNSSEC署名 [#oe95ebd1]
DNSSEC鍵が無くなると、&color(#ff0000){一度DNSSECを解除して"Chain of Trust"を解除する必要};が出てくる。
この事態を避ける為に"storage"で指定したディレクトリを定期的にバックアップする必要がある。
Knotを起動すると『notice: [example.com.] DNSSEC, KSK submission, waiting for confirmation』と表示される。
コレが表示された後に"keymgr"コマンドを打つ事で、上位権威DNSに登録するDSレコードを確認出来る。
# /usr/local/knot/sbin/keymgr -c /etc/knot.conf example.com ds
---
[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
example.com. DS 28302 13 2 XXXXX
example.com. DS 28302 13 4 XXXXX
keymgrで確認したDSレコードを、&color(#ff0000){VALUE-DOMAINやゴンベエドメイン等のDSレコード対応レジストラ経由で登録する。};
DSレコード登録方法はレジストラによって変わるので、ドキュメントを確認するか問い合わせる。
VALUE-DOMAINを使っている場合、DSレコード登録に対応しているccTLD/gTLDならば、
ネームサーバ設定欄に次の様なDNSSEC署名鍵設定が表示されるようになる。
&ref(dnssec-vd.png,left,nowrap,50%);
サブミッション設定をしている場合、定期的にDSレコードを確認し自動的にDNSSEC署名が行われる。
手動でDNSSEC署名を開始する場合、DSレコードが上位権威DNSに登録されている事を確認した上で、
次のコマンドを打ち込むと署名を開始出来る。
# /usr/local/knot/sbin/knotc -c /etc/knot.conf zone-ksk-submitted example.com