BIND 9 を使ってDNSサーバーを建てる

# はじめに

今回はDNSサーバーについて詳しく知る必要があったので、実際に構築して調べてみました！
この方法では実際に運用することはあまりよろしくないと思いますので、実際に運用したい方は[CoreDNS](https://github.com/coredns/coredns)を使いましょう笑

# 0. アドレスの話
実際に構築する前に、今回建てるサーバーのアドレスを調査しておきましょう！

今回の構築における例として、以下のアドレスを利用します
```
example.com
111.211.121.112/20
```

# 1. 上位のDNS設定

実際のドメインから名前解決が飛んでくるように、宛先アドレスへの名前解決のためのAレコードと、それを利用したネームサーバー宛先のためのNSレコードを指定しておきましょう
一般的に、ネームサーバーのアドレスは、`ns1`や`ns2`などが使われることが多いです

```
ns1.example.com.   IN    A     111.211.121.112
example.com.       IN    NS    ns1.example.com.
```

これを指定することで、`example.com.`の次のサブドメインに対して名前解決が行われます。
レジストラの場合は、ネームサーバーの設定からも変更しておいてください

# 2. BIND ネームサーバーの構築

ここからネームサーバーの構築を始めていきます
以下、ルートユーザーでの操作で行われているとします。

## 2.1. 必要パッケージのインストール

`bind9`をインストールします。
便利ツールとして`bind9utils`もインストールします。

```sh
apt update
apt install bind9 bind9utils -y
```

インストールをチェックします
以下のコマンドで、デーモンが起動しているかコマンドが入っているかをチェックできます。

```sh
named -v
dpkg -l | grep bind9utils
systemctl status named
```

## 2.2. named.conf

`/etc/bind/named.conf` がBINDの設定ファイルなのでこれを編集します。
設定ごとにファイルを分けると分かりやすいので以下のように分けます。

`/etc/bind/named.conf.options` : BIND設定のオプションファイル、
`/etc/bind/named.conf.internal-zones` : 内部ネットワークのDNSゾーン設定
`/etc/bind/named.conf.external-zones` : 外部向けのドメインとその関連IPアドレスのDNSゾーン設定

このうち２つを作成し、includeします。

```sh
touch /etc/bind/named.conf.internal-zones /etc/bind/named.conf.external-zones
```

```sh:/etc/bind/named.conf
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.internal-zones";
include "/etc/bind/named.conf.external-zones";
```

## 2.3. named.conf.options

`named.conf.options` オプションの設定を変更します。

```sh:/etc/bind/named.conf.options
options {
    directory "/var/cache/bind";
    forwarders {
        8.8.8.8;  // Google Public DNS
        8.8.4.4;  // Google Public DNS
    };
    forward only;
    allow-query { any; };
    recursion yes;
    dnssec-validation auto;
    listen-on-v6 { none; };
    version "version: none";
};
```

## 2.4. named.conf.internal-zones

作成した`named.conf.internal-zones` を編集します。
内部向けはデフォルトをIncludeするだけです

```sh:/etc/bind/named.conf.internal-zones
include "/etc/bind/named.conf.default-zones";
```

## 2.5. named.conf.external-zones

作成した `named.conf.external-zones` を編集します。
外部向けはゾーンを設定します。

### 2.5.1. 逆引きアドレスの調査

逆引きとは、ドメイン名からアドレスを名前解決するための設定です。
逆引きの設定には、ファイル名や設定の規則を理解しておく必要があるため、以下のように理解してください。

`111.211.121.112/20`の場合の調査をします

1. [この](https://note.cman.jp/network/subnetmask.cgi) サイトで、IPアドレスとサブネットマスクを入力して結果を得ます
この場合、以下の情報が得られます
    ```
    IP: 111.211.121.112
    開始: 111.211.112.0
    終了: 111.211.127.255
    ```
2. 開始アドレスと終了アドレスを比較し、固定されているアドレスを確認します。この場合だと、`111.211` がどの場合においても変更されず固定されています
これは、`/20` が、`11111111.11111111.11110000.00000000` で、末尾２オクテットを利用してアドレスを割り当てるため、開始２オクテットは固定になるということです。

3. よって、`111.211`を逆順にしたアドレス、`211.111` が逆引きの固定アドレスになる

### 2.5.2. ゾーンファイルの設定

全章で逆引きアドレスが判明したら、以下のファイルを作成し、
正引き、逆引きゾーンを作成します。

逆引きでは、逆引きのアドレスに`in-addr.arpa` を付加したものが逆引きアドレスになります。
また、逆引きゾーン、レコードの設定では、アドレスは逆順を利用します。
そのため、ファイル名、追加するレコード等も、逆順で書くことに注意してください。

```sh
touch /etc/bind/example.com /etc/bind/211.111.db
```

```sh:/etc/bind/named.conf.external-zones
# 正引きゾーン
zone "example.com" {
    type master;
    file "/etc/bind/example.com";
    allow-update { none; };
};

# 逆引きゾーン
zone "211.111.in-addr.arpa" {
    type master;
    file "/etc/bind/211.111.db";
    allow-update { none; };
};
```

```:/etc/bind/example.com
$TTL 86400
@       IN      SOA     ns1.example.com. root.example.com. (
                        2023070301      ;Serial
                        3600            ;Refresh
                        1800            ;Retry
                        604800          ;Expire
                        86400           ;Minimum TTL
)
@       IN      NS      ns1.example.com.
@       IN      A       111.211.121.112
ns1     IN      A       111.211.121.112
bind    IN      A       111.211.121.112
```

```:/etc/bind/211.111.db
$TTL 86400
@       IN      SOA     ns1.example.com. root.example.com. (
                2023070301      ;Serial
                3600            ;Refresh
                1800            ;Retry
                604800          ;Expire
                86400           ;Minimum TTL
)

            IN      NS      ns1.example.com.
112.121     IN      PTR     ns1.example.com.
112.121     IN      PTR     bind.example.com.
```

## 2.6 文法チェック

以下のコマンドで文法的エラーをチェックできます。

```sh
named-checkconf
```

### 2.7. 再起動

namedを再起動して適用します。

```sh
systemctl restart bind9
```

## 3. 動作確認

DNSが動作しているかどうかを以下のコマンドでチェックできます

```sh
dig @178.128.127.185 dea.news
dig @178.128.127.185 bind.dea.news
dig @178.128.127.185 -x 178.128.127.185
dig @178.128.127.185 dea.news NS
```

## Reference

https://envader.plus/article/213