脱bind〜改めて考えるDNSセキュリティ2018

# はじめに
脆弱性が後を絶たないBINDを踏まえて、DNSセキュリティについて学習するにあたり、NSDとUnboundに興味を持ったのでまとめました。NSDやUnboundは両方とも最新の技術という訳ではないですが、BINDから他のDNSソフトウェアに変更する場合は最適なDNSソフトウェアだと思います。

## BIND9の脆弱性について
今年も既に[1件の脆弱性](https://www.ipa.go.jp/security/ciadr/vul/20180118-bind.html)が見つかりましたが、BINDの脆弱性は本記事執筆時点で、1999年～2017年で96件、その内DOS攻撃に係るのは66件になり全体の約70%近くになります。

[参考](https://www.cvedetails.com/product/144/ISC-Bind.html?vendor_id=64)
![スクリーンショット 2018-02-22 00.52.47.png](https://qiita-image-store.s3.amazonaws.com/0/221759/d25bcf75-f9bc-adbc-51b6-4b4298b19bff.png)

### **2017年に発見された脆弱性（合計：3件）**

| CVE ID       |    CVSS 基本値    |    概要  |    影響  |
|:-------------|:-----------------|:---------|:---------|
| CVE-2016-9444	|	5.0	|	ISC BIND の named には、サービス運用妨害 (表明違反およびデーモンの停止) 状態にされる脆弱性が存在します。	|	リモートの攻撃者により、応答時の巧妙に細工された DS リソースレコードを介して、サービス運用妨害 (表明違反およびデーモンの停止) 状態にされる可能性があります。	|
| CVE-2016-9147	|	5.0	|	ISC BIND の named には、サービス運用妨害 (表明違反およびデーモンの停止) 状態にされる脆弱性が存在します。	|	リモートの攻撃者により、矛盾した DNSSEC に関連する RRset を含む応答を介して、サービス運用妨害 (表明違反およびデーモンの停止) 状態にされる可能性があります。	
| CVE-2016-9131	|	5.0	|	ISC BIND の named には、サービス運用妨害 (表明違反およびデーモンの停止) 状態にされる脆弱性が存在します。	|リモートの攻撃者により、RTYPE ANY クエリへの不正な形式の応答を介して、サービス運用妨害 (表明違反およびデーモンの停止) 状態にされる可能性があります。|

BINDの脆弱性が絶えない理由については、長年にわたる多数の拡張機能でプログラムが複雑化したことにより、入力データのチェックが不十分になっているのが、脆弱性が次々に見つかる原因だと言われています。

### **BIND9を推奨しない理由**   
上記統計データを見ての通り、BINDはDOSS攻撃に関連する脆弱性が発見され続けています。よって、BINDを使用続けるメリットよりデメリットのほうが多くなってきています。

- [x] **DOS攻撃を受けやすい**
- [x] **運用コストが高い（脆弱性発生時のパッチ適用）**

## NSD/Unbound
### 概要
NSDはオランダで設立された非営利団体の[NLnet Labs](https://www.nlnetlabs.nl/)により開発されているオープンソースのDNSソフトウェアです。最新バージョンは[こちら](https://www.nlnetlabs.nl/projects/nsd/)よりダウンロードできます。
![スクリーンショット 2018-02-22 00.49.15.png](https://qiita-image-store.s3.amazonaws.com/0/221759/bb186710-512c-5024-4b9a-14483005e759.png)

また、[Unbound](http://unbound.net/)も[NLnet Labs](https://www.nlnetlabs.nl/)で開発されているオープンソースのDNSソフトウェアです。最新バージョンは[こちら](http://unbound.net/download.html)よりダウンロードできます。
![スクリーンショット 2018-02-22 00.50.11.png](https://qiita-image-store.s3.amazonaws.com/0/221759/b454d8e7-3dd3-e4f4-4e0c-a307268bf193.png)

### 利用実績
NSDはルートサーバ(※)で使用されています。なお、[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%BC%E3%83%88%E3%82%B5%E3%83%BC%E3%83%90)より日本でもまだbindが使われているのが確認できます。Unboundの国内における利用も数年前から徐々に増えていると推測されますが、依然BINDを利用しているシステムが多いのが現状だと思います。

(※)ルートサーバの最新情報は[こちら](https://www.internic.net/zones/named.root)で確認できます。

### **NSD及びUnboundの利点**
- **NSDもUnboundも導入が容易であり、脆弱性が少ない。**
- **NSDは応答性能が良く、Unboundはキャッシュ機能に特化しているため早い。**
- **Unboundなどのキャッシュサーバはチューニングが肝とされるが、大規模サイト以外の利用であれば、デフォルト設定でも十分使えそう。**

### Unboundの脆弱性
Unboundの脆弱性はこれまで過去に3件発見されているようです。

[参考](https://www.cvedetails.com/vulnerability-list/vendor_id-10197/Unbound.html)
![スクリーンショット 2018-02-22 00.59.15.png](https://qiita-image-store.s3.amazonaws.com/0/221759/203b3b45-9840-8cd8-6a90-aaed3f469196.png)

## NSDとUnboundの導入
CentOSを例にNSDとUnboundのインストール手順について記載します。

OS：CentOS Linux release 7.3.1611 (Core)

### NSD
#### NSDのインストール
-  はじめに[EPEL](https://fedoraproject.org/wiki/EPEL)をインストールする。
`# rpm -i https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm`  

-  yumコマンドの実行時にEPELのリポジトリを使用するために、オプションを付けてNSDをインストールする。
`# yum install --enablerepo=epel nsd`

#### NSDの設定
-  nsd.confを編集する。  
`# vi /etc/nsd/nsd.conf`

編集例）

```bash
zone:
  name: "example.jp"
  zonefile: "zones/%s.zone"
```

-  ゾーンファイルを格納するディレクトリを作成する。
`# mkdir /etc/nsd/zones`

-  ゾーンファイルを作成する。
`# vi /etc/nsd/zones/example.jp.zone `   

編集例）　"N"は、IPアドレスを意味する

```bash
$ORIGIN example.jp.
$TTL 3600
@ IN SOA ns.example.jp. postmaster.example.jp. (
        1   ; serial
        1h  ; refresh
        15m ; retry
        1w  ; expire
        1h  ; negative cache TTL
       )
@  IN NS ns.example.jp.
ns IN A  192.168.N.N
```

-  nsdを起動する。
`# systemctl start nsd `   

-  nsdの状態を確認する。
`# systemctl status nsd`  

#### NSDの動作確認
-  nsd-controlコマンドでゾーンが読み込まれていることを確認する。
`# nsd-control zonestatus example.jp`  

-  digコマンドで名前解決ができることを確認する。
`# dig +norec +norcd @localhost any example.jp`  

---

### Unbound
#### Unboundのインストール
-  unboundをインストールする。  
`# yum install unbound`

#### Unboundの設定（アクセスコントロール）
-  unbound.confを編集する。  
`# vi /etc/unbound/unbound.conf`
 
```bash
# 変更部分のみ記載
server:
 	 interface: 0.0.0.0
 	 interface: ::0

     access-control: 192.168.N.0/24 allow

```

#### Unboundの設定（ログ設定） 
-  ログ出力用ディレクトリを作成する。    
`# mkdir /var/log/unbound`
-  所有者をunboundに変更する。   
`# chown unbound.unbound /var/log/unbound`

**クエリログはデフォルト無効のため以下の方法で出力可能。**

- 一時的に有効にする場合はunbound-controlコマンドを実行する。
`# unbound-control set_option log-queries: yes`

- 恒久設定を行う場合はunbound.confに以下を設定する。

```bash
# serverセクションに以下を追加
server:
 	 log-queries: yes
```

- unboundを起動する。  
`# systemctl start unbound`
- unboundの状態を確認する。  
`# systemctl status unbound`

#### Unboundの動作確認 
-  名前解決できることを確認する。  
`# dig +short +rec @localhost www.google.com`

#### Unboundコマンド
-  バージョン確認　※-hでバージョンとヘルプ両方出力されるためgrepする
`# unbound -h | grep Version`

-  設定ファイル確認（構文チェック）
`# unbound-checkconf`

-  リゾルバを使用して、ホスト名と結果を表示する。
`# unbound-host www.example.com`

-  キャッシュ情報をダンプ出力
`# unbound-control dump_cache`

### 参考
- [Unboundドキュメント](http://unbound.net/documentation/index.html)
- [DNS-OARC](https://www.dns-oarc.net/oarc/services/replysizetest)