DNSサーバの構築をする際には選択肢は意外と少ないと思います。
オープンソース系で言えばdjbdnsとbindがとりあえずメジャーではないでしょうか?
しかし、シェアを見れば実稼動してるサーバではbindがほとんどでしょう。
まだ、新しいdjbdnsは浸透していないように見てます。よってbindを選択することにします。


#でも、djbといえばqmailを見るとsendmailをもしかしたら
#抜くかもって勢いなんでそのうちbindを抜くかも?ってことになるのかな?


【準備】
ダウンロードはこちらから
ftp://ftp.isc.org/isc/bind9/
から最新版をダウンロードしてきます。
バージョンはとりあえず9を使ってみることにします。
※セキュリティホールが発見されているので最新を使いましょうね。

bind9ではとりあえず
・DNSSEC
・TSIG
・IPv6

なんかが目立った機能追加された部分ではないでしょうか?

【インストール】
※前提条件としてSolaris8で構築する場合はここのフリーソフトのインストールは
行っているものとする。あくまでSol8でのログなのでLinuxでやるとipv6の部分が
成功するか分からないのでLinuxの場合はとりあえずconfigureはオプション無し
でやってもOKなのでは?IPv6するにはおそらくカーネルをいじらないとダメです。
もしカーネルが古い場合は--disable-threadsをつけた方がいいかも。


bash-2.05# cd /usr/local/arch
bash-2.05# gzip -d < bind-9.3.0rc1.tar.gz | tar xf -
bash-2.05# cd bind-9.3.0rc1/
bash-2.05# ./configure --with-openssl=/usr/local/ssl \
              --enable-threads \
              --enable-ipv6
\
              --with-randomdev=/dev/random \
              --with-libtool \
              --with-gnu-ld
2>&1|tee configure.log
※/dev/randomをSolarisで使うにはSolaris8では112438-01のパッチを当てておく。
※ipv6が対応していないOSではつけない。
※sslは最近では普通に入ってると思うけど、入ってないときはオプションはつけない
※libtoolやGNU ldは入ってない場合はオプションをつけない。
※theadsはとりあえずSolarisでコンパイルするのでつけてみた。Linuxで
マルチスレッディングに対応しているかどうかわかる場合はつけるべし。


bash-2.05# make 2>&1|tee make.log
bash-2.05# make install 2>&1|tee make_install.log

【設定】
構築するdnsはjinjin.comというドメインのdnsサーバとしましょう!
ドメイン:jinjin.com
IPアドレス:192.168.128.13

・上位DNS:203.139.161.37(ns-os001.ocn.ad.jp)
・メールサーバ:192.168.128.13(home3.jinjin.com)
・wwwサーバ:192.168.128.13(home3.jinjin.com)

ようはやっぱり設定が一番の難関でしょう。
初心者にとっては結構分かりにくいものです。
今回は初心者向きではないかもしれませんが、optionsの設定を
代表的なものを使ってみたいと思います。

allow-transfer (ゾーン転送を許可するホストを限定できる)
allow-query (DNS参照を許可するホストを限定できる)
allow-recursion(再帰的な問合わせも禁止します。これによりキャッシュ汚染攻撃
              (cache poisoning attack: 間違ったデータをサーバに送りつけること) の危険性が減らせます。 )

blackhole (あらかじめ問い合わせを無視するホストを限定)
今回はこのアクセス制御を用いて内部からの問い合わせだけ許可するようにします。
logging (ログの細かな設定をします)
これぐらいちょっと使ってみようかと思います。

・用意するファイル一覧
/var/named/localhost.rev
/var/named/localhost.zone
/var/named/jinjin.com.zone
/var/named/jinjin.com.rev
/var/named/named.root
/etc/named.conf

とりあえずやってみましょう!

bash-2.05# mkdir /var/named
bash-2.05# cd /var/named

注意事項).NSレコードの前には空白かTABがないとチェックをしたときにNSレコードが無いと怒られてしまう。
       一応気持ちが悪いので空白かTABをいれてチェックの時にエラーが出ないようにしておこう。


●ローカルホスト正引きファイル

bash-2.05# vi localhost.zone
; localhost.
$TTL 3600
@ in soa localhost. postmaster.localhost. (
2001091801 ;serial
3600 ;refresh
1800 ;retry
604800 ;expiration
3600 ) ;minimum
;
  in ns localhost.
in a 127.0.0.1
構文エラーがないかチェック
bash-2.05# /usr/local/sbin/named-checkzone localhost /var/named/localhost.zone
zone ゾーン名/IN: loaded seria シリアル番号
OK

※named-checkzone使い方
  named-checkzone ゾーン名(named.confで指定するzoneの名前) ゾーンファイル

●ローカルホスト逆引きファイル
bash-2.05# vi localhost.rev
; 0.0.127.in-addr.arpa
$TTL 3600
@ in soa localhost. postmaster.localhost. (
2001091701 ;serial
3600 ;refresh
1800 ;retry
604800 ;expiration
3600 ) ;minimum

  in ns localhost.
1 in ptr localhost.
構文エラーがないかチェック
bash-2.05# /usr/local/sbin/named-checkzone 0.0.127.in-addr.arpa /var/named/localhost.rev
zone ゾーン名/IN: loaded seria シリアル番号
OK

●ドメインの正引きファイル
bash-2.05# vi jinjin.com.zone
; jinjin.com.
$TTL 3600
@ in soa home3.jinjin.com. postmaster.jinjin.com. (
2001091701 ;serial
3600 ;refresh
1800 ;retry
604800 ;expiration
3600 ) ;minimum
;
     in ns home3.jinjin.com.
     in ns ns-os001.ocn.ad.jp.
home  in a 192.168.128.11
home2 in a 192.168.128.12
home3 in a 192.168.128.13
home4 in a 192.168.128.14
home5 in a 192.168.128.15
jinjin.com. in mx 10 home3.jinjin.com.
www in cname home3.jinjin.com.
ftp in cname home3.jinjin.com.
構文エラーがないかチェック
bash-2.05# /usr/local/sbin/named-checkzone jinjin.com /var/named/jinjin.com.zone
zone ゾーン名/IN: loaded seria シリアル番号
OK

●ドメインの逆引きファイル
bash-2.05# vi jinjin.com.rev
; 128.168.192.in-addr.arpa
$TTL 3600
@ in soa home3.jinjin.com. postmaster.jinjin.com. (
2000040101 ;serial
3600 ;refresh
1800 ;retry
604800 ;expiration
3600 ) ;minimum
;
  in ns home3.jinjin.com.
  in ns ns-os001.ocn.ad.jp.
11 in ptr home.jinjin.com.
12 in ptr home2.jinjin.com.
13 in ptr home3.jinjin.com.
14 in ptr home4.jinjin.com.

15 in ptr home5.jinjin.com.
構文エラーがないかチェック
bash-2.05# /usr/local/sbin/named-checkzone 128.168.192.in.addr.arpa /var/named/jinjin.com.rev
zone ゾーン名/IN: loaded seria シリアル番号
OK

●ルートキャッシュファイル
ftp://rs.internic.net/domain/
から最新版のnamed.rootをダウンロードしてくる。
bash-2.05# vi named.root

●rndc.keyの作成
bash-2.05# /usr/local/sbin/rndc-confgen -a
start typingと出たらとりあえずキーボードたたきまくりましょう!
※Solaris8の場合112438-01のパッチをあてていると特に連打作業は必要ありません。
You must use the keyboard to create entropy, since your system is lacking
/dev/random (or equivalent)

start typing:
...............................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
stop typing.
タイピングが終わってプロンプトが返ってきたら、
bash-2.05# ls -l /etc/rndc.key
bash-2.05# cat /etc/rndc.key
key "rndc-key" {
algorithm hmac-md5;
secret "7HTym7dBZ77QsFX5Zkelmw==";
};
bash-2.05# chown bind:bind /etc/rndc.key

このファイルはopensslを組み込んでdnssecでコンパイルしているので有効になる。
このrndc.keyファイルを作らなくても/var/adm/messagesに起動時にrndc.keyがないという
警告をはくだけでnamed自体の起動は可能である。
また作成したrndc.keyファイルは勝手に起動時に/etc/rndc.keyを読みにいくのでキーの位置を変えずに
デフォルトの位置で使用する場合は特にnamed.confに記述する必要はない。

●bindの設定ファイル
bash-2.05# vi /etc/named.conf
acl ipasec {
192.168.128.0/24;
127.0.0.1;
};
acl blacklist{
172.16.2.0/24;
192.168.128.30;
};
options {
directory "/var/named";
pid-file "/var/named/named.pid";
query-source address * port 53;
allow-transfer { ipasec; };
allow-query { ipsec; };
allow-recursion { ipasec; };
blackhole { blacklist; };
auth-nxdomain yes;  #auth-nxdomain' option is now 'no'というエラーが出るときなどは明示的にyesにしてあげます。
version "";       #バージョン情報を出さないようにする。
};

zone "." {
type hint;
file "named.root";
};

zone "localhost" {
type master;
file "localhost.zone";
};

zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
};

zone "jinjin.com" {
;もしこのゾーンの情報を外部にも公開したいのであれば
;allow-query { any; };をつけるとこのzone部分だけどこからでも参照できるようになります。

type master;
file "jinjin.com.zone";
};

zone "128.168.192.in-addr.arpa" {
type master;
file "jinjin.com.rev";
};
logging{
channel config_debug{
file "/var/named/log/config_debug.log" versions 5 size 10m;
severity debug 3;
print-category yes;
print-severity yes;
print-time yes;
};


channel xfer-in_debug{
file "/var/named/log/xfer-in_debug.log" versions 5 size 10m;
severity debug 3;
print-category yes;
print-severity yes;
print-time yes;
};

channel xfer-out_debug{
file "/var/named/log/xfer-out_debug.log" versions 5 size 10m;
severity debug 3;
print-category yes;
print-severity yes;
print-time yes;
};


channel notify_debug{
file "/var/named/log/notify_debug.log" versions 5 size 10m;
severity debug 3;
print-category yes;
print-severity yes;
print-time yes;
};

channel security_debug{
file "/var/named/log/security_debug.log" versions 5 size 10m;
severity debug 3;
print-category yes;
print-severity yes;
print-time yes;
};


category config { config_debug; };
category xfer-in { xfer-in_debug; };
category xfer-out { xfer-out_debug; };
category notify { notify_debug; };
category security { security_debug; };

};
構文エラーがないかチェック
bash-2.05# /usr/local/sbin/named-checkconf /etc/named.conf

・ログファイルの保存場所の作成
bash-2.05# mkdir /var/named/log

【リゾルバの設定】
bash-2.05# vi /etc/resolv.conf
domain jinjin.com
nameserver 192.168.128.4
nameserver 203.139.161.37
bash-2.05# vi /etc/nsswitch.conf
hosts: dns files

【起動ユーザの作成】
・namedを起動するユーザ・グループの作成
・最後に/var/namedをbindユーザに変更します。

# groupadd bind;useradd -c "bind user" -g bind -d /var/named -s /usr/bin/false bind
# chown -R bind:bind /var/named

【起動確認】
一度動くかどうか動作確認してみます。
・違うターミナルでtail -f /var/adm/messages
・/usr/local/sbin/named -u bind
もしもエラーがあると今までのv8以前のようにエラーのまま起動することはありません。
-uオプションでbindユーザで起動しています。


ここで本当に動いているかどうか確認します。

■正引きの確認
bash-2.05# host home3.jinjin.com
home3.jinjin.com. has address 192.168.128.13

■逆引きの確認
bash-2.05# host 192.168.128.14
14.128.168.192.in-addr.arpa. domain name pointer home4.jinjin.com.

■mxレコード確認
bash-2.05# host -t mx jinjin.com
jinjin.com. mail is handled by 10 home3.jinjin.com.

■cnameレコードの確認
bash-2.05# host -t cname www.jinjin.com
www.jinjin.com. is an alias for home3.jinjin.com.

どやらOKのようですね。
これでDNSはうごいていますね。


【自動起動設定】
システムブート時に自動でbindがあがるように設定しておきましょう。

●solarisの場合
bash-2.05# vi /etc/rc2.d/S72inetsvc
オリジナル
77if [ -f /usr/sbin/in.named -a -f /etc/named.conf ]; then
78 echo 'starting internet domain name server.'
79 /usr/sbin/in.named &
80fi
↓変更
変更後
77if [ -f /usr/local/sbin/named -a -f /etc/named.conf ]; then
78 echo 'starting internet domain name server.'
79 /usr/local/sbin/named -u bind &
80fi


●Redhat7.1Jの場合
※ソースからインストールした場合はrpm版と場所が違うので
起動ファイルはrpm版のものを使ってもいいですがバイナリの場所だけ
ちゃんと書き換えて使用してください。

/etc/init.d/named
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
[ "${NETWORKING}" = "no" ] && exit 0
[ -f /etc/sysconfig/named ] && . /etc/sysconfig/named
[ -f /usr/local/sbin/named ] || exit 0
[ -f /etc/named.conf ] || exit 0
RETVAL=0
prog="named"

start() {
# Start daemons.
echo -n $"Starting $prog: "
if [ -n "${ROOTDIR}" -a "x${ROOTDIR}" != "x/" ]; then
OPTIONS="${OPTIONS} -t ${ROOTDIR}"
fi
daemon named -u bind ${OPTIONS}
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/named
echo
return $RETVAL
}
stop() {
# Stop daemons.
echo -n $"Stopping $prog: "
killproc named
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/named
echo
return $RETVAL
}
rhstatus() {
/usr/local/sbin/rndc status
return $?
}
restart() {
stop
start
}
reload() {
/usr/local/sbin/rndc reload >/dev/null 2>&1 || /usr/bin/killall -HUP named
return $?
}
probe() {
# named knows how to reload intelligently; we don't want linuxconf
# to offer to restart every time
/usr/local/sbin/rndc reload >/dev/null 2>&1 || echo start
return $?
}

case "$1" in
start)
start
;;
stop)
stop
;;
status)
rhstatus
;;
restart)
restart
;;
condrestart)
[ -f /var/lock/subsys/named ] && restart
;;
reload)
reload
;;
probe)
probe
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|probe}"
exit 1
esac

exit $?
以上でDNSサーバとしての機能するようになったはずですが
namedの起動が昔のbind8時代のようにndcコマンドで管理できると楽です。
そのやり方が以下のようになります。

【rndcコマンドへの対応】
※バージョンが9になってndcコマンドはありません。
その代わりrndcコマンドが使えるようになっています。
しかし、上記のようなインストールだけではrndcコマンドは
使うことができません。
以下のようにして使えるようにすることにします。


●共通鍵の作成
# cd /usr/local/sbin
# ./dnssec-keygen -a HMAC-MD5 -b 512 -n HOST home3
 ※最後の「home3」はホスト名のこと
You must use the keyboard to create entropy, since your system is lacking
/dev/random (or equivalent)

start typing:
...............................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
...........................
stop typing.
Khome3.+157+41729
# ls -l K*
-rw------- 1 root other 114 Jan 20 15:05 Khome3.+157+41729.key
-rw------- 1 root other 145 Jan 20 15:05 Khome3.+157+41729.private
2つのファイルが作成されています。
この中に共通鍵の文字列が入っています。

●rndc.confの設定
※テンプレートがソースディレクトリのbin/rndcの中に入っているのを使います。
# cp /usr/local/arch/bind/bind-9.3.0rc1/bin/rndc/rndc.conf /etc/rndc.conf
options {
default-server localhost;
default-key "home3"; 
#dnssec-keygenの際にHOSTで指定した名前
};

server 127.0.0.1{
key "home3";      
#dnssec-keygenの際にHOSTで指定した名前
};

key "home3" {      #dnssec-keygenの際にHOSTで指定した名前
algorithm hmac-md5;
secret "B4zVQWMZKcTEYp8kOKhvL5wr2sd8fCeSeBYldNYmeup9hNLnqSRsGoFQ
1iau7wjLr6Z0LeK/DPCoGK/1GCEmKw==";  

※改行はなしでdnssec-keygenで作ったファイルの中のkeyをコピーしてくる

};

●named.confの設定
key "home3" {
algorithm hmac-md5;
secret "B4zVQWMZKcTEYp8kOKhvL5wr2sd8fCeSeBYldNYmeup9hNLnqSRsGoFQ1iau7wjL
6Z0LeK/DPCoGK/1GCEmKw=="; 
※改行はなしでdnssec-keygenで作ったファイルの中のkeyを
};

controls {
inet 127.0.0.1 allow { 127.0.0.1; } keys
{ "home3"; };
};
この数行を追加しておきましょう。

たったこれだけでrndcコマンドが使えるようになります。
では実際に試して見ます。

実際に今namedが動いているようであればデーモンを再起動してください。
# kill namedのプロセス番号
# /usr/local/sbin/named -u bind &

# /usr/local/sbin/rndc -s 127.0.0.1 status
number of zones: 5
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is OFF
server is up and running
実際に使えるコマンドは
# /usr/local/sbin/rndc -help
/usr/local/sbin/rndc: illegal option -- h
Usage: rndc [-c config] [-s server] [-p port] [-y key] [-V] command

コマンドの使い方:

reload      設定ファイルとゾーンファイルを再読み込みします。
reload zone [class [view]]
          指定したゾーンを再読み込みします。
refresh zone [class [view]]
          ゾーンのリフレッシュを今すぐします。
reconfig     設定ファイルと新しいゾーンのみ読み込みなおします。
stats       サーバの状態をファイルに書き出します。
querylog     クエリーのロギングをONにします。
dumpdb     named_dump.dbのようなファイルにキャッシュをダンプします。
stop       マスターファイルへの更新を保存し、サーバを停止します。
halt        更新途中であっても強制的にサーバを停止します。
trace       デバッグレベルをひとつ上に上げます。
trace level   デバッグレベルを変更します。
notrace     デバッグレベルを0にします。
flush       サーバのすべてのキャッシュをフラッシュします。
flush [view]   サーバのviewキャッシュをフラッシュします。
status      サーバの状態を表示します。
*restart     サーバの再起動。

* == まだ使えません。
Version: 9.3.0rc1
悲しいかな一番使いたいrestartがこのバージョンでは使えないようなので
次期バージョンに期待しましょう。
bind9インストール(2001.11.23)