シンプルで高速な権威 DNS サーバー NSD を試してみた

一般的な LAN 内権威 DNS サーバーの例です。
## 環境
サーバー IP アドレス: `192.168.182.10`
AlmaLinux 9.5
NSD 4.12.0
SELinux 有効
## インストール
epel にもありますが、最新でない場合があるので今回はソースからビルドします。
```
# dnf install gcc make bison flex openssl-devel libevent-devel systemd-devel
# cd /usr/src
# curl -O https://www.nlnetlabs.nl/downloads/nsd/nsd-4.12.0.tar.gz
# tar xf nsd-4.12.0.tar.gz
# cd nsd-4.12.0
# ./configure --enable-systemd 
# make
# make install
```
## 初期設定
NSD を実行するユーザーを追加します。
```
# groupadd nsd
# useradd -g nsd -s /sbin/nologin nsd
```
`nsd-control` が使用する鍵ペア等を生成します。
また、NSD が使用するディレクトリの所有者を変更します。
ゾーンファイルを格納するディレクトリも作成します。
```
# nsd-control-setup 
# mkdir /etc/nsd/zone
# chown nsd:nsd -R /var/db/nsd
```
systemd に NSD を登録します。
```/usr/lib/systemd/system/nsd.service
[Unit]
Description=NSD DNS Server
After=syslog.target network-online.target

[Service]
Type=notify
ExecStart=/usr/local/sbin/nsd -d -P "" -c /etc/nsd/nsd.conf $NSD_EXTRA_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```
ログローテーションの設定を追加します。
```/etc/logrotate.d/nsd.conf
/var/log/nsd.log
{
        daily
        rotate 7
        missingok
        create
        dateyesterday
        postrotate
                nsd-control log_reopen
        endscript
}
```
## NSD の設定
以下の定義ファイルを作成します。
```/etc/nsd/nsd.conf
server:
    ip-address: 192.168.182.10
    ip-address: 127.0.0.1

    reuseport: yes
    do-ip6: no

    server-count: 2 # システムのCPUコア数に合わせる

    tcp-count: 1000 # チューニング事項
    tcp-reject-overflow: yes
    tcp-timeout: 3

    username: nsd

    logfile: /var/log/nsd.log
    verbosity: 3

    hide-identity: yes
    hide-version: yes

remote-control: # nsd-control の設定
    control-enable: yes
    control-interface: 127.0.0.1

pattern:
    name: acl_query
    allow-query: 192.168.182.0/24 NOKEY # TSIG 鍵無しでこのサブネットからのクエリを受け付ける
    allow-query: 192.168.207.0/24 NOKEY
    allow-query: 127.0.0.0/8      NOKEY

zone:
    name: example.com.
    zonefile: /etc/nsd/zone/example.com.zone
    include-pattern: acl_query

zone:
    name: 182.168.192.in-addr.arpa.
    zonefile: /etc/nsd/zone/182.168.192.in-addr.arpa.zone
    include-pattern: acl_query
```
ゾーンファイルを作成します。
```/etc/nsd/zone/example.com.zone
$ORIGIN example.com.
$TTL 3600
@       IN      SOA     dns1.example.com. root.example.com. (
                  0          ; Serial
                  900        ; refresh
                  600        ; retry
                  86400      ; expire
                  900        ; minimum
)

@                 IN NS        dns1.example.com.
dns1              IN A         192.168.182.10
dns-r             IN A         192.168.182.12
```
```/etc/nsd/zone/182.168.192.in-addr.arpa.zone
$ORIGIN 182.168.192.in-addr.arpa.
$TTL 3600
@       IN      SOA     dns1.example.com. root.example.com. (
                  0          ; Serial
                  900        ; refresh
                  600        ; retry
                  86400      ; expire
                  900        ; minimum
)

@                                IN NS        dns1.example.com.
10                               IN PTR       dns1.example.com.
12                               IN PTR       dns-r.example.com.
```
定義ファイルが正しいか確認します。（何も出力されなければ OK です）
その後、FW に通信許可を設定し、NSD を起動します。
```
# chown nsd:nsd -R /etc/nsd
# nsd-checkconf /etc/nsd/nsd.conf
# firewall-cmd --add-service=dns --permanent
# firewall-cmd --reload
# systemctl enable nsd
# systemctl start nsd
```
## 確認
以下の通り解決できます。
```
Resolve-DnsName dns1.example.com. -server 192.168.182.10

Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
dns1.example.com                               A      3600  Answer     192.168.182.10

Name      : example.com
QueryType : NS
TTL       : 3600
Section   : Authority
NameHost  : dns1.example.com


Resolve-DnsName example.com. -server 192.168.182.10

Name                        Type TTL   Section    PrimaryServer               NameAdministrator
----                        ---- ---   -------    -------------               -----------------
example.com                 SOA  900   Authority  dns1.example.com            root.example.com


Resolve-DnsName example.com. -server 192.168.182.10 -type NS

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
example.com                    NS     3600  Answer     dns1.example.com

Name       : dns1.example.com
QueryType  : A
TTL        : 3600
Section    : Additional
IP4Address : 192.168.182.10


Resolve-DnsName 192.168.182.10 -server 192.168.182.10

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
10.182.168.192.in-addr.arpa    PTR    3600  Answer     dns1.example.com
182.168.192.in-addr.arpa       NS     3600  Authority  dns1.example.com
```