Raspberry Pi に DNS サーバを構築してみる


参考: [Dnsmasq 軽量 DNS サーバ構築（内部向け）](http://server.etutsplus.com/dnsmasq-setup-internal-dns/)

## 前提

### 環境

OS: Raspbian Jessie May 2016

### 構成

```
[インターネット]
 ||
[Buffalo ルータ (DHCP)]
 ||
 || FE 0: 192.168.11.xxx/24
[Cisco 1800 ルータ (DHCP)]
 || FE 1: 192.168.0.254/24
 ||
[Catalyst 2950 L2SW]
 ||
[Raspberry Pi "takuya" (192.168.0.30/24)], [Raspberry pi "hideyasu" (192.168.0.18/24)]
```

ドメイン名: hideyasu.net

| ホスト名 | IP アドレス | FQDN | 役割 |
|------------|--------------|-----------------------|----------------|
| takuya     | 192.168.0.30 | takuya.hideyasu.net   | DNS サーバ      |
| hideyasu   | 192.168.0.18 | hideyasu.hideyasu.net | DNS クライアント |

### 事前準備

DNS サーバ・DNS クライアント共通の事項です。

#### 必須

- resolvconf パッケージのインストール

`sudo apt-get install resolvconf`

`/etc/network/interfaces` に記述した設定が `/etc/resolv.conf` に反映されるようになります。

#### 推奨

- Vim のインストール

`sudo apt-get install vim`

- dnsutils パッケージのインストール

`sudo apt-get install dnsutils`

コマンド `nslookup` や `dig` が使えるようになります。

## DNS サーバ側

### 静的 IP アドレスとリゾルバの設定

ローカルネットワークの DNS サーバである自分自身を指す `127.0.0.1` と、Google Public DNS `8.8.8.8` をリゾルバの DNS サーバとして指定します。
後者の上位 DNS サーバの指定により、インターネットにドメイン名でアクセスできるようになります (インターネット上での名前解決が可能になります)。

``` /etc/network/interfaces
...
12 auto eth0
13 iface eth0 inet static
14     address 192.168.0.30
15     netmask 255.255.255.0
16     gateway 192.168.0.254
17     dns-domain hideyasu.net
18     dns-nameservers 127.0.0.1 8.8.8.8
...
```

### Dnsmasq をインストールする
次のコマンドで Dnsmasq をインストールします。

`$ sudo apt-get install dnsmasq`

Dnsmasq はインストールするだけでシステム起動時に自動的にサービスが起動するように設定されるようです。

### Dnsmasq の設定

Dnsmasq によって生成された設定ファイルを編集していきます。
デフォルトではすべてコメントアウトされているので、必要な箇所だけアンコメントします。

次のコマンドで、コメントアウトされていない行だけを表示できます。

`$ cat /etc/dnsmasq.conf | grep -v "^#" | grep -v "^$"`

まだ編集を行っていないため、何も表示されません。

Dnsmasq をローカルネットワーク用の内部向け DNS サーバとして動かすための最低限の設定を行います。
何らかのテキストエディタで `/etc/dnsmasq.conf` を開き、下記の 5 箇所を変更します。

```/etc/dnsmasq.conf
...
18 # Never forward plain names (without a dot or domain part)
19 domain-needed
20 # Never forward addresses in the non-routed address spaces.
21 bogus-priv
...
72 # Add local-only domains here, queries in these domains are answered
73 # from /etc/hosts or DHCP only.
74 local=/hideyasu.net/
...
133 # Set this (and domain: see below) if you want to have a domain
134 # automatically added to simple names in a hosts-file.
135 expand-hosts
...
137 # Set the domain for dnsmasq. this is optional, but if it is set, it
138 # does the following things.
139 # 1) Allows DHCP hosts to have fully qualified domain names, as long
140 #     as the domain part matches this setting.
141 # 2) Sets the "domain" DHCP option thereby potentially setting the
142 #    domain of all systems configured by DHCP
143 # 3) Provides the domain part for "expand-hosts"
144 domain=hideyasu.net
...
```

### hosts の設定

`/etc/hosts` に登録したいサーバの IP アドレス・FQDN・ホスト名をすべて登録します。 
DNS サーバ自身の IP アドレス・FQDN・ホスト名は必ず登録します。
登録されていないと、Dnsmasq サービスの起動に失敗します。

``` /etc/hosts
1 127.0.0.1 localhost
2 ::1   localhost ip6-localhost ip6-loopback
3 ff02::1   ip6-allnodes
4 ff02::2   ip6-allrouters
5 
6 127.0.1.1 takuya-itc30-raspberrypi
7 192.168.0.30 takuya.hideyasu.net takuya
8 192.168.0.18 hideyasu.hideyasu.net hideyasu
```

### 最終チェック

- DNS サーバ自身の IP アドレスが正しいこと

```
$ ip addr | grep inet | fgrep -v "127.0.0.1"
    inet6 ::1/128 scope host 
    inet 192.168.0.30/24 brd 192.168.0.255 scope global eth0
    inet 192.168.0.5/24 brd 192.168.0.255 scope global secondary eth0
    inet6 fe80::ba27:ebff:febe:5ec1/64 scope link 
```

- `/etc/hosts` に DNS サーバの IP アドレス・FQDN・ホスト名が登録されていること

```
$ cat /etc/hosts | fgrep "192.168.0.30"
192.168.0.30 takuya.hideyasu.net takuya
```

- `/etc/network/interfaces` に DNS サーバ自身の IP アドレスが設定されていること

```
$ cat /etc/network/interfaces | grep "dns-nameservers"
    dns-nameservers 127.0.0.1 8.8.8.8
```

### Dnsmasq サービスの起動

次のコマンドで Dnsmasq サービスを起動します。

`$ sudo service dnsmasq start`

何も表示されなければ正常に起動しています。

次のコマンドで 53 番ポートが LISTEN 状態であることを確認します。

```
$ sudo netstat -anp | fgrep ":53" | fgrep "dnsmasq"
tcp        0      0 0.0.0.0:53              0.0.0.0:*               LISTEN      1115/dnsmasq    
tcp6       0      0 :::53                   :::*                    LISTEN      1115/dnsmasq    
udp        0      0 0.0.0.0:53              0.0.0.0:*                           1115/dnsmasq    
udp6       0      0 :::53                   :::*                                1115/dnsmasq    
```

上記の結果、 `0.0.0.0` は検証のためすべて受け付けるようになっています。
また、UDP は状態を持たないプロトコルなので、上記のような結果が出ていれば大丈夫です。

## DNS クライアント側

### 静的 IP アドレスとリゾルバの設定

ローカルネットワークの DNS サーバである `takuya.hideyasu.net` を指す `192.168.0.30` をリゾルバの DNS サーバとして指定します。

``` /etc/network/interfaces
12 auto eth0
13 iface eth0 inet static
14     address 192.168.0.18
15     netmask 255.255.255.0
16     gateway 192.168.0.254
17     dns-domain hideyasu.net
18     dns-nameservers 192.168.0.30
```

### DNS の動作確認

```
$ nslookup takuya
Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	takuya.hideyasu.net
Address: 192.168.0.30
```

```
$ nslookup takuya.hideyasu.net
Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	takuya.hideyasu.net
Address: 192.168.0.30
```

```
$ nslookup 192.168.0.30
Server:		127.0.0.1
Address:	127.0.0.1#53

30.0.168.192.in-addr.arpa	name = takuya.hideyasu.net.
```

```
$ dig +short takuya
192.168.0.30
```

```
$ dig +short takuya.hideyasu.net
192.168.0.30
```

```
$ dig +short -x 192.168.0.30
takuya.hideyasu.net.
```