自宅のラズパイにbindを入れてローカルDNSサーバーを作る

# ラズパイのスペック
RaspberryPi3 modelB
メモリ:1GB
OS:Raspbian11(bullseye)

# 用語
聞き慣れない用語が多いので、ざっくり理解するためのメモ。
| 用語 | ざっくり内容 |
|:-|:-|
| DNS | IPアドレスとドメインの紐づけ(名前解決)をする。 |
| キャッシュDNSサーバー| IPとドメインの紐づけの問い合わせを行い、その結果をキャッシュするDNSサーバー。自宅PCやスマホでインターネット接続するときに問い合わせてるのはこれ。 |
| 権威DNSサーバー(コンテンツDNSサーバー) | IPとドメインの紐づけを、zoneという単位で管理するサーバー。 |
| リゾルバ | DNSに問い合わせをするやつ。クライアント側で動作する。 |
| スタブリゾルバ | DNSリクエストを送信するクライアント端末、もしくはDNSサーバー。 |
| フルサービスリゾルバ | 再帰問い合わせによって名前解決を行えるDNSサーバー。 |
| 再帰問い合わせ | リゾルバがDNSサーバーに問い合わせをすると結果が返ってくる。 |
| 反復問い合わせ | DNSサーバーが複数のDNSサーバーに問い合わせを繰り返して名前を解決してくれる。 |


# bindインストール
```console
# apt -y install bind9
```

## インストール確認
```console
# named -v
BIND 9.16.37-Raspbian (Extended Support Version)
```

# コンフィグファイルを編集していく

## コンフィグファイルの中身を確認
コンフィグファイルは、以下の3つのファイルをincludeしているだけでした。
これに全部書いてもいいんだろうけど、includeされている後述するファイルに分けて書いていくのが良さそう。
```console
# cat /etc/bind/named.conf
```
```conf:named.conf
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
```
## named.confのステートメント
named.confは、以下のステートメントで構成される。
| ステートメント | ファイル | 内容 |
|:-:|:-:|:-:|
| options | named.conf.options | bind共通の設定を書く。 |
| logging | - | ログ出力に関する内容を書く。 |
| zone | named.conf.default-zones | zone設定を書く。 |

# optionファイル編集
編集前にバックアップをとる。
```console
# cp -pi /etc/bind/named.conf.options /etc/bind/named.conf.options.org
```
編集する。
```conf:named.conf.options
// DNSサーバーの設定を書く

options {

    // zoneファイルを置くディレクトリを指定
    directory "/var/cache/bind";

    // bindのバージョン情報を表示させない設定
    version "unknown";

    // 問い合わせのみ許可設定(any:全許可)
    allow-query{ any; };

    // 再帰問い合わせ設定
    // recursion no;

    // フォワード設定(自己解決できない場合は転送する)
    forwarders { 192.168.0.1; };

    // forwarderからの回答がない場合はエラー
    forward only;

    // DNSECCの設定(デフォルトはauto、forward設定する場合はno)
    dnssec-validation no;

    // 再帰問い合わせ許可設定
    allow-recursion { 127.0.0.1; 192.168.0.0/24; };

    // IPv6に対応するかどうか
    listen-on-v6 { any; };
};
```

# zone設定ファイル編集
zone設定は、`named.conf.local`に書いていくことにする。
まずはバックアップをとる。
```console
# cp -pi /etc/bind/named.conf.local /etc/bind/named.conf.local.org
```
編集する。
```conf:named.conf.local
// zone設定を書く

// 正引きzone設定
zone "homenetwork" IN {
    type master;
    file "homenetwork.zone";
};

// 逆引きzone設定
zone "0.168.192.in-addr.arpa" IN {
    type master;
    file "homenetwork.rev";
};
```

## 正引きゾーンファイルを作る
```console
# vi /var/cache/bind/homenetwork.zone
```
```zone:homenetwork.zone
$TTL 3600 
@ IN SOA sv.homenetwork. root.homenetwork. (
  20230701 ; serial
  3H         ; refresh
  15M        ; retry
  1W         ; expire
  1H )       ; minimum

 IN NS sv
sv IN A 192.168.0.254
```

## 逆引きゾーンファイルを作る
```console
# vi /var/cache/bind/homenetwork.rev
```
```zone:homenetwork.rev
$TTL 3600 
@ IN SOA sv.homenetwork. root.homenetwork. (
  2015123105 ; serial
  3H         ; refresh
  15M        ; retry
  1W         ; expire
  1H )       ; minimum

 IN NS sv.homenetwork.
254 IN PTR sv.homenetwork.
```


# 設定チェック
## zone設定のチェック
```console
# named-checkzone 0.168.192.in-addr.arpa /etc/bind/homenetwork.rev
zone 0.168.192.in-addr.arpa/IN: loaded serial 2015123105
OK
# named-checkzone homenetwork /etc/bind/homenetwork.zone 
zone homenetwork/IN: loaded serial 2015123105
OK
```

## 構文チェック
```console
# named-checkconf 
```
何も表示されなければ問題なし。
構文ミスがあるとメッセージを表示してくれます。よくあるのは、セミコロンのつけ忘れ。
こんな感じでエラー箇所を示してくれます。
```
/etc/bind/named.conf.options:13: missing ';' before '}'
```

# bind再起動
設定反映のため再起動します。
```console
# systemctl restart bind9
```
正常に起動しているかどうか確認。
`Active: active`になっていれば正常に動いています。
```console
# systemctl status bind9
```
Failとか正常起動していない場合は、ログを見てエラーを特定しましょう。
`journalctl -u named`でログを確認できます。

# 動作確認
## digインストール
ラズパイには`dig`が入ってなかったのでインストールする。
```console
# apt -y install dnsutils
```

## ラズパイのDNSサーバーを自身に設定
バックアップを取ってからviで書き換えましょう。
```console
# cp -pi /etc/dhcpcd.conf /etc/dhcpcd.conf.org
# vi /etc/dhcpcd.conf
```
設定を書き換えます。
私の環境では、domain_name_serversだけ設定されてましたので、これだけ書き換え。
あとは追記しています。
```diff:/etc/dhcpcd.conf
- static domain_name_servers=192.168.0.1
+ static domain_name_servers=127.0.0.1
+ static domain_name=homenetwork
```
再起動させて反映。
```console
# systemctl resart dhcpcd
```

DNS設定を変更する。
```console
# cp -pi /etc/resolv.conf /etc/resolv.conf.org
```
```console
# vi /etc/resolv.conf
```
```diff:resolv.conf
- nameserver 192.168.0.1
+ nameserver 192.168.0.254
```


## FW設定している場合は許可させる

こちらを参考に許可設定

https://qiita.com/Nats72/items/013f6378933797110c06

digは53番ポートを使ってるみたいなので許可させる。
```console
# ufw allow 53
Rule added
Rule added (v6)
```
確認。
```console
# cat /etc/ufw/user.rules 
〜〜〜〜〜
### tuple ### allow any 53 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 53 -j ACCEPT
-A ufw-user-input -p udp --dport 53 -j ACCEPT
〜〜〜〜〜
```
設定反映＆確認。
`Active: active`になってれば正常。
```console
# systemctl restart ufw
# systemctl status ufw
```

# 正引き・逆引きテスト
DNSサーバのIPアドレスを指定してdig実行。
`ANSWER SECTION:`を見れば引けていることが分かる。

## 正引きテスト
```console
# dig @192.168.0.254 sv.homenetwork
〜〜〜
;; QUESTION SECTION:
;sv.homenetwork.                        IN      A

;; ANSWER SECTION:
sv.homenetwork.         3600    IN      A       192.168.0.254

;; Query time: 0 msec
;; SERVER: 192.168.0.254#53(192.168.0.254)
;; WHEN: Sat Jul 01 17:50:09 JST 2023
;; MSG SIZE  rcvd: 87
```

DNSサーバのIPアドレスを指定して外部ドメインへのdig実行。
こちらもOK。
```console
# dig @192.168.0.254 google.com
〜〜〜
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             185     IN      A       172.217.25.174

;; Query time: 9 msec
;; SERVER: 192.168.0.254#53(192.168.0.254)
;; WHEN: Sat Jul 01 17:52:28 JST 2023
;; MSG SIZE  rcvd: 83
```

DNSサーバー指定なしでdig実行。こちらも問題なし。
```console
# dig sv.homenetwork
〜〜〜
;; QUESTION SECTION:
;sv.homenetwork.                        IN      A

;; ANSWER SECTION:
sv.homenetwork.         3600    IN      A       192.168.0.254

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jul 01 18:01:58 JST 2023
;; MSG SIZE  rcvd: 87
```
## 逆引きテスト
こちらも回答あるのでOK。
逆引きは`-x`オプションをつけます。
```console
# dig -x 192.168.0.254
〜〜〜
;; QUESTION SECTION:
;254.0.168.192.in-addr.arpa.    IN      PTR

;; ANSWER SECTION:
254.0.168.192.in-addr.arpa. 3600 IN     PTR     sv.homenetwork.

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jul 01 18:09:01 JST 2023
;; MSG SIZE  rcvd: 111
```

# 自宅PCやサーバーに設定
あとは、自宅PCやサーバーのDNS設定を、bindを設定したサーバー向きにすれば名前解決ができるようになります。


# 参考にしたサイト
こちらを参考に色々調べながら記事作りました。

https://arw.hatenablog.jp/entry/2020/12/31/180339