【Linux】セキュアなDNSサーバ構築シリーズ② DNS サーバーを構築する

## はじめに

前回の記事で、仮想ネットワークにドメイン取得し、4台の仮想マシーン作成・それぞれにIPV4・IPv6アドレス
を付与し、pingの疎通確認まで確認した。

[【Linux】セキュアなサーバ構築シリーズ①](https://qiita.com/yuzo_____/items/bbd7aa8121bb4ea9b7b3)

しかし、現状では外部ネットワークにIPアドレス指定ではpingで疎通できるが、
ドメイン名指定では疎通確認できません。

```
[root@sv ~]# ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=106 ms
~
1 packets transmitted, 1 received, 0% packet loss, time 0ms

[root@sv ~]# ping www.google.com
ping: www.google.com: 名前またはサービスが不明で
```

↓ドメイン内のトポロジー図（IP少し間違ってるのであとで修正したものアップする）
![FhTK9nNagAEacBr.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935967/210888b1-cb6d-8a41-abf6-5bc7c69e5f22.jpeg)

名前解決を行う設定ファイル `/etc/resolve.conf`を調べます。


```:For DNS SV
[root@ns ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
search d000.mgt.local
nameserver 127.0.0.1
nameserver ::1
```

```:For CL1 SV
[root@cl1 ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
search d000.mgt.local
nameserver 172.16.1.202
nameserver 2001::ca
```

DNS SVの設定ファイルではname serverは自分自身・ CL1 SVでは172.16.1.202（2001::ca）がname serverだと記述している。

しかし172.16.1.202のサーバはDNSサーバとして構築されていないので名前解決ができず、ドメイン名指定のping疎通確認ができないのが現在の状態。

では名前解決できるようにDNSサーバ構築していく

## DNSサーバー構築

DNSサーバーソフトのパッケージ名はBIND。
同パッケージをDL・インストードする。

```
dnf install bind -y
```
指定したパッケージがインストールされているか確認する。

```
[root@ns ~]# rpm -qa | grep "^bind"
bind-9.11.36-3.el8_6.1.x86_64
bind-libs-lite-9.11.36-3.el8_6.1.x86_64
bind-utils-9.11.36-3.el8_6.1.x86_64
bind-license-9.11.36-3.el8_6.1.noarch
bind-libs-9.11.36-3.el8_6.1.x86_64
```

BINDのバージョン9.11がインストールできたことを確認。

## 設定ファイル編集`/etc/named.conf`
namedデーモン（DNSサーバとして仕事するデーモン）の設定ファイルは`/etc/named.conf`

設定ファイルを編集する前に、パーミッションの確認とバックアップを取っていく

```
[root@ns ~]# ls -l /etc/named.conf 
-rw-r-----. 1 root named 1705 10月  5 01:10 /etc/named.conf
[root@ns ~]# cp -p /etc/named.conf /etc/named.conf_org2
```
パーミッションが640なので一般ユーザは見ることを許されていないファイル。

雛形ファイル（設定ファイルのサンプル）のディレクトリ`/usr/share/doc/bind/sample/etc/`を調べる
```
[root@ns ~]# ls -l /usr/share/doc/bind/sample/etc/named*
-rw-r--r--. 1 root root 8599 10月  5 01:10 /usr/share/doc/bind/sample/etc/named.conf
-rw-r--r--. 1 root root 1029 10月  5 01:10 /usr/share/doc/bind/sample/etc/named.rfc1912.zones
```

雛形ファイルを/etc配下にコピーし、named.confを640・所属グループをnamedに変更する。

```
[root@ns ~]# cp -p /usr/share/doc/bind/sample/etc/named* /etc
cp: '/etc/named.conf' を上書きしますか? yes
cp: '/etc/named.rfc1912.zones' を上書きしますか? yes
[root@ns ~]# chgrp named /etc/named.conf
[root@ns ~]# chmod 640 /etc/named.conf
[root@ns ~]# chgrp named /etc/named.rfc1912.zones 
[root@ns ~]# ls -l /etc/named*
-rw-r-----. 1 root named 8599 10月  5 01:10 /etc/named.conf
-rw-r-----. 1 root named 1705 10月  5 01:10 /etc/named.conf_org2
-rw-r--r--. 1 root named 1029 10月  5 01:10 /etc/named.rfc1912.zones
-rw-r--r--. 1 root named 1070 10月  5 01:10 /etc/named.root.key

```
/etc/named*の4つのファイルの所有者・所有グループが`root, named`であることを確認

続いて、zoneファイルの設定ファイルも編集する

```
[root@ns ~]# ls -l /var/named*
合計 16
drwxrwx---. 2 named named    6 10月  5 01:10 data
drwxrwx---. 2 named named    6 10月  5 01:10 dynamic
-rw-r-----. 1 root  named 2253 10月  5 01:10 named.ca
-rw-r-----. 1 root  named  152 10月  5 01:10 named.empty
-rw-r-----. 1 root  named  152 10月  5 01:10 named.localhost
-rw-r-----. 1 root  named  168 10月  5 01:10 named.loopback
drwxrwx---. 2 named named    6 10月  5 01:10 slaves
[root@ns ~]# cp -p /usr/share/doc/bind/sample/var/named/named* /var/named
cp: '/var/named/named.ca' を上書きしますか? yes
cp: '/var/named/named.empty' を上書きしますか? yesy
cp: '/var/named/named.localhost' を上書きしますか? yes
cp: '/var/named/named.loopback' を上書きしますか? yes
[root@ns ~]# cp -p /usr/share/doc/bind/sample/var/named/my* /var/named
[root@ns ~]# ls -l /var/named/
合計 24
drwxrwx---. 2 named named    6 10月  5 01:10 data
drwxrwx---. 2 named named    6 10月  5 01:10 dynamic
-rw-r--r--. 1 root  root    56 11月 15 05:55 my.external.zone.db
-rw-r--r--. 1 root  root    56 11月 15 05:55 my.internal.zone.db
-rw-r-----. 1 root  named 2253 11月 15 05:54 named.ca
-rw-r-----. 1 root  named  152 11月 15 05:54 named.empty
-rw-r-----. 1 root  named  152 11月 15 05:54 named.localhost
-rw-r-----. 1 root  named  168 11月 15 05:54 named.loopback
drwxrwx---. 2 named named    6 10月  5 01:10 slaves

```

設定ファイルを編集する際は、雛形ファイルを利用した方がいい（らしい）

zoneファイルについて
https://www.eis.co.jp/bind9_src_build_2/

## DNSキャッシュサーバ構築

DNSサーバには2種類ある。
①コンテンツサーバ・・・ドメイン名を管理
②キャッシングサーバ・・・外部からの問い合わせに対応する。一回調べた名前はキャッシュSVに保管されるので、次回からはコンテンツSVなどに問い合わせることなく、IPアドレスを返せるようになる。
IPアドレスを調べたい場合は、キャッシュSVに問い合わせする。

今回はコンテンツサーバでもありキャッシングサーバーでもある一つのDNSサーバを構築する。



## /etc/named.confの構成






## `named.conf`の編集

前述で雛形ファイルを/etc/named.confに上書きしたが、このファイルを使っていくので、バックアップを取っておく。

```
[root@ns ~]# cp -p /etc/named.conf /etc/named.conf_org
[root@ns ~]# ls -l /etc/named*
-rw-r-----. 1 root named 8599 11月 15 05:52 /etc/named.conf
-rw-r-----. 1 root named 8599 11月 15 05:52 /etc/named.conf_org
-rw-r-----. 1 root named 1705 10月  5 01:10 /etc/named.conf_org2
-rw-r--r--. 1 root named 1029 10月  5 01:10 /etc/named.rfc1912.zones
-rw-r--r--. 1 root named 1070 10月  5 01:10 /etc/named.root.key
```

### まずキャッシングサーバの設定を行う
https://www.isoroot.jp/blog/2929/
https://tech.synapse.jp/entry/2020/07/15/130000#namedconf%E3%81%AE%E9%87%8D%E8%A6%81%E3%81%AA%E8%A8%AD%E5%AE%9A

変更点は次の通り
・listen-on port 53 (すべてのユーザに対し53番ポートのアクセスを許可する)※#53はDNSポート
  デフォルトでは自身のIPだけだが、`any;`を追記しすべてのユーザーからのアクセス許可
・allow-query
  DNSサーバへの問い合わせそのものを許可または拒否する。
・allow-query-cache
キャッシュDNSサーバが保持しているキャッシュの情報への問い合わせを許可または拒否する。
・allow-recursion（追記）
 再帰問い合わせ受付ホスト
・forwarders
 問い合わせ転送先DNSの指定
 ・recursion
  リゾルバー（キャッシングDNSサーバ）として動作させる場合yes
・
  


```
 26         //listen-on port 53     { any; };
 27         listen-on port 53       { any; 127.0.0.1; };
 28 
 29         //listen-on-v6 port 53  { any; };
 30         listen-on-v6 port 53    { any; ::1; };

 48         allow-query             { any; localhost; };
 49         allow-query-cache       { any; localhost; };
 50         allow-recursion         { any; localhost; };
 52         forwarders              { 8.8.8.8; 8.8.4.4; };

65          recursion yes;
```


## 自分自身の問い合わせ設定：view "localhost_resolver"

次に自分自身の問い合わせにどうするかの設定を`/etc/named`ファイルの`view "localhost_resolver"`内で定義する。

今回は編集する箇所がないので、確認だけになる。

```
115 view "localhost_resolver"
116 {
121         recursion yes;
124         zone "." IN {
125                 type hint;
126                 file "/var/named/named.ca";
127         };
128
134 };
```

### 鍵の設定は今はしないのでコメントアウト

```
188 ###key ddns_key
189 ###{
190 ###     algorithm hmac-md5;
191 ###     secret "use /usr/sbin/dnssec-keygen to generate TSIG keys";
192 ###};
```

### 外部NWからの問い合わせ設定：view "external''


今回は外部NWからの問い合わせを受け付けない仕様にするので、コメントアウトする。
```
194 view "external"
195 {

206 ###     recursion no;

213 ###     zone "my.external.zone" { 
214 ###             type master;
215 ###             file "my.external.zone.db";
216 ###     };
217 };
```

以上、設定ファイルの編集終了。

構文チェックコマンド`named-checkconf`を使ってエラーがでないか確認する

```
[root@ns ~]# named-checkconf /etc/named.conf
[root@ns ~]# 
```



## キャッシングSVの動作確認

自分自身がnameserverであることを確認

```
[root@ns ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
search d000.mgt.local
nameserver 127.0.0.1
nameserver ::1
```

上記で設定ファイルを変更した内容をデーモン起動で反映する前に、現在は名前解決されていないためドメイン利用の外部通信できないこと再確認。

```
[root@ns ~]# ping www.google.com -c 3
ping: www.google.com: 名前またはサービスが不明です
```

では自ホストをDNSサーバーとしてデーモンを起動する。

```
[root@ns ~]# systemctl status named
named-setup-rndc.service  named.service             
[root@ns ~]# systemctl status named.service 
● named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
[root@ns ~]# systemctl start named.service 
[root@ns ~]# systemctl status named.service 
   Active: active (running) since Tue 2022-11-15 20:28:46 JST; 2s ago
   Main PID: 4110 (named)
   asks: 5 (limit: 23530)
   Memory: 29.3M
   CGroup: /system.slice/named.service
           └─4110 /usr/sbin/named -u named -c /etc/named.conf

```

これでDNAサーバーとして起動したので、ドメイン名指定でも名前解決可能になり、次のようにpingで疎通がとれる。


```
[root@ns ~]# ping www.google.com -c 2
PING www.google.com (142.250.207.36) 56(84) bytes of data.
64 bytes from nrt13s55-in-f4.1e100.net (142.250.207.36): icmp_seq=1 ttl=55 time=31.4 ms
64 bytes from nrt13s55-in-f4.1e100.net (142.250.207.36): icmp_seq=2 ttl=55 time=81.4 ms
```
一応、稼働してるnamedデーモンのプロセスIDを確認

```
[root@ns ~]# ps aux | grep named | grep -v grep
named       4110  0.0  0.8 343456 32452 ?        Ssl  20:28   0:00 /usr/sbin/named -u named -c /etc/named.conf
```


### システム起動時にnamed.serviceの起動を設定
```
[root@ns ~]# systemctl is-enabled named.service 
disabled
[root@ns ~]# systemctl enable named.service 
Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /usr/lib/systemd/system/named.service.
[root@ns ~]# systemctl is-enabled named.service 
enabled

```


しかし、ドメイン内の他のSV（CL1・WEB）は外部NWへドメイン指定でping遅れない（名前解決ができていない）



## ゾーンファイルを作る

ゾーンファイルとは・・・
 ⇒ コンテンツサーバが管理するドメイン内（ゾーン）のIPアドレスとドメイン名の対応表

ゾーンファイルの書き方（zone statement）は次のいずれかの方法で定義される。

① 設定ファイルに直接入力する
or
②外部ファイルに"zone statement"を定義し、それを"include"で読み込む。

今回は方法②で設定する。


### named.confの編集

`"view localhost_resolver''`と `"view internal''` の`include "/etc/named.rfc1912.zones";`の直下に以下を追記する
```
view "localhost_resolver"
116 {
133         include "/etc/named.rfc1912.zones";
134         include "/etc/named.common.zones";    ←追記
135 };
136 view "internal"
137 {

152          */
153         include "/etc/named.rfc1912.zones";
154         include "/etc/named.common.zones";    ←追記
160};
```

### 外部ファイル：Zone Statementの定義

```:vim /etc/named.common.zones
  1 zone "d000.mgt.local" IN {
  2         type master;
  3         file "d000.mgt.local.db";
  4 };
```

3行目の`d000.mgt.local.db`が実際のzoneファイルになり、`/var/named`配下に手動で新規作成する。

`/var/named/d000.mgt.local.db`にドメインの情報を登録する。これを【Zoneファイル】と呼ぶ。


### 正引きZoneファイル：/var/named/d000.mgt.local.dbの作成

ゾーンファイルの記述の仕方が次のリンク参考
https://www.infraexpert.com/study/tcpip23.html


```:vim /var/named/d000.mgt.local.db
  1 $TTL 86400
  2 $ORIGIN d000.mgt.local.
  3 d000.mgt.local. IN SOA ns.d000.mgt.local. root.d000.mgt.local. (
  4                 2022110901      ; serial
  5                         3H      ; refresh
  6                         15M     ; retry
  7                         1W      ; expiry
  8                         1D      ; minimum
  9 )
 10 d000.mgt.local.         IN      NS       ns.d000.mgt.local.
 11 d000.mgt.local.         IN      MX 10    sv.d000.mgt.local.
 12 d000.mgt.local.         IN      MX 20    sv2.d000.mgt.local.
 13 ns.d000.mgt.local.      IN      A        172.16.1.202
 14 ns.d000.mgt.local.      IN      AAAA     2001::ca
 15 sv.d000.mgt.local.      IN      A        172.16.1.201
 16 sv.d000.mgt.local.      IN      AAAA     2001::c9
 17 sv2.d000.mgt.local.     IN      A       172.16.1.201
 18 cl1.d000.mgt.local.     IN      A       172.16.1.101
 19 cl1.d000.mgt.local.     IN      AAAA     2001::65
 20 cl2.d000.mgt.local.     IN      A        172.16.1.102
 21 cl2.d000.mgt.local.     IN      AAAA     2001::66
 22 www.d000.mgt.local.     IN      A        172.16.1.201
 23 d000.mgt.local.         IN      A        172.16.1.201
 24 dns2.d000.mgt.local.    IN      CNAME   ns.d000.mgt.local.

```

編集した2つのファイルの構文チェック

```
[root@ns ~]# named-checkzone d000.mgt.local /var/named/d000.mgt.local.db
zone d000.mgt.local/IN: loaded serial 2022110901
OK
[root@ns ~]# named-checkconf /etc/named.conf
[root@ns ~]# 
```

namedデーモンの再起動

```
[root@ns ~]# systemctl restart named.service 
[root@ns ~]# systemctl status named.service 
● named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2022-11-16 00:51:05 JST; 18s ago
```

キャッシュSVに溜まったキャッシュのクリア

```
[root@ns ~]# rndc flush
```

systemdを採用したシステムは、`journalctl`コマンドを使って、systemdのログを閲覧できる・

```
[root@ns ~]# journalctl -u named.service 
-- Logs begin at Tue 2022-11-15 18:54:27 JST, end at Wed 2022-11-16 00:56:31 JST. --
11月 15 20:28:45 ns.d000.mgt.local systemd[1]: Starting Berkeley Internet Name Domain (DNS)...
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: zone localhost.localdomain/IN: loaded serial 0
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: zone localhost/IN: loaded serial 0
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: 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
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: zone 0.in-addr.arpa/IN: loaded serial 0
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: zone localhost.localdomain/IN: loaded serial 0
11月 15 20:28:45 ns.d000.mgt.local bash[4106]: zone localhost/IN: loaded serial 0

```

現在、ドメイン内のDNSサーバ以外のSVがドメイン名で外部NWと通信はできない。
その理由は、DNSサーバ側のfirewallの設定がデフォルトの状態のため、DNS問い合わせを拒否してるから。
DNSを許可します。


```
[root@ns ~]# firewall-cmd --add-service=dns --permanent --zone=public
success
[root@ns ~]# systemctl restart firewalld.service 
[root@ns ~]# firewall-cmd --list-services 
cockpit dhcpv6-client dns ssh
```
DNSも許可された。
これで他のSVもDNSサーバに名前解決の問い合わせをできるようになった。


## CLから確認

```
[root@cl1 ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
search d000.mgt.local
nameserver 172.16.1.202
nameserver 2001::ca
```


```
[root@cl1 ~]# ping www.google.com -c 2
PING www.google.com (142.250.207.36) 56(84) bytes of data.
64 bytes from nrt13s55-in-f4.1e100.net (142.250.207.36): icmp_seq=1 ttl=55 time=35.8 ms
64 bytes from nrt13s55-in-f4.1e100.net (142.250.207.36): icmp_seq=2 ttl=55 time=30.6 ms

```

```
[root@cl1 ~]# dig www.google.com 

; <<>> DiG 9.11.36-RedHat-9.11.36-3.el8_6.1 <<>> www.google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54368
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 27

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: ee87e87c9e2730cbe74e402a6373c21719c2e556c41fb4f1 (good)
;; QUESTION SECTION:
;www.google.com.			IN	A

;; ANSWER SECTION:
www.google.com.		11	IN	A	142.250.207.36

```