DNS環境の構築

#1 はじめに
DNSの各種実験をするため、PC上にDNS環境を構築してみました。

#2 環境
##2.1 構成
VMware Workstation 15 Player上の仮想マシン3台を使いました。
・仮想マシンのCentOS版数は`CentOS7.6`。
・`dns`,`web`,`client`はホスト名。本記事では、`dnsサーバ`、`webサーバ`と呼んでいます。
・`abc.test`はテスト用に作成したドメイン。`test`は予約済トップレベルドメイン([rfc6761](https://tools.ietf.org/html/rfc6761))。

```console:構成
                    abc.test ドメイン
+------------------- PC(Windows10) -------------------+
|                                                     |
|                                                     |
|     client              web               dns       |
| +-----------+      +-----------+      +-----------+ |
| |           |      |           |      |           | |
| | CentOS7.6 |      | CentOS7.6 |      | CentOS7.6 | |
| |           |      |           |      |           | |
| |           |      |           |      |           | |
| +--- eth0 --+      +--- eth0 --+      +--- eth0 --+ |
|       | .105             | .109             | .100  |
|       |                  |                  |       |
|       |                  |                  |       |
|       |                  | 192.168.2.0/24   |       |
| +-------------------------------------------------+ |
| |                                                 | |                     Wifi Router
| |            VMware Workstation 15 Player         | |                    +-----------+
| |                                                 | |.x               .1 |           |
| +-------------------------------------------------+ |--------------------| DNS Cache |--->ISP
|                                                     |   192.168.2.0/24   |   server  |
+-----------------------------------------------------+                    +-----------+
```


##2.2 設計方針
・テスト用に作成するドメインは、`abc.test`とする。
・dnsサーバに対する名前解決は以下にしたがう。
 - `abc.test`ドメイン以外の名前解決は、`Wifi Router(192.169.2.1)`に問い合わせをする。
 - `abc.test`ドメイン内の名前解決は、dnsサーバのzoneファイルをもとに行う。

#3 インストール方法
##3.1 bindのインストール
dnsサーバにbindをインストールします。

```console:bindのインストール
[root@dns ~]# yum install bind
```

bindの版数を確認します。

```console:httpdの版数確認
[root@dns ~]# named -v
BIND 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 (Extended Support Version) <id:7107deb>
```

##3.2 httpdのインストール
webサーバにhttpdをインストールします。

```console:httpdのインストール
[root@web ~]# yum install httpd
```

httpdの版数を確認します。

```console:httpdの版数確認
[root@web ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Apr  2 2020 13:13:23
```

##3.3 digのインストール
clientにdigコマンドをインストールします。
digコマンドのインストール／使い方は、[digコマンドの使い方](https://qiita.com/hana_shin/items/e99f64a01f2632b7a719)を参照ください。

```console:digのインストール
[root@client ~]# yum install bind-utils
```

#4 bindの設定ファイル編集
bindの設定ファイル編集は、以下の順序で進めます。
1. /etc/named.conf編集(ZONEステートメント等の各種ステートメントの追加／変更)
2. ZONEファイル編集(A,NSレコード等の登録）


##4.1 /etc/named.conf編集
`named.conf`の設定内容は、以下のとおりです。
デフォルトの`named.conf`との差分を示します。

```console:named.conf設定内容
[root@dns ~]# diff -Nur /etc/named.conf.org /etc/named.conf
--- /etc/named.conf.org 2020-10-26 17:13:56.358803543 +0900
+++ /etc/named.conf     2020-10-26 20:50:19.679976755 +0900
@@ -10,7 +10,7 @@
 // configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html

 options {
-       listen-on port 53 { 127.0.0.1; };
+       listen-on port 53 { 192.168.2.100; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
@@ -18,7 +18,10 @@
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
-       allow-query     { localhost; };
+       allow-query     { 192.168.2.0/24; };
+       allow-recursion { 192.168.2.0/24; };
+       forward only;
+       forwarders { 192.168.2.1; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
@@ -56,6 +59,11 @@
        file "named.ca";
 };

+zone "abc.test" IN {
+        type master;
+        file "abc.test";
+};
+
 include "/etc/named.rfc1912.zones";
 include "/etc/named.root.key";

```

##4.2 ZONEファイル編集
`abc.test`ドメインのZONEファイルを作成します。
`$TTL`やネガティブキャッシュの時間は、意図的に短い値(10秒)を設定しています。

```
[root@dns ~]# cat /var/named/abc.test
$ORIGIN abc.test.
$TTL 10
@    IN SOA     ns.abc.test. root.abc.test. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        10 )    ; minimum

        NS      ns.abc.test.
ns      A       192.168.2.100
www     A       192.168.2.109
client  A       192.168.2.105
```

#5 firewallの設定
bind,およびhttpdが使用するポート番号を開放します。

##5.1 bindが使用するポート番号開放
bindが使用するUDPの53番ポートを開放します。
なお、firewall-cmdコマンドの使い方は、[firewall-cmdコマンドの使い方](https://qiita.com/hana_shin/items/bd9ba363ba06882e1fab)を参照ください。

```console:ポート番号開放
[root@dns ~]# firewall-cmd --add-port=53/udp
success
```

開放したポート番号の確認をします。53番ポートが開放されたことがわかります。

```console:開放したポート番号の確認
[root@dns ~]# firewall-cmd --list-ports
53/udp
```

##5.2 httpdが使用するポート番号開放
httpdが使用するTCPの80番ポートを開放します。

```console:ポート番号開放
[root@web ~]# firewall-cmd --add-port=80/tcp
success
```

開放したポート番号の確認をします。80番ポートが開放されたことがわかります。

```console:開放したポート番号の確認
[root@web ~]# firewall-cmd --list-ports
80/tcp
```

#6 /etc/resolv.confの設定
clientで、`/etc/resolv.conf`の設定を行います。設定内容は以下のとおりです。
・`domain`：テスト用に作成したドメイン(`abc.test`)を指定します。
・`nameserver`：dnsサーバのIPアドレスを指定します。

```console:resolv.confの設定内容
[root@client ~]# cat /etc/resolv.conf
# Generated by NetworkManager
domain abc.test
nameserver 192.168.2.100
```

#7 動作確認(その1)

`abc.test`ドメイン内のwwwサーバに対してpingを実行してみます。

```console:test.abcドメイン内のサーバに対するping
[root@client ~]# ping -c 1 www
PING www.abc.test (192.168.2.109) 56(84) bytes of data.
64 bytes from 192.168.2.109 (192.168.2.109): icmp_seq=1 ttl=64 time=0.528 ms

--- www.abc.test ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.528/0.528/0.528/0.000 ms
```

次に`abc.test`ドメイン以外のwwwサーバに対してpingを実行してみます。

```console:test.abcドメイン以外のサーバに対するping
[root@client ~]# ping -c 1 www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=54 time=112 ms

--- www.example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 112.523/112.523/112.523/0.000 ms
```

#8 動作確認(その2)
`allow-query`および`allow-recursion`に指定するネットワークアドレスを
以下のように変化させたとき、DNS名前解決ができるかどうか確認してみました。
`192.168.3.0/24`は、この記事では未定義のネットワークアドレスです。

表中の`○`,`×`はpingの実行結果です。`○`はping応答あり、`×`はping異常終了を表します。
`www`は、`resolv.conf`のdomain 設定により、`www.abc.test`に展開されます。
なお、pingコマンドの使い方は、[pingコマンドの使い方](https://qiita.com/hana_shin/items/c31b0d05a91244c4db83)を参照ください。

| 項番 | allow-query | allow-recursion | pingの宛先(www)| pingの宛先(www.example.com) |
|:-:|:-----------|:-------------|:---|:---|
|1|192.168.2.0/24|192.168.2.0/24| ○  | ○  |
|2|192.168.3.0/24|192.168.2.0/24| ×  | ○  |
|3|192.168.2.0/24|192.168.3.0/24| ○  | ×  |
|4|192.168.3.0/24|192.168.3.0/24| ×  | ×  |


##8.1 項番1の実行結果

```console:wwwへのping
[root@client ~]# ping -c 1 -q www
PING www.abc.test (192.168.2.109) 56(84) bytes of data.

--- www.abc.test ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.632/0.632/0.632/0.000 ms
```

```console:www.example.comへのping
[root@client ~]# ping -c 1 -q www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.

--- www.example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 111.876/111.876/111.876/0.000 ms
```


##8.2 項番2の実行結果

```console:wwwへのping
[root@client ~]# ping -c 1 -q www
ping: www: 名前またはサービスが不明です
```

```console:www.example.comへのping
[root@client ~]# ping -c 1 -q www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.

--- www.example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 111.940/111.940/111.940/0.000 ms
```


##8.3 項番3の実行結果

```console:wwwへのping
[root@client ~]# ping -c 1 -q www
PING www.abc.test (192.168.2.109) 56(84) bytes of data.

--- www.abc.test ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.514/0.514/0.514/0.000 ms
```

```console:www.example.comへのping
[root@client ~]# ping -c 1 -q www.example.com
ping: www.example.com: 名前またはサービスが不明です
```

##8.4 項番4の実行結果

```console:wwwへのping
[root@client ~]# ping -c 1 -q www
ping: www: 名前またはサービスが不明です
```

```console:www.example.comへのping
[root@client ~]# ping -c 1 -q www.example.com
ping: www.example.com: 名前またはサービスが不明です
```

##8.5 まとめ

|ステートメント | 意味 |
|:-------------|:--------------------------------------------------------------------|
|listen-on     |DNS問い合わせを受け付けるIPアドレスを指定します。                      |
|allow-query   |DNS問い合わせを受け付けるIPアドレスを指定します。`abc.test`ドメイン内の名前解決を要求するDNSクライアントのIPアドレスを指定します。        |
|allow-recursion | 再帰問い合わせを受け付けるIPアドレスを指定します。`abc.test`ドメイン以外の名前解決を要求するDNSクライアントのIPアドレスを指定します。   |
|forwarders |`abc.test`ドメイン以外のドメインの名前解決をおこなうDNSサーバのIPアドレスを指定します。このDNSサーバをフォワーダと呼びます。本記事では`Wifi Router`がフォワーダになります。 |
|forward first |まずフォワーダでは名前解決をします。名前解決ができなかったらdnsサーバで名前解決をします。    |
|forward only  |フォワーダで名前解決をします。フォワーダで名前解決できなくても、dnsサーバで名前解決をしません。 |
|zone          |zoneの定義をします。`abc.test`ドメインの指定、zoneファイルを指定します。|


#9 その他(digコマンドバグっているの???）
ping,ssh,ncコマンドを使った場合、ホスト名でホストにアクセスできます。
しかし、digコマンドの場合、ホスト名を指定しても名前解決ができません。
digコマンドがおかしいのでしょうか???それとも、私の設定がおかしいのでしょうか？

sshの場合、ホスト名(`ns`)を指定するだけで、ホストにログインできます。

```console:sshの場合
[root@client ~]# ssh ns
root@ns's password:
Last failed login: Sat Oct 31 19:57:09 JST 2020 from 192.168.2.105 on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Sat Oct 31 19:30:48 2020 from 192.168.2.105
[root@dns ~]#
```

ncコマンドも、ホスト名を指定するだけで、ホストにアクセスすることができます。
なお、ncコマンドの使い方は、[ncコマンドの使い方](https://qiita.com/hana_shin/items/97e6c03ac5e5ed67ce38)を参照ください。

```console:ncの場合
[root@dns ~]# nc -kl 11111
```

クライアント側は、サーバの11111番ポートにTCPコネクションを確立することができます。

```console:ncの場合
[root@client ~]# nc ns 11111
12345
```


digコマンドの場合、ドメイン名(`abc.test`)も指定すると、ホストにアクセスすることができます。
なお、digコマンドの使い方は、[digコマンドの使い方](https://qiita.com/hana_shin/items/e99f64a01f2632b7a719)を参照ください。


```console:digコマンドの場合（ドメインも指定した場合）
[root@client ~]# dig www.abc.test +short
192.168.2.109
```

しかし、ホスト名だけを指定した場合、ホストの名前解決ができません。
以下の期待値は、`www`のIPアドレス(`192.168.2.109`)です。
このときの様子をtcpdumpで確認すると、ホスト名にドメイン名が補完されていません。
なお、tcpdumpコマンドの使い方は、[tcpdumpの使い方](https://qiita.com/hana_shin/items/385182b05db96ef4e205)を参照ください。

```console:digコマンドの場合
[root@client ~]# dig www +short
[root@client ~]#
```

hostコマンドだと、ホスト名を指定しただけでも、名前解決ができます。

```console:hostコマンドの場合
[root@client ~]# host www
www.abc.test has address 192.168.2.109
```

nslookupコマンドも、ホスト名だけで、名前解決ができます。

```console:nslookupコマンドの場合
[root@client ~]# nslookup www
Server:         192.168.2.100
Address:        192.168.2.100#53

Name:   www.abc.test
Address: 192.168.2.109
```

上記結果より、digコマンドが、`/etc/resolv.conf`を正しく解釈していないように思います。
ようは、digコマンドがバグっている!?

#z 参考情報
[Linux教科書 LPICレベル2 スピードマスター問題集 Version4.5対応](https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC%E3%83%AC%E3%83%99%E3%83%AB2-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version4-5%E5%AF%BE%E5%BF%9C-%E6%9C%89%E9%99%90%E4%BC%9A%E7%A4%BE%E3%83%8A%E3%83%AC%E3%83%83%E3%82%B8%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3/dp/4798151238/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=lpic+%E3%83%AC%E3%83%99%E3%83%AB2&qid=1584167037&sr=8-2)
[Linux教科書 LPICレベル2 Version 4.5対応 (日本語) ](https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC%E3%83%AC%E3%83%99%E3%83%AB2-Version-4-5%E5%AF%BE%E5%BF%9C-%E4%B8%AD%E5%B3%B6/dp/4798151254/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=LPIC&qid=1587548686&s=books&sr=1-3)

[BINDのDNSオープンリゾルバ対策について](https://faq.interlink.or.jp/faq2/View/wcDisplayContent.aspx?id=567)