BINDによるDNSサーバ構築

# DNSサーバの構築
BINDは、オープンソースのネームサーバアプリケーションとして世界中で導入されている。
DNSは、ネットワーク情報を含むコンピュータリソースに関する情報を取得するために使用される階層的なネーミングシステムのこと。
一般にDNSサービスを提供するマシンをDNSサーバ、DNSによる名前解決の問い合わせを行うクライアントマシンをDNSクライアントと呼ぶ。


## BINDのインストール
DNSサーバとしてBINDをインストールする
```bash
dnf install -y bind bind-utils
```

## DNSの設定
OS：AlmaLinux9.4
DNSサーバのIP：192.168.0.200

DNSサーバに設定するパラメータは以下とする
項目|パラメータ|
|-|-|
ドメイン名|bjpn.linux.hpe.com
FQDN|n200.jpn.linux.hpe.com.
ゾーン|.jpn.linux.hpe.com.

## DNSの設定ファイル
DNSの設定ファイルは以下の通り
- /etc/named.conf  
⇒**BIND（named）DNSサーバのメイン設定ファイル**であり、ローカルネットワーク向けに正引き・逆引きDNSを提供するよう構成されている。
- /var/named/jpn.linux.hpe.com.forward  
⇒**BIND（DNSサーバ）用の正引きゾーンファイル**
- /var/named/jpn.linux.hpe.com.reverse  
⇒**BIND（DNSサーバ）用の逆引きゾーンファイル**


## /etc/named.confファイルの設定
今回は以下のように設定を行った。
```bash
//
// 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.
//

options {
        listen-on port 53 { 192.168.0.200; };
        #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     { localhost; 192.168.0.0/24; };
        allow-transfer  { localhost; 192.168.0.0/24; };


        /*
         - 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;

        dnssec-validation yes;

        managed-keys-directory "/var/named/dynamic";
        geoip-directory "/usr/share/GeoIP";

        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 "jpn.linux.hpe.com" IN {
        type master;
        file "jpn.linux.hpe.com.forward";
        allow-transfer { localhost; 192.168.0.0/24; };
};

zone "0.168.192.in-addr.arpa" IN {
        type master;
        file "jpn.linux.hpe.com.reverse";
        allow-transfer { localhost; 192.168.0.0/24; };
};
```

### セクション毎の説明

#### `options`セクション：基本動作の指定
```bash
options {
    listen-on port 53 { 192.168.0.200; };
    #listen-on-v6 port 53 { ::1; };
```
- BINDが **DNSクエリを受け付けるIPアドレスとポート** を指定する
- `192.168.0.200` のみで受け付け、他のNICでは受け付けない
- IPv6設定はコメントアウト

```bash
    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";
```
- 動作に必要なファイルの保存先を指定。  
  ゾーンデータや統計情報、キャッシュダンプの保存先

```bash
    secroots-file   "/var/named/data/named.secroots";
    recursing-file  "/var/named/data/named.recursing";
```
- DNSSECや再帰処理に関するデータファイル

```bash
    allow-query     { localhost; 192.168.0.0/24; };
```
- このDNSサーバに問い合わせを許可するクライアントの範囲（ローカルと同一セグメントのみ）

```bash
    allow-transfer  { localhost; 192.168.0.0/24; };
```
- ゾーン転送（セカンダリDNSへのデータ転送）を許可する範囲

```bash
    recursion yes;
```
- 再帰問い合わせを有効化し**キャッシュDNSサーバとして動作**させる

```bash
    dnssec-validation yes;
```
- DNSSEC（DNSの信頼性拡張）の検証を有効化

```bash
    managed-keys-directory "/var/named/dynamic";
    geoip-directory "/usr/share/GeoIP";
```
- DNSSEC鍵やGeoIP情報の保存場所

```bash
    pid-file "/run/named/named.pid";
    session-keyfile "/run/named/session.key";
```
- プロセスIDとセッションキーを保存するファイルパス

```bash
    include "/etc/crypto-policies/back-ends/bind.config";
```
- 暗号ポリシー（Fedora系のセキュリティ設定）

---

#### `logging`セクション：ログ出力の指定
```bash
logging {
    channel default_debug {
        file "data/named.run";
        severity dynamic;
    };
};
```
- ログファイル `data/named.run` に動的な詳細度でログ出力を行う

---

#### `zone "." IN`セクション：ルートゾーンのヒント
```bash
zone "." IN {
    type hint;
    file "named.ca";
};
```
- インターネット上のルートDNSサーバ情報を記述したファイル
- 外部問い合わせをするときの出発点

---

#### `include` ディレクティブ：設定ファイルの追加読み込み

```conf
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
```
- よく使われるローカル用ゾーンの定義ファイル（`localhost` や `127.in-addr.arpa` など）を読み込む
- `named.root.key` はDNSSECに使う鍵を定義

---

#### 正引きゾーン定義

```bash
zone "jpn.linux.hpe.com" IN {
    type master;
    file "jpn.linux.hpe.com.forward";
    allow-transfer { localhost; 192.168.0.0/24; };
};
```
- このDNSサーバが `jpn.linux.hpe.com` ドメインの**正引きマスターサーバ**であることを宣言
- ゾーンファイル：`/var/named/jpn.linux.hpe.com.forward`

---

#### 逆引きゾーン定義

```bash
zone "0.168.192.in-addr.arpa" IN {
    type master;
    file "jpn.linux.hpe.com.reverse";
    allow-transfer { localhost; 192.168.0.0/24; };
};
```
- `192.168.0.0/24` 範囲のIPアドレスに対応する**逆引きゾーン**
- ゾーンファイル：`/var/named/jpn.linux.hpe.com.reverse`


## 正引きゾーンファイルの設定（/var/named/jpn.linux.hpe.com.forward）
BIND（DNSサーバ）用の正引きゾーンファイルに以下のような記述を行った。
```bash
$TTL 86400
@       IN      SOA     ns01.jpn.linux.hpe.com. root.jpn.linux.hpe.com. (
                2024121101      ;Serial
                3600            ;Refresh
                1800            ;Retry
                604800          ;Expire
                86400           ;Minimum TTL
)
                IN      NS      n200.jpn.linux.hpe.com.
                IN      MX 10   n100.linux.hpe.com.
n200            IN      A       192.168.0.200
n100            IN      A       192.168.0.100
n182            IN      A       192.168.0.182
websvr          IN      CNAME   n182.jpn.linux.hpe.com.
```

### 各行の説明

#### TTL設定
```bash
$TTL 86400
```
- **TTL（Time To Live）**：DNS応答のキャッシュ有効時間を秒単位で指定。ここでは 86400 秒（= 1日）。

---

#### SOAレコード（ゾーンの基本情報）
```bash
@       IN      SOA     ns01.jpn.linux.hpe.com. root.jpn.linux.hpe.com. (
                2024121101      ;Serial
                3600            ;Refresh
                1800            ;Retry
                604800          ;Expire
                86400           ;Minimum TTL
)
```

- **SOA（Start of Authority）レコード**：このゾーンの権威情報を定義
  - `@`：このゾーンファイルで定義するドメイン名（`jpn.linux.hpe.com.`）の省略表記
  - `IN`：Internet クラス
  - `SOA`：このゾーンの管理情報
  - `ns01.jpn.linux.hpe.com.`：プライマリDNSサーバ名
  - `root.jpn.linux.hpe.com.`：管理者のメールアドレス（メールアドレスは `@` を `.` に変換した形）
  - `2024121101`：シリアル番号（ゾーン情報の更新を伝える番号。通常は日付+連番）
  - `3600`：セカンダリDNSがSOAをチェックする間隔（秒）
  - `1800`：セカンダリDNSが再試行するまでの時間（秒）
  - `604800`：ゾーン情報の有効期限（秒）
  - `86400`：最小TTL（キャッシュの有効時間）

---

#### ネームサーバの指定
```dns
        IN      NS      n200.jpn.linux.hpe.com.
```
- **NSレコード**：このゾーンのネームサーバは `n200.jpn.linux.hpe.com.`

---

#### メールサーバの指定
```dns
        IN      MX 10   n100.linux.hpe.com.
```
- **MXレコード**：メールの配送先サーバを指定。優先度10で `n100.linux.hpe.com.` がメールサーバ

---

#### 各ホストのAレコード（名前→IPアドレス）
```dns
n200            IN      A       192.168.0.200
n100            IN      A       192.168.0.100
n182            IN      A       192.168.0.182
```
- それぞれのホスト名に対してIPアドレスを割り当てています

---

#### CNAME（別名）レコード
```dns
websvr          IN      CNAME   n182.jpn.linux.hpe.com.
```
- `websvr.jpn.linux.hpe.com.` は `n182.jpn.linux.hpe.com.` の別名として機能する
 **注意**：`CNAME`の右辺はFQDN（ピリオドで終わる完全なドメイン名）である必要がある

---






## 逆引きゾーンファイルの設定（/var/named/jpn.linux.hpe.com.reverse）
BIND（DNSサーバ）用の逆引きゾーンファイルに以下のような記述を行った。
```bash
$TTL 86400
@       IN      SOA     ns01.jpn.linux.hpe.com. root.jpn.linux.hpe.com. (
                2024121101      ;Serial
                3600            ;Refresh
                1800            ;Retry
                604800          ;Expire
                86400           ;Minimum TTL
)
                IN      NS      ns01.jpn.linux.hpe.com.
200             IN      PTR     n200.jpn.linux.hpe.com.
100             IN      PTR     n100.jpn.linux.hpe.com.
182             IN      PTR     n182.jpn.linux.hpe.com.
```

#### 各行の説明
#### TTL設定
```bash
$TTL 86400
```
- 各レコードのデフォルトのキャッシュ有効時間を 86400 秒（=1日）に設定

--- 

### SOAレコード（ゾーンの基本情報）
```dns
@       IN      SOA     ns01.jpn.linux.hpe.com. root.jpn.linux.hpe.com. (
                2024121101      ;Serial
                3600            ;Refresh
                1800            ;Retry
                604800          ;Expire
                86400           ;Minimum TTL
)
```
- `@`：このファイルのゾーン名を表します（例：`0.168.192.in-addr.arpa.` などが想定される）
- `IN SOA`：この逆引きゾーンの管理情報
- `ns01.jpn.linux.hpe.com.`：ゾーンのプライマリDNSサーバ
- `root.jpn.linux.hpe.com.`：DNS管理者のメールアドレス（`@`を`.`に置換した形式）
- 各値はゾーン情報の更新タイミングを制御


---

#### ネームサーバの定義
```dns
        IN      NS      ns01.jpn.linux.hpe.com.
```
- このゾーンの権威ネームサーバは `ns01.jpn.linux.hpe.com.`

---

#### PTRレコード（IPアドレス → ホスト名）
```dns
200             IN      PTR     n200.jpn.linux.hpe.com.
100             IN      PTR     n100.jpn.linux.hpe.com.
182             IN      PTR     n182.jpn.linux.hpe.com.
```
-  **逆引きレコード**で、IPアドレスの下位オクテットに対するホスト名を定義
- 例えば、ゾーンが `0.168.192.in-addr.arpa.` だとすると：
  - `200 IN PTR ...` → `192.168.0.200` の逆引きで `n200.jpn.linux.hpe.com.` が返される
  - `100 IN PTR ...` → `192.168.0.100` の逆引き
  - `182 IN PTR ...` → `192.168.0.182` の逆引き

## DNSサーバのサービス関連設定
```bash
# DNSサーバ自身の名前解決先をNICに設定する
# NICはeth0とする
nmcli c m eth0 ipv4.dns 192.168.0.200
nmcli c m eth0 ipv4.dns-search jpn.linux.hpe.com
nmcli c down eth0
nmcli c up eth0
reboot
```

```bash
# 設定ファイル/etc/resolv.confにドメイン名とDNSサーバのIPアドレスが記述されているか確認
grep -E "search|nameserver" /etc/resolv.conf

# ファイアウォールの許可
firewall-cmd --zone=public --add-service=dns
firewall-cmd --runtime-to-permanent

# DNSサーバの設定ファイル内容を確認する
named-checkconf -z

# 作成したDNSの設定ファイルが存在するかを確認する
ls -1aF /var/named/

# DNSサービスの起動
systemctl enable --now named
systemctl is-active named
```


## DNSクライアントの設定
```bash
# 名前解決先を構築したDNSサーバに設定する
# NICはeth0とする
nmcli c m eth0 ipv4.dns 192.168.0.200,8.8.8.8
nmcli c m eth0 ipv4.dns-search jpn.linux.hpe.com
nmcli c down eth0
nmcli c up eth0
reboot
grep -E "search|nameserver" /etc/resolv.conf
```

## DNSサーバによる名前解決の確認
```bash
# 以下コマンドをDNSクライアントから実行
host n200; host n100;  host n182;
```
```bash
# 出力結果
n200.jpn.linux.hpe.com has address 192.168.0.200
n100.jpn.linux.hpe.com has address 192.168.0.100
n182.jpn.linux.hpe.com has address 192.168.0.182
```