RaspberryPiにUnboundを入れてDNSキャッシュにする

何番煎じか分かりませんが、自分用の備忘録として残しておきます…

# Unboundとは

> UnboundはDNSリゾルバ、キャッシュ、DNSSEC検証機能を持つDNSキャッシュサーバーです。

[(出典)日本Unboundユーザ会](https://unbound.jp/unbound/)



# 環境

* Raspberry Pi 3B
* FedoraServer 32 ARM

```bash
$ uname -a
Linux localhost.localdomain 5.6.15-300.fc32.aarch64 #1 SMP Thu May 28 15:37:06 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
```

# Unboundのインストール

デフォルトで入っているリポジトリにあるため、yumでインストールできる。

```bash
$ sudo yum install -y unbound
```


# Unboundの設定

## ファイアウォールの設定

DNSで使用するポートをあけておく

```bash
$ sudo firewall-cmd --get-active-zones 
FedoraServer
  interfaces: eth0

$ sudo firewall-cmd --add-service=dns --zone=FedoraServer --permanent
success

$ sudo firewall-cmd --reload
success

$ sudo firewall-cmd --list-all
FedoraServer (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: cockpit dhcpv6-client dns mdns ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
```

services に dns が追加された。これは 53 tcp, 53 udp を表す。


## ネットワーク情報の取得

あらかじめ、設置予定ネットワークの情報を取得しておく。

* 上位DNSサーバのアドレス（IPv4/IPv6 両方。ブロードバンドルータやISP、オープンリゾルバのもの）
* ネットワークアドレス、CIDR（IPv4/IPv6 両方）


## /etc/unbound/unbound.conf

メインの設定ファイル。
とりあえず、最低限の設定を放り込む。

```conf:unbound.conf
# https://unbound.jp/unbound/unbound-conf/

server:
    verbosity: 0  # エラー以外のログをとらない
    username: "unbound"
    chroot: ""
    directory: "/etc/unbound"
    pidfile: "/var/run/unbound/unbound.pid"
    
    port: 53
    so-reuseport: yes
    ip-transparent: yes
    max-udp-size: 3072

    do-ip4: yes
    do-ip6: yes

    # ★待ち受けするインタフェイス
    interface: ::1          #IPv6
    interface: ::0          #IPv6
    interface: 127.0.0.1    #IPv4
    interface: 0.0.0.0      #IPv4

    # ★アクセス制限
    access-control: 0.0.0.0/0 refuse  # 基本は全拒否
    access-control: ::0/0 refuse      # 基本は全拒否
    access-control: 127.0.0.0/8 allow # ループバックアドレス許可
    access-control: ::1 allow         # ループバックアドレス許可

    access-control: 192.0.2.0/24 allow      # アクセスを許可するネットワーク（IPv4）
    access-control: 198.51.100.0/24 allow   # アクセスを許可するネットワーク（IPv4）
    access-control: 2001:0db8::::/32 allow  # アクセスを許可するネットワーク（IPv6）

    # ★個別設定ファイルパスの指定
    include: /etc/unbound/local.d/*.conf


# ★フォワード（上位DNSサーバ）の設定
forward-zone:
    name: "."
    forward-addr: 2001:0db8:0000:0000:0000:0000:0000:008f   # IPv6 DNS 1
    forward-addr: 2001:0db8:0000:0000:0000:0000:0000:00fe   # IPv6 DNS 2
    forward-addr: 192.0.2.254         # IPv4 DNS 1
    forward-addr: 198.51.100.0        # IPv4 DNS 2
```

不足などありましたらご教示ください :pray: 

書き込んだら書式チェックをしておく


```bash
$ sudo unbound-checkconf /etc/unbound/unbound.conf
unbound-checkconf: no errors in /etc/unbound/unbound.conf
```


## サービス起動

```bash
$ sudo systemctl enable unbound
$ sudo systemctl start unbound
$ $ sudo systemctl status unbound
● unbound.service - Unbound recursive Domain Name Server
     Loaded: loaded (/usr/lib/systemd/system/unbound.service; enabled; vendor preset: disabled)
     Active: active (running) since Thu 2020-06-04 15:51:00 JST; 2h 28min ago
   Main PID: 4731 (unbound)
      Tasks: 4 (limit: 1004)
     Memory: 25.5M
        CPU: 5.389s
     CGroup: /system.slice/unbound.service
             └─4731 /usr/sbin/unbound -d

Jun 04 15:50:29 localhost.localdomain systemd[1]: Starting Unbound recursive Domain Name Server...
Jun 04 15:50:29 localhost.localdomain unbound-checkconf[4560]: unbound-checkconf: no errors in /etc/unbound/unbound.conf
Jun 04 15:51:00 localhost.localdomain systemd[1]: Started Unbound recursive Domain Name Server.
Jun 04 15:51:01 localhost.localdomain unbound[4731]: [4731:0] info: start of service (unbound 1.10.1).
```

:tada: running!!

必要に応じて、このDNSサーバのリゾルバを127.0.0.1にする。


# テスト

同じネットワークの端末から、nslookup等で名前解決ができるかテストする。

```cmd
C:\> nslookup qiita.com (DNSサーバのIPアドレス)
サーバー:  UnKnown
Address:  (DNSサーバのIPアドレス)

権限のない回答:
名前:    qiita.com
Addresses:  2406:da14:add:902:xxxx:xxxx:xxxx:xxxx
          2406:da14:add:901:xxxx:xxxx:xxxx:xxxx
          2406:da14:add:900:xxxx:xxxx:xxxx:xxxx
          54.65.xxx.xxx
          54.64.xxx.xxx
          52.199.xxx.xxx
```

といった具合に返ってこればOK

あとはネットワークアダプタのIP設定からDNSサーバの設定を変更してやれば、次から新しいDNSサーバを見に行くようになる。



# チューニング

おそらく個人レベルでは必要ないかと思われる

```conf:unbound.conf
# server: 以下に追加する

    # Tune: スレッド数。CPUコア数に合わせる
    num-threads: 4
    
    # Tune: スレッド数に近い2のN乗にする（1~2=2, 3~4=4, 5~8=8, etc.）
    msg-cache-slabs: 4
    rrset-cache-slabs: 4
    infra-cache-slabs: 4
    key-cache-slabs: 4
    
    # Tune: キャッシュメモリサイズ。rrsetのキャッシュはmsgの2倍とする
    # 実メモリ使用量は、指定したキャッシュファイルの2.5倍程度を想定しておく。
    # ex. (64m + 128m)*2.5 = 480m, (128m + 256m) * 2.5 = 965m
    msg-cache-size: 64m
    rrset-cache-size: 128m
```

他に設定しておくとよいパラメータなどありましたらご教示ください :pray: 


# おまけ

## ローカル端末の名前を引けるようにする

いちいちIPアドレスを打つのがめんどくさいときに

```conf:/etc/unbound/local.d/servers.conf(ファイル名は任意)
local-data: "iketeru.test.server.example.com. IN A 192.168.0.5"
```


## 特定のドメインの名前を引けなくする

アクセスさせたくないドメインがあるときに…

```conf:/etc/unbound/local.d/ban.conf(ファイル名は任意)
local-zone: "mitakunai.example.com." redirect
local-data: "mitakunai.example.com A 0.0.0.0"
local-data: "mitakunai.example.com AAAA ::"
```

などと羅列すれば、無効なIPアドレスが返され名前解決ができなくなる。