djbdnsでローカルドメインの名前解決をおこなう


# Goal

* djbdnsでDNSネームサーバ（権威サーバ）をたてて、プライベートなドメインの管理をおこなう
* djbdnsでDNSキャッシュサーバ（再帰検索サーバ）をたてて、同じネットワーク内のホストが利用できるようにする
* プライベートなドメインであれば自前DNSネームサーバに問い合わせ、そうでなければ外部へ再帰検索をおこなうようにDNSキャッシュサーバを設定する

![スクリーンショット 2015-01-25 1.23.21.png](https://qiita-image-store.s3.amazonaws.com/0/36978/ed9f0405-c302-67d6-e093-1095072c1d23.png "スクリーンショット 2015-01-25 1.23.21.png")
図1

# Install

以下を参考にn-djbdnsを利用してインストールする.
[Install ndjbdns on CentOS](http://qiita.com/metheglin/items/2c4f798eded252b2b61e)

# 登場人物

| 登場人物 | 説明 |
|:-----------|:------------|
| tinydns | DNSネームサーバ（権威サーバ）|
| dnscache | DNSキャッシュサーバ（再帰検索サーバ）|
| etc/ndjbdns/tinydns.conf | tinydns起動設定ファイル|
| etc/ndjbdns/dnscache.conf | dnscache起動設定ファイル|
| etc/ndjbdns/servers/* | 管理したいゾーンのドメイン名とネームサーバアドレスのマッピングを定義する|
| etc/ndjbdns/servers/roots | これがroot DNSの一覧...|
| etc/ndjbdns/ip/* | dnscacheにアクセス可能なホスト一覧を定義する|
| etc/ndjbdns/{data, data.cdb}|  tinydnsが管理するDNSレコードの実体|

# 事前確認

### djbdnsの各コマンドのパスが通っていること

```
which tinydns
which tinydns-data
which dnscache
which dnsname
```

### ネームサーバ、キャッシュサーバのデーモンが起動していること

tinydnsとdnscacheが別のIPアドレスをバインドして起動されていることを確認.
port53であることを確認.

```
lsof -i:53
  # COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
  # tinydns  23402 daemon    4u  IPv4 373980      0t0  UDP localhost:domain
  # dnscache 28041 daemon    3u  IPv4 406795      0t0  UDP 192.168.2.12:domain
  # dnscache 28041 daemon    4u  IPv4 406796      0t0  TCP 192.168.2.12:domain (LISTEN)
```

### root DNSのIPが間違っていないか確認しておく

```
## 
## ndjbdnsの設定ファイル・ディレクトリに移動する
## /usr/local以下にインストールした場合は、以下のパスになる
## 
cd /usr/local/etc/ndjbdns

dnsname `cat servers/roots`
  # h.root-servers.net
  # g.root-servers.net
  # e.root-servers.net
  # b.root-servers.net
  # c.root-servers.net
  # i.root-servers.net
  # f.root-servers.net
  # j.root-servers.net
  # k.root-servers.net
  # a.root-servers.net
  # l.root-servers.net
  # d.root-servers.net
  # m.root-servers.net
```

# tinydnsレコードを追加

図1の(1)をおこなう手順.
dataファイルを記述し、tinydns-dataコマンドでデータベースを作成する.
rvprov-jupiter.netという架空のドメインをローカルドメインとして管理することにする.

### dataファイル作成

dataファイルに以下のように記述する（なければ新規作成）.
この例では、rvprov-jupiter.netの権威サーバが192.168.2.12で、そのドメイン下のホストであるmetheglin.rvprov-jupiter.netも同じ192.168.2.12としている.
（DNSネームサーバ、DNSキャッシュサーバ、HTTPサーバを同じホストで動かしてる）

古いかもしれないけど、設定内容は以下を参考.
http://network.station.ez-net.jp/special/djbdns/doc/3-3.asp

```/usr/local/etc/ndjbdns/data
.rvprov-jupiter.net:192.168.2.12:ns

=metheglin.rvprov-jupiter.net:192.168.2.12
```

### tinydns-dataコマンドでバイナリファイルを作成する.

```
tinydns-data
ls -l /usr/local/etc/ndjbdns/data.cdb
  # data.cdbが作成されていることを確認
```

### reload

```
service tinydns reload
```

### 確認

DNSデーモンを起動しているホストからdigコマンドで権威サーバに直接問い合わせをおこなう.

```
## 
## digコマンドに@をつけて問い合わせをおこなうネームサーバ/キャッシュサーバを指定できる
## 
dig @localhost metheglin.rvprov-jupiter.net
  # ;; AUTHORITY SECTION:
  # rvprov-jupiter.net.	2560	IN	SOA	ns.ns.rvprov-jupiter.net. hostmaster.rvprov-jupiter.net. 1422109757 16384 2048 1048576 2560
```

# dnscache設定

### 同じネットワーク内（今回は192.168.2.*）からのアクセスを許可する

図1の(3)を許可する手順.
ipディレクトリ以下にIPアドレスをファイル名とした空ファイルを作ることでACLを作る.

```
touch /usr/local/etc/ndjbdns/ip/192.168.2
```

### tinydnsとdnscacheの連携

図1の(2),(4)を実現する.
dnscacheが名前解決のリクエストを受け付けたとき、tinydnsが管理しているゾーンのドメインであれば、tinydnsに名前解決をリクエストし、見つからなければ外部ネットワークに再帰検索を委譲する.

#### resolv.conf設定

同じDNSサーバ内で名前解決をおこなったときに、デフォルトでdnscacheのデーモンを利用するように、DNSキャッシュサーバのアドレス（192.168.2.12）を追加する.
/etc/resolv.confはLinux共通のファイルなので/etcにおいてる点に注意.

```:/etc/resolv.conf
; generated by /sbin/dhclient-script
nameserver 192.168.2.12
nameserver 10.0.2.3
```

#### ゾーン設定

djbdns設定ファイルルートのservers以下にゾーン名をファイル名としたファイルを作成し、ネームサーバのアドレスをファイル内に記載する.

```
echo "127.0.0.1" > /usr/local/etc/ndjbdns/servers/rvprov-jupiter.net
```

### reload

設定を変更したらreloadまたはrestartする.

```
service dnscache reload
```

### 確認

DNSサーバとは別の、PCなどから、リゾルバを指定して名前解決コマンドを投げる.
ANSERセクションにAレコードのIPが返ることを確認する.

```
## 
## 内部に権威が存在するドメインで名前解決
## 
dig @192.168.2.12 metheglin.rvprov-jupiter.net
  # ;; ANSWER SECTION:
  # metheglin.rvprov-jupiter.net. 85950 IN	A	192.168.2.12

## 
## 外部に権威が存在するドメインで名前解決
## 
dig @192.168.2.12 metheglin.jp
  # ;; ANSWER SECTION:
  # metheglin.jp.		3600	IN	A	49.212.37.195
```

dnscacheの通信を捕捉するコマンド（DNSサーバ側で実行）
（※ 1秒以内で名前解決が完結する場合コマンドで捕捉できないのであくまで参考）
（※ 一度検索成功するとキャッシュにのるので初名前解決したドメインでないと捕捉できないかも）

```
while :; do echo "-----------"; netstat -an | grep "ESTA" | grep :53; sleep 1; done
  # udp        0      0 10.0.2.15:49021             49.212.111.248:53           ESTABLISHED
```

# デフォルトのDNSリゾルバを変更

PC側でブラウザのアクセスもオリジナルDNSを経由させたい場合は、Macであればシステム環境設定などでdnscacheがlistenするアドレスを指定する.
（「DNSサーバ　変更」などでぐぐればOK）

# Others

間違いがあればご指摘お願い致します.

# Environment

```
uname -a
  # Linux *** 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/issue
  # CentOS release 6.5 (Final)
  # Kernel \r on an \m
```

# References

* http://pjp.dgplug.org/ndjbdns/document.html
* http://network.station.ez-net.jp/special/djbdns/index.asp
* http://www.nslabs.jp/djbdns.rhtml
* http://www41.tok2.com/home/pochi/oshigoto/oshigoto/04dnscachex.htm