FreeBSD 12で自宅サーバの構築　DNS編

## はじめに
FreeBSD 12を使用した自宅サーバの構築を行った。FreeBSD 12はリリースされて間もない状態ですが、カーネルに標準でVIMAGEが取り込まれDNSの外向きと、内向きを別々のシステム（jail+VIMAGE）が同一ホストで構築できることから採用することにしました。その時の構築手順を備忘録の意味も含め、具体的にいくつかに渡り説明する。

* [基本システム編その１](https://qiita.com/Chun3/items/2f891e5993c91b58ae5c)
	- 背景
	- 基本のインストール
	- 日本語環境の設定
* [基本システム編その２](https://qiita.com/Chun3/items/1e8fe5071c4a78d37e66)
	- セキュリティ
	- ftpサーバ
* [基本システム編その３](https://qiita.com/Chun3/items/e5cc6a69542153649dc0)
	- jail
	- 基本システム編おわり
* [jail内基本システム編](https://qiita.com/Chun3/items/4b11b9acdd080ecdab6c)
	- 基本の設定（jail1・jail2共通）
	- 基本の設定（jail1・jail2共通）
* [DNS編](https://qiita.com/Chun3/items/95ad3113202d111ee53c)（この記事）
 	- DNSの構築におけるこれまでの問題
 	- bind9インストール
 	- NTPサーバ
* [Let's Encrypt編](https://qiita.com/Chun3/items/4814c25c09756690133f)
 	- Let's Encryptについて
 	- certbotのインストール
 	- 各種設定
 	- 証明書の取得
* [Webサーバ編](https://qiita.com/Chun3/items/286e567952cd9faf279f)
 	- インストール（apache2.4・webalizer・php7.3・postgresql11.2・mysql8.0）
 	- 設定
* [メールサーバ編](https://qiita.com/Chun3/items/dc0e176c9de4f6b4bfb8)
 	- インストール（cyrus-sasl・postfix・dovecot・procmail・pflogsumm・policyd-spf）
 	- 設定・起動
 	- spfレコード送信設定
* [ファイルサーバ編](https://qiita.com/Chun3/items/356b7fadd7aa5280ec65)
 	- sambaの選択
 	- samba3のインストール
* [メールサーバ編その2](https://qiita.com/Chun3/items/4c15ee889b052df67bbd)
 	- 概要
 	- OpenDKIM
 	- OpenDMARC
 	- ClamAV (clamav-milter)
 	- Spamassasin (spamass-milter)

## DNSの構築におけるこれまでの問題
DNSは、今回のサーバー再構築のトリガーになった機能である。従来からbind9を使用し今回も使用するが、従来は以下のような設定を行っていた。

```/usr/local/etc/namedb/named.conf
include "/usr/local/etc/namedb/rndc.key";
controls {
        inet 127.0.0.1 port 953 allow {127.0.0.1;} keys {"rndc-key";};
};

acl localnet {
        192.168.1.0/24;
        127.0.0.1;
};

options {
        directory       "/usr/local/etc/namedb";
        pid-file        "/var/run/named/pid";
        dump-file       "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";
        listen-on-v6    { none; };
        allow-transfer  { localhost; localnet; };
};

// lan側の設定
view "internal" {
        match-clients { localnet; };
        recursion yes;
        // ルートのゾーンファイル
        zone "." {
                type hint;
                file "/usr/local/etc/namedb/named.root";
        };
        // localhost正引き
        zone "localhost" {
                type master;
                file "/usr/local/etc/namedb/master/localhost.zone";
        };
        // localhost逆引き
        zone "0.0.127.in-addr.arpa" {
                type master;
                file "/usr/local/etc/namedb/master/0.0.127.rev";
        };
        // 自ドメイン正引き
        zone "example.jp" {
                type master;
                file "/usr/local/etc/namedb/master/example.jp.local.zone";
        };
        // 自ドメイン逆引き
        zone "1.168.192.in-addr.arpa" {
                type master;
                file "/usr/local/etc/namedb/master/1.168.192.rev";
        };
};

// wan側の設定
view "external" {
        match-clients {any;};
        recursion no;
        // 自ドメイン正引き
        zone "example.jp" {
                type master;
                file "/usr/local/etc/namedb/master/example.jp.zone";
        };
};
```

この設定で外部へのドメイン情報の提供と、内部へのドメイ情報の提供を同居して運用ですることができた。
問題が発生したのは、固定IPアドレスを2個取得し、セカンダリDNSを運用したときである。
セカンダリとマスタはローカルネットで接続されている（ルータの関係で外部アドレスでの接続ができない）状態で、ゾーンファイル情報をマスタからセカンダリに提供した時である。
セカンダリでは、外部向けexample.jpと内部向けexample.jpのゾーンファイル情報がどちらも内部向けになってしまった。
予想では、ローカルネットで接続されているためセカンダリからマスタに要求したときは内部向けも、外部向けも要求元（セカンダリ）が内部から接続しているため、内部ゾーンファイル情報が送られたためと思われる。
解決策が見つからなかったので、手動でドメイン情報をコピーして運用していた。
次に発生した問題はlet's encryptの認証にDNSを使用したときである。同様の理由で外部向けのTXTレコードを設定できなかった。
これもゾーンファイルをリンクするなどして回避できたが、最終的な解決策は、外部向けと内部向けのDNSを分けることと考え、今回のサーバ再構築となった。

## bind9インストール
###jail1・jail2共通
前置きが長くなったがbind9をインストールする。
ネットワークの前提条件を以下に示す。（IPアドレスは有り得ない値に設定しています）なお、静的NAT設定はルータのwan-IPアドレスに届いたパケットをlan-IPアドレスに割り当てることとする。

| 項目 | 内容 | 静的NAT設定 wan → lan|
|:-:|:-:|:-:|
|ドメイン名|example.jp| |
|lan側のネットワークアドレス|192.168.1.0/24| |
|IPアドレス１|111.222.333.100| 192.168.1.41 |
|IPアドレス２|111.222.333.200| 192.168.1.43 |

```
jail1 /root # pkg install bind913
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Updating database digests format: 100%
The following 11 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        bind913: 9.13.6_3
        libxml2: 2.9.8
        python27: 2.7.15
        readline: 7.0.5
        gettext-runtime: 0.19.8.1_2
        libidn2: 2.1.1
        libunistring: 0.9.10_1
        py27-ply: 3.11
        py27-setuptools: 40.8.0
        json-c: 0.13.1
        lmdb: 0.9.23,1

Number of packages to be installed: 11

The process will require 137 MiB more space.
20 MiB to be downloaded.
[jail1] [1/11] Fetching bind913-9.13.6_3.txz: 100%    7 MiB 188.6kB/s    00:38
[jail1] [2/11] Fetching libxml2-2.9.8.txz: 100%  818 KiB 167.6kB/s    00:05
[jail1] [3/11] Fetching python27-2.7.15.txz: 100%   11 MiB 201.1kB/s    00:55
[jail1] [4/11] Fetching readline-7.0.5.txz: 100%  332 KiB 170.2kB/s    00:02
[jail1] [5/11] Fetching gettext-runtime-0.19.8.1_2.txz: 100%  149 KiB 153.0kB/s    00:01
[jail1] [6/11] Fetching libidn2-2.1.1.txz: 100%  104 KiB 106.9kB/s    00:01
[jail1] [7/11] Fetching libunistring-0.9.10_1.txz: 100%  522 KiB 133.6kB/s    00:04
[jail1] [8/11] Fetching py27-ply-3.11.txz: 100%  127 KiB 129.8kB/s    00:01
[jail1] [9/11] Fetching py27-setuptools-40.8.0.txz: 100%  476 KiB 243.5kB/s    00:02
[jail1] [10/11] Fetching json-c-0.13.1.txz: 100%   56 KiB  57.4kB/s    00:01
[jail1] [11/11] Fetching lmdb-0.9.23,1.txz: 100%   94 KiB  95.9kB/s    00:01
Checking integrity... done (0 conflicting)
[jail1] [1/11] Installing readline-7.0.5...
[jail1] [1/11] Extracting readline-7.0.5: 100%
[jail1] [2/11] Installing gettext-runtime-0.19.8.1_2...
[jail1] [2/11] Extracting gettext-runtime-0.19.8.1_2: 100%
[jail1] [3/11] Installing python27-2.7.15...
[jail1] [3/11] Extracting python27-2.7.15: 100%
[jail1] [4/11] Installing libunistring-0.9.10_1...
[jail1] [4/11] Extracting libunistring-0.9.10_1: 100%
[jail1] [5/11] Installing py27-setuptools-40.8.0...
[jail1] [5/11] Extracting py27-setuptools-40.8.0: 100%
[jail1] [6/11] Installing libxml2-2.9.8...
[jail1] [6/11] Extracting libxml2-2.9.8: 100%
[jail1] [7/11] Installing libidn2-2.1.1...
[jail1] [7/11] Extracting libidn2-2.1.1: 100%
[jail1] [8/11] Installing py27-ply-3.11...
[jail1] [8/11] Extracting py27-ply-3.11: 100%
[jail1] [9/11] Installing json-c-0.13.1...
[jail1] [9/11] Extracting json-c-0.13.1: 100%
[jail1] [10/11] Installing lmdb-0.9.23,1...
[jail1] [10/11] Extracting lmdb-0.9.23,1: 100%
[jail1] [11/11] Installing bind913-9.13.6_3...
[jail1] [11/11] Extracting bind913-9.13.6_3: 100%
Message from python27-2.7.15:

===========================================================================

Note that some standard Python modules are provided as separate ports
as they require additional dependencies. They are available as:

bsddb           databases/py-bsddb
gdbm            databases/py-gdbm
sqlite3         databases/py-sqlite3
tkinter         x11-toolkits/py-tkinter

===========================================================================
Message from bind913-9.13.6_3:

**********************************************************************
*            _  _____ _____ _____ _   _ _____ ___ ___  _   _         *
*           / \|_   _|_   _| ____| \ | |_   _|_ _/ _ \| \ | |        *
*          / _ \ | |   | | |  _| |  \| | | |  | | | | |  \| |        *
*         / ___ \| |   | | | |___| |\  | | |  | | |_| | |\  |        *
*        /_/   \_\_|   |_| |_____|_| \_| |_| |___\___/|_| \_|        *
*                                                                    *
*   BIND requires configuration of rndc, including a "secret" key.   *
*    The easiest, and most secure way to configure rndc is to run    *
*   'rndc-confgen -a' to generate the proper conf file, with a new   *
*            random key, and appropriate file permissions.           *
*                                                                    *
*     The /usr/local/etc/rc.d/named script will do that for you.     *
*                                                                    *
*      If using syslog to log the BIND9 activity, and using a        *
*     chroot'ed installation, you will need to tell syslog to        *
*       install a log socket in the BIND9 chroot by running:         *
*                                                                    *
*            # sysrc altlog_proglist+=named                          *
*                                                                    *
*    And then restarting syslogd with: service syslogd restart       *
*                                                                    *
*                                                                    *
*   THIS IS A DEVELOPMENT VERSION OF BIND, IT MAY EAT YOUR DATA      *
*                                                                    *
*                                                                    *
*                                                                    *
**********************************************************************
```

最初に使用宣言

```sh:/etc/rc.conf
named_enable="YES"
```

rndcの設定

```
jail1 /root # cd /usr/local/etc/namedb
jail1 /usr/local/etc/namedb # rndc-confgen >rndc.conf
jail1 /usr/local/etc/namedb # cp rndc.conf rndc_key
```

rndc.confの前半のみに編集する。（後半はコメントになっているので特に編集はしなくてもよい。）

```/usr/local/etc/namedb/rndc.conf
key "rndc-key" {
        algorithm hmac-sha256;
        secret "+RRgAOIR71bNy6wZ9YabcdefgihjzOepeEjzwiiZNyI=";
};

options {
        default-key "rndc-key";
        default-server 127.0.0.1;
        default-port 953;
};
```

rndc_keyは後半のkey部分のみを取り出してnamed.confにincludeできるようにする。

```sh:/usr/local/etc/namedb/rndc_key
key "rndc-key" {
        algorithm hmac-sha256;
        secret "+RRgAOIR71bNy6wZ9YabcdefgihjzOepeEjzwiiZNyI=";
};
```

設定は、これまでの設定を分けるだけである。
### jail1（外向き）の設定

```/usr/local/etc/namedb/named.conf
include "/usr/local/etc/namedb/rndc_key";
controls {
        inet 127.0.0.1 port 953 allow {127.0.0.1;} keys {"rndc-key";};
};

options {
        directory       "/usr/local/etc/namedb/working";
        pid-file        "/var/run/named/pid";
        dump-file       "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";
        listen-on-v6    { none; };
        allow-transfer  { 192.168.1.0/24; };
};

// wan側の設定
// 自ドメイン正引き
zone "example.jp" {
        type master;
        file "/usr/local/etc/namedb/master/example.jp.zone";
};
```

ゾーンファイル

```/usr/local/etc/namedb/master/example.jp.zone
$TTL    3600

@       IN      SOA     ns1.example.jp.    root.example.jp.  (
                        20190020101      ; Serial
                        3600            ; Refresh
                        900             ; Retry
                        3600000         ; Expire
                        3600            ; Minimum
                                )
                        IN      NS      ns1.example.jp.
                        IN      NS      ns2.example.jp.
                        IN      MX  10  mail.example.jp.
                        IN      A       111.222.333.100
ns1                     IN      A       111.222.333.100
ns2                     IN      A       111.222.333.200
mail                    IN      A       111.222.333.100
www                     IN      CNAME   ns1.example.jp.
www2                    IN      CNAME   ns2.example.jp.
ftp                     IN      CNAME   ns1.example.jp.
```

リゾルバの設定は、内部DNSサーバに設定する

```/etc/resolv.conf
search example.jp
nameserver 192.168.1.42
```

開始する。

```
jail1 /root # service named start
Starting named.
```

### jail2（内向き）の設定

```/usr/local/etc/namedb/named.conf
include "/usr/local/etc/namedb/rndc_key";
controls {
        inet 127.0.0.1 port 953 allow {127.0.0.1;} keys {"rndc-key";};
};

options {
        directory       "/usr/local/etc/namedb/working";
        pid-file        "/var/run/named/pid";
        dump-file       "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";
        listen-on-v6    { none; };
        allow-transfer  { 192.168.1.0/24; };
        forwarders      { 192.168.1.41; };
        forward         only;
};

// lan側の設定
// localhost正引き
zone "localhost" {
        type            master;
        file            "/usr/local/etc/namedb/master/localhost.zone";
        forwarders      {};
};
// localhost逆引き
zone "0.0.127.in-addr.arpa" {
        type            master;
        file            "/usr/local/etc/namedb/master/0.0.127.rev";
        forwarders      {};
};
// 自ドメイン正引き
zone "example.jp" {
        type            master;
        file            "/usr/local/etc/namedb/master/example.jp.local.zone";
        forwarders      {};
};
// 自ドメイン逆引き
zone "1.168.192.in-addr.arpa" {
        type            master;
        file            "/usr/local/etc/namedb/master/1.168.192.rev";
        forwarders      {};
};
```

ゾーンファイル

```/usr/local/etc/namedb/master/localhost.zone
$TTL    3600

@       IN      SOA     ns1.example.jp.    root.localhost.  (
                        2019020101   ; Serial
                        3600         ; Refresh
                        900          ; Retry
                        3600000      ; Expire
                        3600 )       ; Minimum
        IN      NS      localhost.
        IN      A       127.0.0.1
```

```/usr/local/etc/namedb/master/0.0.127.rev
$TTL    3600

@       IN      SOA     ns1.example.jp.    root.example.jp.  (
                        2019020101   ; Serial
                        3600         ; Refresh
                        900          ; Retry
                        3600000      ; Expire
                        3600 )       ; Minimum
        IN      NS      localhost.
1       IN      PTR     localhost.
```

```/usr/local/etc/namedb/master/example.jp.local.zone
$TTL    3600

@               IN      SOA     ns1.example.jp.    root.example.jp.  (
                        2019020101      ; Serial
                        3600            ; Refresh
                        900             ; Retry
                        3600000         ; Expire
                        3600 )          ; Minimum
                IN      NS      ns1.example.jp.
                IN      NS      ns2.example.jp.
                IN      MX      10      mail.example.jp.
                IN      A       192.168.1.41
router          IN      A       192.168.1.1
ns1             IN      A       192.168.1.41
ns2             IN      A       192.168.1.43
mail            IN      A       192.168.1.41
server1         IN      A       192.168.1.32
server2         IN      A       192.168.1.33
jail1           IN      A       192.168.1.41
jail2           IN      A       192.168.1.42
jail3           IN      A       192.168.1.43
jail4           IN      A       192.168.1.44
www             IN      CNAME   jail1.example.jp.
www2            IN      CNAME   jail3.example.jp.
hoge1           IN      A       192.168.1.101
hoge2           IN      A       192.168.1.102
```

```/usr/local/etc/namedb/master/1.168.192.rev
$TTL    3600

@       IN      SOA     ns1.example.jp.    root.example.jp.  (
                        2019020101      ; Serial
                        3600            ; Refresh
                        900             ; Retry
                        3600000         ; Expire
                        3600 )          ; Minimum
        IN      NS      ns1.example.jp.
1       IN      PTR     router.example.jp.
32      IN      PTR     server1.example.jp.
33      IN      PTR     server2.example.jp.
41      IN      PTR     jail1.example.jp.
42      IN      PTR     jail2.example.jp.
43      IN      PTR     jail3.example.jp.
44      IN      PTR     jail4.example.jp.
101     IN      PTR     hoge1.example.jp.
102     IN      PTR     hoge2.example.jp.
```

リゾルバの設定は、内部DNSサーバに設定する

```/etc/resolv.conf
search example.jp
nameserver 192.168.1.42
```

開始する。

```
jail1 /root # service named start
Starting named.
```

## NTPサーバ
時計がズレていることに気が付きログを調べると、以下のようなログが吐かれていた。

``` /var/log/ntpd.log
 5 Apr 20:03:49 ntpd[93514]: 0.0.0.0 c618 08 no_sys_peer
 5 Apr 20:03:57 ntpd[93514]: Soliciting pool server 2001:4860:4806::
 5 Apr 20:04:15 ntpd[93514]: Soliciting pool server 2001:df0:232:eea0::fff4
 5 Apr 20:04:19 ntpd[93514]: Soliciting pool server 210.173.160.57
 5 Apr 20:05:03 ntpd[93514]: Soliciting pool server 2001:4860:4806:4::
 5 Apr 20:05:19 ntpd[93514]: Soliciting pool server 2001:df0:232:eea0::fff3
 5 Apr 20:05:26 ntpd[93514]: Soliciting pool server 210.173.160.27
 5 Apr 20:06:09 ntpd[93514]: Soliciting pool server 2001:4860:4806:4::
 5 Apr 20:06:25 ntpd[93514]: Soliciting pool server 2001:df0:232:eea0::fff3
 5 Apr 20:06:32 ntpd[93514]: Soliciting pool server 210.173.160.87
 5 Apr 20:07:15 ntpd[93514]: Soliciting pool server 2001:4860:4806:c::
 5 Apr 20:07:32 ntpd[93514]: Soliciting pool server 2001:df0:232:eea0::fff4
 5 Apr 20:07:36 ntpd[93514]: Soliciting pool server 210.173.160.57
 5 Apr 20:07:40 ntpd[93514]: 0.0.0.0 c613 03 spike_detect +8.816487 s
 5 Apr 20:13:16 ntpd[93514]: 0.0.0.0 c61c 0c clock_step +8.821064 s
 5 Apr 20:13:16 ntpd[93514]: step-systime: Operation not permitted
 5 Apr 20:13:16 ntpd[93514]: 0.0.0.0 c615 05 clock_sync
 5 Apr 20:13:16 ntpd[93514]: local_clock: usr/src/contrib/ntp/ntpd/ntp_loopfilter.c line 818: ntp_adjtime: Operation not permitted
```

ntpサーバと接続しntpqでは正常に同期しているようだったが、実はjail内ではシステム時計を修正する権限がない様です。dateコマンドで修正もエラーが表示される。
そこで、ntpdはホスト側で実行することとし、ルータの設定も123ポートの振替先をホスト側のIPアドレスに変更し、外部の時計に同期するマスターサーバとそのマスターサーバと同期をかけるスレーブサーバに考え方を変え、jail内のntpd起動は行わないこととする（/etc/rc.confに設定されていてもOS起動時には自動起動がかからないようです）(2019/8/5)。

最初に使用宣言

```sh:/etc/rc.conf
ntpd_enable="YES"
```

設定ファイルの編集
時計を合わせるサーバの指定

```
pool ntp.nict.jp
```

以下のように個別指定と同様である

```
server ntp-a2.nict.go.jp
server ntp-a3.nict.go.jp
server ntp-b2.nict.go.jp
server ntp-b3.nict.go.jp
```

加えて、ホスト名の後にオプションを指定できiburstを指定すると起動直後はバースト上にパケットを送出し時刻同期を早める事ができる。

### マスターサーバの設定
ローカルネットワークからの問い合わせに応答するよう以下の設定とする。

```sh:/etc/ntp.conf
pool            ntp.nict.jp iburst
pool            ntp.jst.mfeed.ad.jp iburst
pool            time.google.com iburst

logfile         /var/log/ntpd.log
logconfig       =syncstatus +sysevents +clockall

restrict        default noquery nomodify notrap
restrict        192.168.1.0 mask 255.255.255.0 nomodify notrap
restrict        127.0.0.1
```

起動する。

```
# service ntpd start
Starting ntpd.
```

同期の状況確認以下でできる。ntp.jst.nfeed.ad.jpが見えなくなった？

```
# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 ntp.nict.jp     .POOL.          16 p    -   64    0    0.000    0.000   0.000
 ntp.jst.mfeed.a .POOL.          16 p    -   64    0    0.000    0.000   0.000
 time.google.com .POOL.          16 p    -   64    0    0.000    0.000   0.000
*ntp-a2.nict.go. .NICT.           1 u  241 1024  377   16.236    0.954   0.667
+ntp-a3.nict.go. .NICT.           1 u  255 1024  377   15.284    0.703   1.166
+ntp-b2.nict.go. .NICT.           1 u  468 1024  377   17.810    1.577   1.211
+ntp-b3.nict.go. .NICT.           1 u  201 1024  377   16.306    0.470   1.152
+time1.google.co .GOOG.           1 u  238 1024  377   49.762   -0.123   0.928
+time2.google.co .GOOG.           1 u 1044 1024  377   82.096    0.910   0.574
+time4.google.co .GOOG.           1 u  204 1024  377  142.249   -0.551   1.466
```

### スレーブサーバの設定
ローカルネットワークからの問い合わせに応答するよう以下の設定とする。

```sh:/etc/ntp.conf
server          master.example.jp iburst
logfile         /var/log/ntpd.log
logconfig       =syncstatus +sysevents +clockall

restrict        default noquery nomodify nopeer notrap
restrict        192.168.1.0 mask 255.255.255.0 nomodify nopeer notrap
restrict        127.0.0.1
```

起動する。


```
# service ntpd start
Starting ntpd.
```