【RHEL】最新のRHEL9.4を使ってDNS兼NTPサーバを構築する

## はじめに
インターネットへの接続ができない、クローズドな環境にDNS兼NTPサーバを構築します。
ネット上に参考となる情報は色々ありましたが、RHEL9.4の場合の情報は少なかったため書き残します。

## 環境情報
* ハイパーバイザー：VMware ESXi 8.0 update2（Nutanix AHVでも可）
* OS：Red Hat Enterprise Linux 9.4（執筆時点で最新ver）

各サーバのホスト名は以下。
* DNS兼NTPサーバ：hostserver
* クライアントサーバ：clientserver
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691986/8c255fa6-1f53-428c-467e-979607016e5c.png)

※動作確認のため作成するクライアントサーバも同じOSで作成します。

## 0.前提
DNS機能とNTP機能を実現するにあたり、以下パッケージは導入済みと想定します。
・chrony
・bind
・bind-utils

## 1.共通設定
DNS機能とNTP機能を実現するにあたって以下を実行します。
```
★DNS(dns)とNTP(ntp)で利用するポートを解放するため、firewalldサービスは無効

[root@hostserver ~]# systemctl disable firewalld

★DNS機能（nameサービス)とNTP機能(chronydサービス)への影響を考慮し、SELinuxは無効

[root@hostserver ~]# cat /etc/selinux/config
SELINUX=enforcing

[root@hostserver ~]# vi /etc/selinux/config
[root@hostserver ~]# cat /etc/selinux/config
SELINUX=disabled

★再起動
[root@hostserver ~]#systemctl reboot
```
★追記
SELinuxの無効化方法が誤っていました。
正しくは、以下リンクを参考にコンフをいじるのではなくコマンドで設定変更してください。
https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/9/html/using_selinux/enabling_and_disabling_selinux-disabling_selinux_changing-selinux-states-and-modes

## 2.時刻同期設定
chrony.confに以下の設定を行い、hostserverをNTPサーバとして設定します。

```
[root@hostserver ~]# cat /etc/chrony.conf

# Use public servers from the pool.ntp.org project.		
# Please consider joining the pool (https://www.pool.ntp.org/join.html).		
# pool 2.rhel.pool.ntp.org iburst		
		
# Use NTP servers from DHCP.		
sourcedir /run/chrony-dhcp		
		
# Record the rate at which the system clock gains/losses time.		
driftfile /var/lib/chrony/drift		
		
# Allow the system clock to be stepped in the first three updates		
# if its offset is larger than 1 second.		
makestep 1.0 3		
		
# Enable kernel synchronization of the real-time clock (RTC).		
rtcsync		
		
# Enable hardware timestamping on all interfaces that support it.		
#hwtimestamp *		
		
# Increase the minimum number of selectable sources required to adjust		
# the system clock.		
#minsources 2		
		
# Allow NTP client access from local network.		
#allow 192.168.0.0/16		
allow

# Serve time even if not synchronized to a time source.		
local stratum 10
```
デフォルト値から設定変更している箇所を以下に抜粋します。

①上位NTPサーバへの参照設定をコメントアウトします。
※「server localhost iburst」としてしまうと、NTPサーバーが自身を繰り返し参照し時刻同期できなくなるようです。
```
# Use public servers from the pool.ntp.org project.		
# Please consider joining the pool (https://www.pool.ntp.org/join.html).		
# pool 2.rhel.pool.ntp.org iburst 👈コメントアウト
```

②アクセス許可を行います。今回は全てのセグメントからのアクセスを許可するので、allowを追加しました。
（aloow 10.0.0.0/24としてもいいかも）
```
# Allow NTP client access from local network.		
#allow 192.168.0.0/16		
allow　👈追加
```

③本サーバをNTPサーバとして機能させて時刻同期を行えるように設定します。
```
# Serve time even if not synchronized to a time source.		
local stratum 10　👈コメントアウトを外す
```

この状態で、クライアントサーバ側（10.0.0.4）のchrony.confに「server 10.0.0.3 iburst」を入れた後、以下コマンドを実行し、時刻同期ができることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691986/60a502e9-7784-9b74-4ad2-ef552ea7c2a6.png)
※　^* IPアドレス　となっていればOK
```
[root@clientserver ~]# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* 10.0.0.3                     10   6    17     4    +55us[  +66us] +/-  221us
[root@clientserver ~]#
```

ちゃんと時刻同期ができました。

## 3.名前解決設定
### named.confの設定
named.confを以下の通り修正し、DNSとして機能するように設定します。
ドメイン名は「demo.localdomain」です。
```
[root@hostserver ~]# cat /etc/named.conf
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
acl "internalnet"{10.0.0.0/24;};

options {
        listen-on port 53 { internalnet; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     {internalnet; localhost; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        recursion yes;

        dnssec-validation yes;

        managed-keys-directory "/var/named/dynamic";
        geoip-directory "/usr/share/GeoIP";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";


zone "demo.localdomain" {
      type master;
      file "demo.localdomain.zone";
      allow-query { any; };
      allow-transfer { none; };
};

zone "0.0.10.in-addr.arpa" {
    type master;
    file "0.0.10.in-addr.arpa.zone";
    allow-query { any; };
    allow-transfer { none; };
};

```
デフォルト値から設定変更している箇所を以下に抜粋します。

①本bindにアクセスできるネットワークを定義します。
```
acl "internalnet"{10.0.0.0/24;};　👈追加
```

②IPv4でlistenするポートとネットワークを定義します。ネットワークは①で定義した範囲からの許可を行います。
```
 listen-on port 53 { internalnet; };　👈デフォルト値を修正
```

③本bindに問い合わせ可能なクライアントの許可設定を行います。
```
allow-query     {internalnet; localhost; };　👈internalnetを追加
```

④正引きゾーンの設定を行います。
参照先のファイルに関する設定は後述します。
```
👇新規で追加
zone "demo.localdomain" {
      type master;
      file "demo.localdomain.zone";
      allow-query { any; };
      allow-transfer { none; };
};
```

⑤逆引きゾーンの設定を行います。
参照先のファイルに関する設定は後述します。
```
👇新規で追加
zone "0.0.10.in-addr.arpa" {
    type master;
    file "0.0.10.in-addr.arpa.zone";
    allow-query { any; };
    allow-transfer { none; };
};
```

### 正引きゾーンの設定
以下に正引きゾーンの設定内容を記載します。
named.confで設定した通り、demo.localdomain.zoneファイルを新規作成します。ホストとクライアント間でホスト名（ドメイン名）による名前解決ができるよう設定します。

```
[root@hostserver ~]# cat /var/named/demo.localdomain.zone
$TTL 8h
@       IN      SOA     hostserver.demo.localdomain. hostmaster.demo.localdomain.(
                          2022070601 ; serial number
                          1d         ; refresh period
                          3h         ; retry period
                          3d         ; expire time
                          3h )       ; minimum TTL
             IN      NS      hostserver.demo.localdomain.
hostserver     IN      A       10.0.0.3
clientserver     IN      A       10.0.0.4
```

### 逆引きゾーンの設定
以下に正引きゾーンの設定内容を記載する。
named.confで設定した通り、0.0.10.in-addr.arpa.zoneファイルを新規作成する。ホストとクライアント間でIPアドレスによる名前解決ができるよう設定する。
```
$TTL 8h	
@ IN SOA hostserver.demo.localdomain. hostmaster.demo.localdomain. (	
                          2022070601 ; serial number	
                          1d         ; refresh period	
                          3h         ; retry period	
                          3d         ; expire time	
                          3h )       ; minimum TTL	
	
                 IN NS   hostserver.demo.localdomain.	
3                IN PTR  hostserver.demo.localdomain.	
4                IN PTR  clientserver.demo.localdomain.
```

### 動作確認
上記設定が完了したら、各設定ファイルに問題がないかチェックをします。以下の通り、エラーが出なければ問題のない状態です。
```
★/etc/named.confの確認
[root@hostserver ~]# named-checkconf -z /etc/named.conf
zone localhost.localdomain/IN: loaded serial 0
zone localhost/IN: loaded serial 0
zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
zone 0.in-addr.arpa/IN: loaded serial 0
zone demo.localdomain/IN: loaded serial 2022070601
zone 0.0.10.in-addr.arpa/IN: loaded serial 2022070601

★正引きゾーンファイルの確認
[root@hostserver ~]# named-checkzone demo.localdomain.zone /var/named/demo.localdomain.zone
zone demo.localdomain.zone/IN: loaded serial 2022070601
OK

★逆引きゾーンファイルの確認
[root@hostserver ~]# named-checkzone 0.0.10.in-addr.arpa.zone /var/named/0.0.10.in-addr.arpa.zone
zone 0.0.10.in-addr.arpa.zone/IN: loaded serial 2022070601
OK
```

上記を確認できれば、namedサービスを再起動させます。
```
[root@hostserver ~]# systemctl restart named
```

続いて、クライアント側のresolv.confにDNS情報を登録します。
```
[root@clientserver ~]# nmcli d
DEVICE  TYPE      STATE            CONNECTION
ens3    ethernet  接続済み         ens3
lo      loopback  接続済み (外部)  lo
[root@clientserver ~]#
[root@clientserver ~]# nmcli connection modify "ens3" ipv4.dns 10.0.0.3
[root@clientserver ~]#
[root@clientserver ~]# nmcli connection up "ens3"
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/3)
[root@clientserver ~]#
[root@clientserver ~]#
[root@clientserver ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 10.0.0.3
```

では、クライアント側から名前解決ができるか確認しましょう。
nslookupを使い確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691986/cfbea719-dcc4-de7e-d197-6c9c71e896c0.png)
```
[root@clientserver ~]# nslookup 10.0.0.4
4.0.0.10.in-addr.arpa   name = clientserver.demo.localdomain.

[root@clientserver ~]# nslookup 10.0.0.3
3.0.0.10.in-addr.arpa   name = hostserver.demo.localdomain.

[root@clientserver ~]#
[root@clientserver ~]# nslookup hostserver.demo.localdomain.
Server:         10.0.0.3
Address:        10.0.0.3#53

Name:   hostserver.demo.localdomain
Address: 10.0.0.3

[root@clientserver ~]#
[root@clientserver ~]# nslookup clientserver.demo.localdomain.
Server:         10.0.0.3
Address:        10.0.0.3#53

Name:   clientserver.demo.localdomain
Address: 10.0.0.4

[root@clientserver ~]#
```

ちゃんと、ホスト名（ドメイン名）でもIPアドレスでも名前解決ができていますね。


以上

### 参考
■RHEL9.4の公式ドキュメント

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/managing_networking_infrastructure_services/assembly_configuring-zones-on-a-bind-dns-server_assembly_setting-up-and-configuring-a-bind-dns-server#proc_setting-up-a-forward-zone-on-a-bind-primary-server_assembly_configuring-zones-on-a-bind-dns-server