DNSの仕組みとBINDの設定（基礎＋ログ出力設定）

実装環境
---

```
[root@ns1 ~]# cat /etc/redhat-release
CentOS release 6.6 (Final)
[root@ns1 ~]# uname -a
Linux ns1.homelab.strike-witches.moe 2.6.32-504.30.3.el6.x86_64 #1 SMP Wed Jul 15 10:13:09 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
```

インストール,設定
---
```
[root@ns1 ~]# yum install bind
```
ゾーン情報に関する設定ファイルは/var/named配下に,BIND自体の設定ファイルは/etc/配下に設置されている.また,今回はchrootを実装しない.理由としては,外部からのアクセスは実装されていないため.

## chrootについて

セキュリティ確保のためにchrootが推奨されている.chrootを実施し動作させることにより,bindがサンドボックスに似た状態で動作をする.それにより,いざサーバに侵入された場合でも受ける被害を制限することができる.
今回は外部公開しないため,chroot非適用で実装する.

```
  //
  // named.conf
  //
  // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
  // server as a caching only nameserver (as a localhost DNS resolver only).
  //
  // See /usr/share/doc/bind*/sample/ for example named configuration files.
  //

  acl internal{
  192.168.100.0/24;
  127.0.0.1/32;
  };

  acl my_nic{
  192.168.100.1;
  127.0.0.1;
  };

  options {
  listen-on port 53 { my_nic; };
  #listen-on-v6 port 53 { ::1; };
  version"unknown";
  directory "/var/named";
  dump-file "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
	allow-query     { internal; };
	recursion yes;
	allow-recursion { internal; };

	dnssec-enable yes;
	dnssec-validation yes;
	dnssec-lookaside auto;

	/* Path to ISC DLV key */
	bindkeys-file "/etc/named.iscdlv.key";

	managed-keys-directory "/var/named/dynamic";
  };

  logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
  };

  zone "." IN {
  type hint;
  file "named.ca";
  };

  include "/etc/named.rfc1912.zones";
  include "/etc/named.root.key";

  zone "homelab.strike-witches.moe" IN {
    type master;
    file "internal_homelab.strike-witches.moe.zone";
  };

  zone "100.168.192.in-addrarpa" IN {
    type master;
    file "internal_100.168.192.in-addr.arpa.zone";
  };
  
  zone "test.jp" IN {
    type forward;
    forward only;
    forwarders { 192.168.100.254; };
    };
```

設定値に関する詳細
----

## aclステートメント
マッチしたIPアドレスを定義する仕組み.フォーマットとして以下が設定されている

```
  acl acl-name {
    address_match_list
  };
```

## optionsステートメント
bindで利用するグローバルオプションを設定できる

### listen-on
サーバが名前解決を受け付けるインターフェースを設定する
ポートまで詳細に設定することが可能

### version
DNSサーバのバージョン情報リクエストに対する回答文字列を指定する

### allow-query
名前解決を許可するクエリの送信元ネットワークを指定する
許可されていないネットワークからのクエリは捨てられる
デフォルトでは全てのネットワークからのクエリを名前解決する

### recursion
サーバが再帰問合わせを行うかどうか指定する
デフォルトではyesになっている

### allow-recursion
再帰問合わせを許可する送信元ネットワークを指定する
デフォルトではlocalhostとlocalnetsが許可されている

### allow-query-cache
サーバが蓄積したキャッシュからの回答を許可するネットワークを指定する
デフォルトではlocalhostとlocalnetsが許可されている

zoneステートメント
---
ゾーン情報に関する設定をする. フォーマットとして,以下が設定されている

```
  zone zone_name [class] {
            .....
  };
```

### zone_name
自分が扱うゾーン情報を指定する. 正引き情報の場合はドメイン名を、逆引きの場合は第4オクテットから記載していく
例として....

```
0.168.192.in-addr.arpa -> 192.168.0.0/24に関するゾーンステートメント
128/28.0.168.192.in-addr.arpa -> 192.168.0.128/28に関するゾーンステートメント
```

### classはINはインターネット上での利用を指定する
基本はINでOK

### type
zone_nameに対する自分のサーバとしての役割を指定する.
masterの場合はプライマリサーバとして、slaveの場合はセカンダリサーバとして役割を明示的に表す

### file
zone_nameで指定したゾーンの情報が記載されたファイルを指定する

viewステートメント
---
送信元ネットワークに対して別々の挙動を実行することを実現するためのステートメント. 
match-clientsにマッチしたクライアントに対して,viewステートメント内部で指定した挙動を実施する.
最初にマッチしたviewで処理されるため,書く順番を気にしておかなければならない.
フォーマットとして,以下が設定されている.

```
  view "view_name" {
       match-clients{ acl_name; };
       ......
  };
```

特定ドメインに対してDNSサーバを指定する
---
特定のドメインに対するクエリがきたら,特定のDNSへクエリを転送（回送）させることができる.
フォーマットは以下の通り

```
  zone "domain_name" IN {
   type forward;
   forward first | only ; (default is first)
   forwarders {DNS_Address; .... };
   };
```

type forwardにて,domain_nameに対する名前解決を回送させることを明示する.
forwardは名前解決ができなかった際の挙動に関する設定である.
firstは,まず回送先のDNSサーバにて解決をし解決できなかった場合,自分でrootDNSから解決する.
onlyは,回送先で解決できなければ,解決できなかったと答えを返す.
forwardersは,回送先のDNSサーバを指定する.

ゾーンファイルを書いてみる
---
ゾーンファイルにはORIGINディレクティブ,TTLディレクティブ,リソースレコードが記載される.
それぞれの意味は以下の通り.

|ORIGINディレクティブ|TTLディレクティブ|リソースレコード|
|---|---|---|
|ドメイン名が示されていない場合,補完するドメイン名|他のDNSサーバがこのゾーンデータをキャッシュする時間|ゾーンに関する情報|

注意しなければならないのが,ゾーン情報でドメイン名に「.」を記載していない場合, ORIGINディレクティブで記載されたドメイン名が末尾に補完されてしまう.
また,ゾーンファイルには様々なリソースレコードのタイプが存在する.必要に応じて記載する.

|SOA|NS|MX|A|AAAA|CNAME|PTR|
|---|---|---|---|---|---|---|
|ゾーンに関する情報|ゾーンを管理するDNSサーバの情報|メールサーバに関する情報|ホスト名に対するIPv4アドレスの情報|ホスト名に対するIPv6アドレスの情報|別名の正しいホスト名情報|IPアドレスに対するホスト名の情報|

設定内容
---

```
  $ORIGIN homelab.strike-witches.moe.
  $TTL 43200
  @    IN SOA ns1.homelab.strike-witches.moe. root.homelab.strike-witches.moe.(
       2015072501 ;Serial
       10800 ;Refresh
       10800 ;Retry
       86400 ;Expire
       3600 ;Minimum
  )

  homelab.strike-witches.moe. IN NS ns1.homelab.strike-witches.moe.
  ns1                         IN A  192.168.100.1
  proxy 		      IN A  192.168.100.2
  main 			      IN A  192.168.100.3
  www 			      IN A  192.168.100.4
  esxi			      IN A  192.168.24.60
  splunk		      IN A  192.168.24.63
```

## 設定詳細

### SOAレコード
1行目には,DNSサーバのホスト名と管理者のメールアドレスを記載する.
2行目には,シリアル番号を記載する.番号は任意の番号でよい.ゾーンファイルの更新状態を明確化させるために利用する.
3行目には,スレーブDNSサーバがマスターDNSサーバのゾーン情報の更新を確認しに行く間隔を記載する.
4行目には,スレーブDNSサーバがマスターDNSサーバにアクセスできなかった際,リトライするまで待機する時間を記載する.
5行目には,スレーブDNSサーバがマスターDNSサーバにアクセスできなかった際,引き継いでいるゾーン情報を破棄するまでの待機時間を記載する.
6行目には,存在しないドメインに関するキャッシュデータの保持期間を記載する.
「@」は$ORIGINで定義されたドメイン名を示している.

```
  domain IN SOA ドメインの権威サーバ名 ドメイン管理者のメールアドレス (Serial,Refresh,Retry,Expire,Minimum);
```

### NSレコード
domainを管理しているDNSサーバを指定する.DNSサーバ名はFQDNで記載する.
また,フォーマットとして以下の通り

```
  domain IN NS DNSサーバ名
```

### MXレコード
メールサーバがメールを送信する際に参照するレコード.domainを管理するメールサーバ名を記載する.
プリファレンス値は優先度を示し,値が小さい方が優先される.メールサーバ名はFQDNで記載する.
また,フォーマットとして以下の通り

```
  domain IN MX プリファレンス値 メールサーバ名
```

### Aレコード
 ホスト名に対するIPv4アドレスを指定する.フォーマットとして以下の通り

```
  ホスト名 IN A IPv4アドレス
```

### AAAAレコード
ホスト名に対するIPv6アドレスを指定する.別名クアッドAレコード.
フォーマットとして以下の通り

```
 ホスト名 IN AAAA IPv6アドレス
```

### CNAMEレコード
ホスト名の別名を記載する.フォーマットとして以下の通り

```
 別名 IN CNAME ホスト名
```

### PTRレコード
IPアドレスに対するホスト名を記載する.
フォーマットとして以下の通り

```
 IPアドレス IN PTR ホスト名
```

詳細なログ出力の設定
---
amed.confのloggingセクションにデフォルトで記述されている設定では,エラー及びプロセスのアップ/ダウンしかログに出力されない.
クエリ受付及び処理に関するログ出力の設定を行う.
設定する際の流れとしては,channelというログ出力方法に関する詳細設定を定義する.
その後,どのようなログを出力するかcategoryで定義する.

設定
---
以下が今回,クエリ受付に関する処理ログを出す設定である.

```
  logging {
         channel query_log {
                file "log/query.log" versions 10 size 20M;
                severity dynamic;
                print-time yes;
                print-severity yes;
                print-category yes;
        };
        
        category queries {
                 query_log;
        };

  };
```
query_logという名前でchannelを作成し,そのquery_logはどのようなログ出力方法を利用するのか定義している.

## channel


### file
今回は,ログファイルを生成するためファイルパスを指定しているが,nullやsyslog,stderrが設定できる.
nullはログを破棄する.syslogはsyslogへ転送する.stderrは標準エラー出力へ書き出す.
versionsで保持されるファイル世代数を,sizeではローテーションする際の基準となるファイルサイズが指定することができる.

### severity
出力される内容を指定する.指定できるものは,

```
critical,error,warning,notice,info,debug,dynamic
```

となっており,dynamicは全てのログが出力される.

### print-time
ログにタイムスタンプが出力されるかどうか指定する.時間は重要な情報源なのでyes.

### print-severity
ログに重要度が出力されるかどうか指定する.後々役に立つためyes.

### print-category
ログにカテゴリ名が出力されるかどうか指定する.後々役に立つためyes.

### category
出力するログがどのようなものなのかを指定する.選択肢は以下の表の通り.

|カテゴリ|内容|
|---|---|
|database|ゾーン情報やキャッシュ情報など、データベースに関連する記録|
|security|要素の承認／否認記録|
|config|構成ファイルの構文解析と処理の記録|
|resolver|クライアントに代わって実行されるキャッシュサーバの動作に代表される、再帰検索のようなDNS解決の記録|
|xfer-in|サーバが受信したゾーン転送の記録|
|xfer-out|サーバが送信したゾーン転送の記録|
|notify|NOTIFY（通知）プロトコルの記録|
|client|クライアント要請の処理記録|
|network|ネットワーク操作の記録|
|update|DDNSの記録|
|queries|問い合わせクエリーの記録|
|dispatch|サーバモジュールへ入ってくるパケットを処理するCPU割り当て（ディスパッチ）の記録|
|dnssec|DNSSECやTSIG処理の記録|
|lame-servers|DNS解決の際にほかのサーバで見つけた設定ミス（lame）の記録|
|general|上記以外の多くのログはカテゴリが未分類であり、それらはgeneralに分類される|
|default|categoryで意図的に指定された以外のカテゴリがここで定義される|


出力されるログ
---
今回設定した内容だと以下のようなログが出力される.

```
  31-Jul-2015 23:48:00.563 queries: info: client 192.168.100.3#50986: query: splunk.homelab.strike-witches.moe IN A + (192.168.100.1)
```

clientでは,クライアントのソースIP/ソースポート情報が,queryには受け付けたクエリと回答したサーバのIPアドレスが記述される.


参考
artmarkIT BIND9の運用情報収集と分析方法
<http://www.atmarkit.co.jp/ait/articles/0310/15/news001.html>