djbdnsでDNSサーバを作る
設計
一般的にはDNSサーバを一台のホスト上で実現するには、外側に向けているインターフェースで外部からのDNS要求に応じるようなDNSサーバ(tinydns)を動かし、ループバックインターフェース(127.0.0.1)でキャッシュサーバを動かすと思います。しかし、ここで実現したいことは、ファイアウォールの内部の名前解決を内部ネットワーク向けてサービスをしたいということで以下の考え方でdjbdnsを設定しました(外部に向けてのDNSサービスは動かしていません)
------------+----+----+--------+-----+-----+192.168.1.1(dnscash)
--Internet--|DSLモデム|--------|FreeBSD BOX|-----LAN-----CLIENTS
------------+----+----+--------+-----+-----+
-------------------------------lo:127.0.0.1(tinydns)
■LAN内のマシンは192.168.1.1で動いているdnscashに名前解決をしようとする。ここでdnscashは192.168.1.0/24に対して接続許可を与えてやる必要がある。
■FreeBSD BOXのlo0ではtinydnsが内部ネットワークのゾーン情報を持っている。
■dnscashは内部の名前解決ならば127.0.0.1に対してクエリを出す。
■外部の名前解決ならばプロバイダのdnsサーバにフォワードして名前解決を行う。
daemontoolsのインストール
まず、daemontoolsをインストールします。djbツール群のひとつでデーモンの起動やロギングなどを管理するものです。FreeBSDではportsになっているので、portsからインストールします。
# cd /usr/ports/sysutils/daemontools
# make install
これで、daemontools-0.76(2002/05/14現在)がインストールされます。djbのツール群のインストールディレクトリはなんだか変、なのですが、まあいいや、と/serviceを作ります(portsに付属してくる起動スクリプトでは/var/serviceが想定されています)。
# mkdir /service
/usr/local/etc/rc.dにsvscan.sh.sampleがコピーされるので、私の場合はSVDIRを/serviceに変更してsvscan.shとして、実行権限を与えます。
# vi svscan.sh.sample
# mv svacan.sh.sample svscan.sh
# chmod +x svscan.sh
svscanを起動します。
# /usr/local/etc/rc.d/svscan.sh start
svscanは/serviceにリンクを張ったデーモンを監視します。落ちた場合は自動的に再起動しようとします。
# svc [コマンド] デーモン
で制御します。詳しくはman svcを参照してください。
djbdnsのインストール
ユーザの作成
まず、daemon及びloggerのためのユーザを作成します。tinydns、dnscashのためにそれぞれ同名のユーザを作成し、ログ記録のためにdnslogというユーザを作成します。グループはdnsとします。uid、gidは適宜重複しないようにしてくださいね。
# vipw
dnscache:*:71:71::0:0:DNS cache:/noexistent:/sbin/nologin
dnslog:*:72:71::0:0:DNS log:/noexistent:/sbin/nologin
tinydns:*:73:71::0:0:DNS log:/noexistent:/sbin/nologin
# vi /etc/group
dns:*:71:
djbdnsのインストール
portsを利用します。portsのMakefileを読めばわかりますが、WITH_IPV6をつけてmakeすると、http://www.fefe.de/dns/にあるIPv6化パッチがあたってからコンパイルされます。
# cd /usr/ports/net/djbdns
# make WITH_IPV6=1
tinydnsの設定
さて、始めに挙げたようにtinydnsを127.0.0.1で動かす設定を行います。設定にはtinydns-confを使います。
tinydns-conf 起動ユーザ ログのためのユーザ 設定ファイルの場所 listenするIP Addr
私の場合、
# tinydns-conf tinydns dnslog /usr/local/etc/tinydns 127.0.0.1
これで/usr/local/etc/tinydns($tinydnsとします)内に設定がインストールされます。
# cd $tinydns
# less env/IP
127.0.0.1
ゾーンの設定はrootディレクトリ内で行います。$tinydns/root内にはadd-nsやadd-hostなどのコマンドがあり、これを利用してゾーンの設定を行うのです。なお、中身を見てみればわかりますが、これはtinydns-editというプログラムを呼び出しているだけなので、tinydns-editを直接実行しても良いでしょう。
# cd root
# ./add-ns f-bell.net 192.168.1.1 #nsレコード
# ./add-ns 1.168.192.in-addr.arpa 192.168.1.1 #nsレコード
# ./add-host leon.f-bell.net 192.168.1.1 #aレコード、逆引きも設定される
-------snip! hostの分だけ繰り返す------
# ./add-mx f-bell.net 192.168.1.2 #mxレコード
# ./add-alias ftp.f-bell.net 192.168.1.3 #cname
# make
/usr/local/bin/tinydns-data
#
こんな感じです。最後にmakeするのを忘れないでください。$tinydns/root/dataに記録され、$tinydns/root/data.cdbにバイナリでデータベースが保存されます。なお、$tinydns/root/dataを手で書いてmakeしてもかまいません。
このままではmxレコードがa.mx.f-bell.netという感じに設定されてしまうので、それをmail.f-bell.netに変えます。
# vi data
=mail.f-bell.net:192.168.1.2:86400
@f-bell.net::mail.f-bell.net:1:86400
# make
後ろから二つ目の「1」はmxレコードのpreffixです。
これでtinydnsの設定は終わりです。最後にsvcが自動的にdaemonを起動するように/serviceにリンクを張ります。
# ln -s /usr/local/etc/tinydns /service/tinydns
dnscashの設定
tinydnsと似たような感じで設定ファイル群をインストールします。
# dnscache-conf dnscache dnslog /usr/local/etc/dnscache 192.168.1.1
これで/usr/local/etc/dnscashe($dnscashとします)以下に設定ファイル群がインストールされます。まず、デフォルトではdnscashはそのホストからの接続のみ応答するようになっているので、LAN(192.168.1.0/24)からの接続を許可する設定を加えます。
# cd $dnscash/root/ip
# touch 192.168.1
次にf-bell.netと1.168.192.in-addr.arpaについては127.0.0.1に問い合わせるようにします。
# cd $dnscash/root/servers
# echo 127.0.0.1 > f-bell.net
# echo 127.0.0.1 > 1.168.192.in-addr.arpa
自ドメイン以外の名前の解決をプロバイダのDNSサーバに問い合わせするように設定します。
# echo 1 > $dnscache/env/FORWARDONLY
# vi $dnscache/root/servers/@
xxx.xxx.xxx.xxx #プロバイダのDNSサーバ。列挙するときは改行で。
yyy.yyy.yyy.yyy
#
これでdnscacheの設定は終わりです。最後にsvcが自動的にdaemonを起動するように/serviceにリンクを張ります。
# ln -s /usr/local/etc/dnscache /service/dnscache
/etc/resolv.confには192.168.1.1を指定します。LAN内のクライアントに対してもdnsサーバは192.168.1.1を設定します。
なお、tinydnsでは自動的にlocalhostが127.0.0.1、ns.hoge.netが動かしているipに設定されるようです。ゾーンファイルにはlocalhostの記述もnsの記述もないのですが、
# dnsip localhost
127.0.0.1
# dnsip ns.f-bell.net
192.168.1.1
#
こんな感じで帰ってきます。
