Unboundを使って，フォワーダーとDoTで通信するキャッシュDNSサーバーを作る

# はじめに
DNSサーバーとの通信は多くの場合、暗号化されずに平文で行われるため、第三者に通信内容を閲覧されたり、改ざんされたりするリスクがあります。

こうした課題を解決する手段の一つとして、**DNS over TLS（DoT）** が注目されています。**DoT** は、DNSのクエリとレスポンスを**TLS（Transport Layer Security）** で**暗号化**することで、通信の秘匿性と完全性を確保する技術です。

こうした通信に対応するパブリックDNSサーバーは未だ少数に留まりますが、今回は**Cloudflare DNS**と自宅キャシュDNSサーバーとの通信を**DoT**で通信し、よりセキュアなDNS通信を行います。


## システム概要図
今回作るシステムはこんな感じです。
![システム概要図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/dc051678-17d2-4e33-a55c-5accaa609c8a.jpeg)


LAN内のDNSクエリを受け付ける、キャッシュDNSサーバーとして利用することを想定します。

LAN内のクエリについては、平文で通信を行いますが、キャッシュされていないDNSレコードをパブリックDNSより受け取る際に、**DoT** で通信を行うというものです。

# 方法
今回は、**Raspberry Pi**に**Unbound** をインストールすることを想定します。

同じ**Debian** 系OSを使っていれば手順は変わらないと思います。

## 1. Unboundをインストールする
**apt**を使って**Unbound**をインストールします。

```bash
sudo apt update && sudo apt install unbound
```

## 2. 設定ファイルを編集する
続いて設定ファイルを編集し、Unboundの初期設定を行います。

``/etc/unbound/unbound.conf``をお好きなエディタで開きます。

```bash
sudo nano /etc/unbound/unbound.conf
```
開いたファイルに以下のように書き換えます。

```/etc/unbound/unbound.conf
# Unbound configuration file for Debian.
#
# See the unbound.conf(5) man page.
#
# See /usr/share/doc/unbound/examples/unbound.conf for a commented
# reference config file.
#
# The following line includes additional configuration files from the
# /etc/unbound/unbound.conf.d directory.
server:
    # 基本設定
    verbosity: 4
    interface: 0.0.0.0
    interface: ::0
    num-threads: 4
    #logfile: /var/log/unbound.log
    # デフォルト拒否
    access-control: 0.0.0.0/0 refuse
    access-control: ::0/0 refuse
    # IPv4設定
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.100.0/24 allow
    # IPv6設定
    access-control: ::1 allow
    access-control: ::ffff:127.0.0.1 allow

    # IPv6 対応
    do-ip6: yes
    do-ip4: yes
    do-udp: yes
    do-tcp: yes

    # DNSのセキュリティ対策
    hide-identity: yes 
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes

# DNS over TLS を Cloudflare に使う
forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853
    forward-addr: 1.0.0.1@853
    forward-addr: 2606:4700:4700::1111@853
    forward-addr: 2606:4700:4700::1001@853
```

今回の設定ファイルでは、**Cloudflare DNS** をフォワーダーとして使用し、通信には**DoT**を使用するほかに
- ``IPv4, v6``の双方の通信を受付
- 同一サブネット（家庭内LAN）からの通信を許可
- udp, tcp両方を使う
- クライアントにアイデンティティ情報やバージョン情報を知られないようにする
- glueレコードに対して厳密な検証を行う

という設定を盛り込んでいます。

## 3. 設定ファイルの適用
先ほど記述した設定ファイルに構文のエラーがないか、チェックを行います。
以下のコマンドを実行してください。

```bash
unbound-chekconf
```

設定ファイルに問題がなければ、
```bash
unbound-checkconf: no errors in /etc/unbound/unbound.conf
```

と返ってきます。もし、エラーがある場合にはインデントミスやタイプミスがないか、チェックしましょう。

問題がなければ、設定ファイルの適用を行います。以下のコマンドを実行し、**unbound**を再起動しましょう。

```bash
sudo systemctl restart unbound
```

# 動作確認
続いて正しくunboundが動作しているか確認していきます。今回は**Linux** や**MacOS** に標準搭載されている、``dig``コマンドで動作を確認します。

以下のコマンドを実行し、正しく返答が返ってくるか確認しましょう。
```
dig A @キャッシュDNSサーバーのアドレス google.com 
```

``ANSWER SECTION``の欄に以下のような返答が返ってきていたら成功です。

```bash
;; ANSWER SECTION:
google.com.             263     IN      A       142.250.206.206
```
お疲れ様でした。

# 余談
キャッシュDNSサーバーは家庭用の無線LANルーターに搭載されていることが多く、わざわざ自身で構築する理由がないように見えるかもしれません。

しかし、家庭用の無線LANルーターに搭載されているDNSサーバーは平文で通信を行っていることも多いのが現状です。


そのため、今回のように自分でキャッシュDNSサーバーを作成することで、DNSの上流への問い合わせを暗号化することができるようになります。

また、自分のキャッシュDNSサーバーを構築するメリットとして、特定のドメインはローカルで名前解決をしてしまうこともできるようになります。

したがって、``example.home``というドメインについては、``192.168.1.1``を返す、といったようにSSH接続をする際にIPを手打ちする必要がなくなるというのもメリットといえるでしょう。

# 参考文献
https://unbound.jp/unbound/

https://qiita.com/kurokoya/items/cd7d8b2aad9464089a05

https://qiita.com/squid_lo39/items/a6b8113f3218c4b19067