CentOS8 bindの設定

# CentOS8　にbind をインストールして公開DNSサーバを作る

**CentOS8 は　2021年12月31日でサポート終了なので今更ですが、、、、
書きかけの記事があったので公開しちゃいます。**

## この記事に書かれてる事

* CnetOS8 でbindを動かすための基本的な設定手順
* bindをchrootで動かす方法（この記事の手順通りに進めると named-chrootを動かす事になります）
* 正引きzoneファイルのサンプル
* 逆引きzoneファイルのサンプル
* 外部からDNSへのアクセスを許可するためのfirewalldの設定
* 日常的に使いそうなコマンド例
* named.ca の更新方法

## 準備が必要な情報

* ドメイン名
* ホスト名
* IPアドレス（公開用）
* IPアドレス（アクセスリスト用:リゾルバとしても利用する場合）

## 必要なパッケージ

|パッケージ名|用途|備考|
|:--|:--|:--|
|bind|bind本体||
|bind-chroot|bindのchroot環境|セキュリティを考慮し、特別な事情がない限りchrootで導入しましょう。|
|bind-utils|bindのデバッグツール群||

## bindの導入

必要なパッケージの導入状況を確認し、インストールされていなければインストールします。

```text
[user01@cent8 ~]$ rpm -q bind bind-chroot bind-utils
パッケージ bind はインストールされていません。
パッケージ bind-chroot はインストールされていません。
bind-utils-9.11.4-26.P2.el8.x86_64
[user01@cent8 ~]$ sudo dnf install -y bind bind-chroot
```

## 基本的な設定ファイルの確認

|設定対象|設定内容|対象ファイル|備考|
|:-:|:--|:--|:--|
|○|動作設定|/etc/named.conf||
|○|正引きzoneファイル|/var/named/**example.co.jp**_zone（作成）|ドメイン部分は環境に合わせましょう|
|○|逆引きzoneファイル|/var/named/**192.168.1.0**_rev（作成）|IP部分は環境に合わせましょう|
||rndc設定ファイル|/etc/rndc.conf|
||rndc keyファイル|/etc/rndc.key|自動生成|
|||/etc/named.iscdlv.key|dnssec-lookaside auto 用key：設定不要|
|||/etc/named.rfc1912.zones|localhostに関する推奨設定：設定不要|
|||/etc/named.root.key|DNSKEY for the root zone.：設定不要|
||最新のnamed.ca|/var/named/named.ca|無い場合、rndc-confgen -a を使って作成 dig @a.root-servers.net . ns > /var/named/named.ca 常に更新する必要はないと思いますが、やり方は覚えておきましょう。|
|||/var/named/slaves|slave時 masterから入手したzone情報を保存する|
|||/var/named/data|統計とデバッグ情報を保存するディレクトリ|
||chroot先ディレクトリ|/var/named/chroot|namdの動作に必要なファイル・ディレクトリは、実行時にこのディレクトリ配下に自動マウントされます。設定を行う際に、chrootを意識する必要はありません。|

### 設定前に知っておいていた方が良い事

chrootで利用する場合、設定ファイルの配置に注意してください。
ファイルの実体がある場所と、bind-chroot起動時に読み込まれるファイルの位置は異なります。
ただし、この違いは、bind-chroot起動時に各種ファイルがchroot用ディレクトリ配下にマウントされる事で解消
される為、実ファイル位置（SOURCE側)を意識して設定ファイルの編集／zoneファイルの配置を行いましょう。
※chroot用にファイルのコピーなどは不要です。

* こんな感じにマウントされます。

```shell
[user01@cent8 ~]$ findmnt /dev/mapper/cl-root
TARGET                                                      SOURCE                                                           FSTYPE OPTIONS
/                                                           /dev/mapper/cl-root                                              xfs    rw,relatime,seclab
/var/named/chroot/etc/localtime                             /dev/mapper/cl-root[/usr/share/zoneinfo/Asia/Tokyo]              xfs    rw,relatime,seclab
/var/named/chroot/etc/named.root.key                        /dev/mapper/cl-root[/etc/named.root.key]                         xfs    rw,relatime,seclab
/var/named/chroot/etc/named.conf                            /dev/mapper/cl-root[/etc/named.conf]                             xfs    rw,relatime,seclab
/var/named/chroot/etc/named.rfc1912.zones                   /dev/mapper/cl-root[/etc/named.rfc1912.zones]                    xfs    rw,relatime,seclab
/var/named/chroot/etc/rndc.key                              /dev/mapper/cl-root[/etc/rndc.key]                               xfs    rw,relatime,seclab
/var/named/chroot/etc/crypto-policies/back-ends/bind.config /dev/mapper/cl-root[/usr/share/crypto-policies/DEFAULT/bind.txt] xfs    rw,relatime,seclab
/var/named/chroot/etc/protocols                             /dev/mapper/cl-root[/etc/protocols]                              xfs    rw,relatime,seclab
/var/named/chroot/etc/services                              /dev/mapper/cl-root[/etc/services]                               xfs    rw,relatime,seclab
/var/named/chroot/etc/named                                 /dev/mapper/cl-root[/etc/named]                                  xfs    rw,relatime,seclab
/var/named/chroot/usr/lib64/bind                            /dev/mapper/cl-root[/usr/lib64/bind]                             xfs    rw,relatime,seclab
/var/named/chroot/usr/share/GeoIP                           /dev/mapper/cl-root[/usr/share/GeoIP]                            xfs    rw,relatime,seclab
/var/named/chroot/var/named                                 /dev/mapper/cl-root[/var/named]                                  xfs    rw,relatime,seclab
[user01@cent8 ~]$
```

## bindの設定

### /etc/named.conf への設定記述

bindの基本設定を行います。

* サービス提供インターフェース／ポート番号の指定
* ACLなどのセキュリティ設定（192.168.1.0/24からの再帰問い合わせ受付を設定）
* 管理対象ドメインの設定（example.co.jp/192.168.1.0/24で例示します）
* サービス起動中にファイルを編集する場合、chroot環境での制限からvimではなくviの利用をお勧めします。  
vimを使う場合は backupcopy=yes を宣言してください。 

```r
[user01@cent8 ~]$ sudo vi /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 internals {    // アクセス制限用のACLを追加
    127.0.0.1;
    192.168.1.0/24;
};

options {
	//listen-on port 53 { 127.0.0.1; };  // コメントアウト
	//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     { internals; };    // localhost -> insternals に変更
	allow-query-cache     { internals; };    // cache問い合わせへのacl設定を追加
	allow-transfer  { none; };    // zone転送にaclを設定

	/* 
	 - 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;
	version "";  //version.bind の応答内容をブランクに設定
	hostname ""; //hostname.bind の応答内容をブランクに設定

	dnssec-enable yes;
	dnssec-validation yes;

	managed-keys-directory "/var/named/dynamic";

	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の設定
zone "example.co.jp" IN {
        type master;
        allow-query { any; };
        allow-transfer { 192.168.1.11; };	// 有ればセカンダリサーバを指定
        file "example.co.jp_zone";		// zoneファイル名を指定
        notify yes;				// セカンダリに更新通知を送信する場合 yes に設定
        also-notify { 192.168.1.11; };		// セカンダリサーバがプライベートIPの場合そのIPを指定
};

zone "1.168.192.in-addr.arpa" IN {
        type master;
        allow-query { any; };
        allow-transfer { 192.168.1.11; };	// 有ればセカンダリサーバを指定
        file "192.168.1.0_rev";			// zoneファイル名を指定
        notify yes;				// セカンダリに更新通知を送信する場合 yes に設定
        also-notify { 192.168.1.11; };		// セカンダリサーバがプライベートIPの場合そのIPを指定
};

include "/etc/rndc.key";
//以下の設定は無くても、rndc.keyが読み込まれると、設定したのと同様の動作をします。
//設定変更の際の参考情報として記載しています。
controls {
    inet 127.0.0.1 port 953
    allow { 127.0.0.1; } keys { "rndc-key"; };
};
```

### 設定ファイル構文チェック

間違いを指摘するメッセージが出ない事を確認しましょう。

```shell
[user01@cent8 ~]$ sudo named-checkconf /etc/named.conf
[sudo] user01 のパスワード:
[user01@cent8 ~]$
```

## 権威ゾーンファイルの作成

### exmaple.co.jp zoneのゾーンファイル例

```r
[user01@cent8 ~]$ sudo vi /var/named/example.co.jp_zone

; example.co.jp
$TTL 86400
@       IN      SOA ns1.example.co.jp. postmaster.ns1.example.co.jp. (
                  2020061901              ;Serial	// 変更する度に必ず更新してください。
                  7200                    ;Refresh
                  1800                    ;Retry
                  1209600                 ;Expire
                  900                     ;nagative
                                )
        IN      NS      ns1.example.co.jp.
        IN      NS      ns2.example.co.jp.
;        IN      TXT     "v=spf1 +ip4:xxx.xxx.xxx.xxx ~all"

ns1    IN      A       192.168.1.10
ns2    IN      A       192.168.1.11
localhost IN    A       127.0.0.1
```

### 192.168.1.0/24 の逆引き用ゾーンファイル例

```r
[user01@cent8 ~]$ sudo vi /var/named/192.168.1.0_rev
; 1.168.192.in-addr.arpa
$TTL 86400
@       IN      SOA ns1.example.co.jp. postmaster.ns1.example.co.jp. (
                   2020061901              ;Serial	// 変更する度に必ず更新してください。
                   7200                    ;Refresh
                   1800                    ;Retry
                   1209600                 ;Expire
                   900                    ;negative
                                )
        IN      NS      ns1.example.co.jp.
        IN      NS      ns2.example.co.jp.

10      IN     PTR     ns1.example.co.jp.
11      IN     PTR     ns2.example.co.jp.
```

## named-chrootの起動

chrootを有効にしたbindを使用する場合、起動するサービスは named-chroot になります。
間違って、named を起動しないように注意してください。

### named が起動している場合は停止

```r
[user01@cent8 ~]$ sudo systemctl disable named --now
```

### named-chroot の有効化と起動

```r
[user01@cent8 ~]$ sudo systemctl enable named-chroot --now
Created symlink /etc/systemd/system/multi-user.target.wants/named-chroot.service → /usr/lib/systemd/system/named-chroot.service.
[user01@cent8 ~]$ 
```

### 起動（status）確認

```r
[user01@cent8 ~]$ sudo systemctl status named-chroot

● named-chroot.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named-chroot.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-11-29 17:02:47 JST; 8s ago
  Process: 16297 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} -t /var/named/chroot $OPTIONS (code=exited, status=0/SUCCESS)
  Process: 16288 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -t /var/named/chroot -z "$NAMED>
 Main PID: 16300 (named)
    Tasks: 7 (limit: 37880)
   Memory: 56.1M
   CGroup: /system.slice/named-chroot.service
           └─16300 /usr/sbin/named -u named -c /etc/named.conf -t /var/named/chroot

11月 29 17:02:47 cent8.example.co.jp named[16300]: zone 1.168.192.in-addr.arpa/IN: loaded serial 2020061901
11月 29 17:02:47 cent8.example.co.jp named[16300]: 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月 29 17:02:47 cent8.example.co.jp named[16300]: zone example.co.jp/IN: loaded serial 2020061901
11月 29 17:02:47 cent8.example.co.jp named[16300]: all zones loaded
11月 29 17:02:47 cent8.example.co.jp named[16300]: running
11月 29 17:02:47 cent8.example.co.jp named[16300]: zone 1.168.192.in-addr.arpa/IN: sending notifies (serial 2020061901)
11月 29 17:02:47 cent8.example.co.jp named[16300]: zone example.co.jp/IN: sending notifies (serial 2020061901)
11月 29 17:02:47 cent8.example.co.jp systemd[1]: Started Berkeley Internet Name Domain (DNS).
11月 29 17:02:47 cent8.example.co.jp named[16300]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
11月 29 17:02:47 cent8.example.co.jp named[16300]: resolver priming query complete
[user01@cent8 ~]$
```

### 待ち受け状態の確認

```r
[user01@cent8 ~]$ sudo lsof -P -i:53
COMMAND     PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd-r  1353 systemd-resolve   16u  IPv4  31263      0t0  UDP 127.0.0.53:53
named     16300           named   21u  IPv4  85726      0t0  TCP localhost:53 (LISTEN)
named     16300           named   22u  IPv4  85728      0t0  TCP cent8.example.co.jp:53 (LISTEN)
named     16300           named  512u  IPv4  85722      0t0  UDP localhost:53
named     16300           named  513u  IPv4  85722      0t0  UDP localhost:53
named     16300           named  514u  IPv4  85722      0t0  UDP localhost:53
named     16300           named  515u  IPv4  85727      0t0  UDP cent8.example.co.jp:53
named     16300           named  516u  IPv4  85727      0t0  UDP cent8.example.co.jp:53
named     16300           named  517u  IPv4  85727      0t0  UDP cent8.example.co.jp:53
[user01@cent8 ~]$
```

## Firewalldの設定変更（外部からのクエリを許可）

外部からのqueryを許可するため、 port 53への外部からのアクセスを許可する設定を行います。
53/udpだけでも良い場合もありますが、queryへの応答サイズが大きくなる傾向にある事もから、tcp,udp共にアクセスを許可しておきます。

### firewalld 状態確認

```r
[user01@cent8 ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

[user01@cent8 ~]$
```

### Port 53へのアクセスを許可

```r
[user01@cent8 ~]$ sudo firewall-cmd --permanent --add-service=dns --zone=public
success
[user01@cent8 ~]$ sudo firewall-cmd --reload
success
[user01@cent8 ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client dns https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

[user01@cent8 ~]$
```

参考）
service dnsの設定内容は、/usr/lib/firewalld/services/dns.xml　に記述されてます。

## 日常使用するコマンドたち

### 起動

```r
[user01@cent8 ~]$ sudo systemctl enable named-chroot --now
```

### 停止

```r
[user01@cent8 ~]$ sudo systemctl disable named-chroot --now
```

### 設定ファイル/zoneファイルの再読み込み

```r
[user01@cent8 ~]$ sudo rndc reload
```

### 状態確認

```r
[user01@cent8 ~]$ sudo rndc status
version: BIND 9.11.13-RedHat-9.11.13-6.el8_2.1 (Extended Support Version) <id:ad4df16> ()
running on cent8.example.co.jp: Linux x86_64 4.18.0-193.28.1.el8_2.x86_64 #1 SMP Thu Oct 22 00:20:22 UTC 2020
boot time: Sun, 29 Nov 2020 08:02:47 GMT
last configured: Sun, 29 Nov 2020 08:02:47 GMT
configuration file: /etc/named.conf (/var/named/chroot/etc/named.conf)
CPUs found: 4
worker threads: 4
UDP listeners per interface: 3
number of zones: 105 (97 automatic)
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is OFF
recursive clients: 0/900/1000
tcp clients: 2/150
TCP high-water: 2
server is up and running
[user01@cent8 ~]$
```

### querylogの採取

トラブル対応などでqueryの内容を確認したい場合に有効にしてください。
また、大量のログが生成されるため、調査が終わったら必ず無効化してください。
現在の状態は rndc status で確認出来ます。
なお、有効化も無効化も以下のコマンドです。

querylog は /var/named/data/named.run に記録されます。

#### query logging on

```r
[user01@cent8 ~]$ sudo rndc status |grep query
query logging is OFF
[user01@cent8 ~]$ sudo rndc querylog
[user01@cent8 ~]$ sudo rndc status |grep query
query logging is ON
[user01@cent8 ~]$
```

#### query logging off

```r
[user01@cent8 ~]$ sudo rndc status |grep query
query logging is ON
[user01@cent8 ~]$ sudo rndc querylog
[user01@cent8 ~]$ sudo rndc status |grep query
query logging is OFF
[user01@cent8 ~]$ 
```

### rootcache（named.ca） の更新

1. 現行のnamed.caをバックアップ
2. rootcacheを入手
3. 新しいrootcacheの読み込み

```r
[user01@cent8 ~]$ sudo cp /var/named/named.ca /var/named/named.ca.`date +%Y%m%d`
[user01@cent8 ~]$ sudo sh -c "dig +noall +answer +add +bufsize=4096 @a.root-servers.net . ns > /var/named/named.ca"
[user01@cent8 ~]$ sudo rndc reload
```