BIND
Linux上にDNSサーバ(名前解決)を構築する為のミドルウェア。
0. アンインストール
インストール済みのBINDが残ったまま新しいBINDを入れると、
後に相性問題とかで面倒くさい事になるので、事前にアンインストールをしておく。
$ yum -y remove bind bind-libs bind-chroot bind-devel bind-devel $ ldconfig
1. ビルド・インストール
事前に最新版のBINDをダウンロードしておく事。
今回はOpenSSLをソースからインストールしてある事と、BINDをchroot環境で動作させる事を前提とする。
また、ビルド前の./configureかける時に、普通はオプションとかを直接打ち込むのだが、
今回は長めのオプションを指定するのでオプションコマンドを別ファイルにしておく。
$ tar zxvf bind-9.10.1.tar.gz $ echo "--prefix=/usr/local/bind-9.10.1 --with-openssl=/usr/local/openssl --enable-threads --enable-ipv6 --with-pic --disable-static --disable-openssl-version-check --disable-isc-spnego --enable-largefile --enable-chroot" > ./configure.option $ cd bind-9.10.1 $ ./configure `cat ../configure.option` $ make $ make install $ cd /usr/local $ ln -s /usr/local/bind-9.10.1 ./bind
2. ユーザとディレクトリの作成
ソースからインストールした場合、BINDの実行ユーザやchrootディレクトリも自作する必要がある。
さらに言うと、initファイルやnamed.confも自作する必要がある。
※コンフィグのひな形はソース内の"FAQ"に書いてあるが、完成形コンフィグではないので移植不可能
今回は以下の環境を想定して設定を行う。
また、ディレクトリはchroot化しなかった場合と同じ内部構成とする。
BIND(chroot)ディレクトリ:/var/named/chroot BIND実行ユーザ:named BIND実行グループ:named BIND設定ファイル:/var/named/chroot/etc/named.conf
$ mkdir /var/named $ groupadd named $ useradd -g named -d /var/named -s /sbin/nologin named $ rm -rf /var/named/* && rm -rf /named/.* $ chmod 750 /var/named $ chown root.named /var/named
$ cd /var/named $ mkdir -p ./chroot/dev ./chroot/etc ./chroot/var $ cd ./chroot/dev $ mknod -m 644 ./null c 1 3 $ mknod -m 644 ./zero c 1 5 $ mknod -m 644 ./full c 1 7 $ mknod -m 644 ./random c 1 8 $ mknod -m 644 ./urandom c 1 9 $ cd ../var $ mkdir -p ./cache/bind ./log ./named/data ./named/dynamic ./run/named $ chown named.named ./log ./run/named $ chown -R named.named ./named
3. 設定ファイル
基本的に1から作成する必要がある。BIND側でテンプレを入れてくれればいいのに...
下記では、必須のzoneファイルのみをメモ。
※1. named.confは/var/named/chroot/etc/named.confに設置
※2. named.confの中身やzoneの書き方は他のサイトを参照
$ /usr/local/bind/bin/dig . ns @202.12.27.33 +bufsize=1024 > /var/named/chroot/var/named/named.ca $ cp /etc/localtime /var/named/chroot/etc/
$ vi /var/named/chroot/var/named/named.empty -------------------------------------------------- $TTL 3H @ IN SOA @ rname.invalid. ( 0 ; serial 1D ; refresh 1H ; retry 1W ; expire 3H ) ; minimum IN NS localhost. IN A 127.0.0.1 IN AAAA ::1
$ vi /var/named/chroot/var/named/named.localhost -------------------------------------------------- $TTL 1D @ IN SOA @ rname.invalid. ( 0 ; serial 1D ; refresh 1H ; retry 1W ; expire 3H ) ; minimum IN NS localhost. IN A 127.0.0.1 IN AAAA ::1
$ vi /var/named/chroot/var/named/named.loopback -------------------------------------------------- $TTL 1D @ IN SOA @ rname.invalid. ( 0 ; serial 1D ; refresh 1H ; retry 1W ; expire 3H ) ; minimum IN NS localhost. IN A 127.0.0.1 IN AAAA ::1 IN PTR localhost.
$ vi /var/named/chroot/var/named/named.rfc1912.zones -------------------------------------------------- zone "localhost.localdomain" IN { type master; file "named.localhost"; allow-update { none; }; }; zone "localhost" IN { type master; file "named.localhost"; allow-update { none; }; }; zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" IN { type master; file "named.loopback"; allow-update { none; }; }; zone "1.0.0.127.in-addr.arpa" IN { type master; file "named.loopback"; allow-update { none; }; }; zone "0.in-addr.arpa" IN { type master; file "named.empty"; allow-update { none; }; };
$ vi /etc/init.d/named -------------------------------------------------- #!/bin/sh # # named This shell script takes care of starting and stopping # named (BIND DNS server). # # chkconfig: 345 55 45 # description: named (BIND) is a Domain Name Server (DNS) # that is used to resolve host names to IP addresses. # probe: true # BIND configuration BIND_ROOT="/var/named/chroot" BIND_CONFIG="/etc/named.conf" BIND_USER="named" BIND_OPTIONS="-u ${BIND_USER} -c ${BIND_CONFIG} -t ${BIND_ROOT}" BIND_PIDFILE="${BIND_ROOT}/var/run/named/named.pid" # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ ${NETWORKING} = "no" ] && exit 0 [ -f /usr/local/bind/sbin/named ] || exit 0 [ -f ${BIND_ROOT}${BIND_CONFIG} ] || exit 0 # See how we were called. case "$1" in start) # Start BIND. echo -n "Starting bind: " if [ -e /var/lock/subsys/named ] ; then echo "BIND running" exit 0 else daemon /usr/local/bind/sbin/named ${BIND_OPTIONS} echo touch /var/lock/subsys/named fi ;; stop) # Stop daemons. echo -n "Shutting down bind: " killproc -p ${BIND_PIDFILE} for PID in `ps -ef | grep "[n]amed.*${BIND_USER}" | awk '{print $2}'` do kill ${PID} done rm -f /var/lock/subsys/named echo ;; status) status named exit $? ;; restart) $0 stop $0 start exit $? ;; *) echo "Usage: named {start|stop|restart|status}" exit 1 esac exit 0
4. 起動準備
BINDを起動させる時に/etcからBINDのコンフィグを読み込む必要がある為、シンボリックリンクを張る
ついでにパーミッション操作も行い、読み取り権限の整理をする
$ cd /etc $ ln -s /var/named/chroot/etc/named.conf . $ chmod 755 /etc/init.d/named $ chown root.root /etc/init.d/named $ chkconfig --add named $ chkconfig named on
次にBINDとrndcの連携に必要な、rndc.confを作成する
通常は、rndc.confの作成に/dev/randomの乱数を利用するのだが、
乱数から鍵を作成するのは時間がかかる為、キーボード連打によって疑似乱数を作成し鍵として利用する。
$ /usr/local/bind/sbin/rndc-confgen -a -b 512 -k rndc-key -r keyboard start typing: 『ひたすら、キーボードを叩き続ける』 stop typing. wrote key file "/usr/local/bind-9.10.1/etc/rndc.key"
$ cd /var/named/chroot/etc/ $ mv /usr/local/bind/etc/rndc.key . $ cp rndc.key rndc.conf $ chmod 640 ./rndc.key && chown root.named ./rndc.key $ chmod 600 ./rndc.conf && chown root.root ./rndc.conf $ ln -s /var/named/chroot/etc/rndc.key /etc/rndc.key $ ln -s /var/named/chroot/etc/rndc.conf /etc/rndc.conf -------------------------------------------------- $ vi ./rndc.conf ※ 以下を追記 options { default-key "rndc-key"; default-server localhost; default-port 953; };
最後に起動テストを実施する。
initから起動した場合はエラーログが出力されない為、
最初に起動コマンドを直打ちし、無事起動したらプロセスをkillした上でinitからテストする
※起動コマンド直打ち $ /usr/local/bind/sbin/named -u named -c /etc/named.conf -t /var/named/chroot ※initスクリプトからの起動 $ /etc/init.d/named start
5. ログローテート
BINDはログが肥大化しやすいので、ちゃんとローテートをかける。
ローテートファイルの書式は色々あるので適当にググって調べる。
$ ln -s /var/named/chroot/var/log /var/log/named $ vi /etc/logrotate.d/named -------------------------------------------------- /var/log/named/named.log { daily compress rotate 30 missingok notifempty sharedscripts delaycompress create 0644 named named postrotate /etc/init.d/named restart > /dev/null 2>/dev/null || true endscript }
1. DSO_load error
chroot環境でBINDを起動すると、/var/log/messagesに以下のログが出て起動出来ない場合がある
DSO support routines:DSO_load:could not load the shared library:dso_lib.c:244: engine routines:DYNAMIC_LOAD:dso not found:eng_dyn.c:450: engine routines:ENGINE_by_id:no such engine:eng_list.c:418:id=gost
chroot環境の場合、DNSSECに必要なSSLライブラリもchroot環境下を参照してしまう。
結果、存在しない『{$CHROOT_DIR}/usr/local/openssl/lib』を見に行き、DSO_load errorが出てしまう。
解決方法としては
1. /usr/local/openssl/lib/engines/*をchroot環境下へコピー 2. chrootを諦める
のどちらかを実施する必要がある。
ちなみに、シンボリックリンクをchroot内のディレクトリから実ディレクトリへ張った場合、
"chroot環境下からのシンボリックリンク"とBINDに解釈される為、
$ ln -s /usr/local/openssl /var/chroot/named/usr/openssl
にしても、実際は
$ ln -s ${CHROOT_DIR}/usr/local/openssl ${CHROOT_DIR}/var/chroot/named/usr/openssl
へ張っている事と同じとなり起動出来なくなる。
1の方法で解決する場合、
$ mkdir -p ${CHROOT_DIR}/usr/local/openssl/lib/engines $ cp -a /usr/local/openssl/lib/engines/* ${CHROOT_DIR}/usr/local/openssl/lib/engines/ $ chown root.root ${CHROOT_DIR}/usr/local/openssl/lib/engines/*
を実行し、実ファイルを移動させる必要がある。
また、上記コマンドで使用しているディレクトリ名opensslは
"シンボリックリンクでないOpenSSLのディレクトリ名"と同じ物を指定する必要がある。
つまり、OpenSSLの実ディレクトリが/usr/local/openssl-1.0.0だとすると、chroot環境下のOpenSSLディレクトリも、
$ mkdir -p ${CHROOT_DIR}/usr/local/openssl-1.0.0
とする必要がある。
それでも起動出来ない場合は、OSレベルのライブラリディレクトリ(/lib , /lib64)を作成し、
OpenSSL環境下のライブラリをそっちへ移動してみる。
2. ログのタイムスタンプ
chroot環境では、BINDから出力されるログのタイムスタンプがUTCのままになる事がある
これを、JSTにするには"localtime"設定もchroot下にコピーする必要がある
$ cp /etc/localtime ${CHROOT_DIR}/etc/localtime $ chown root.root ${CHROOT_DIR}/etc/localtime $ chmod 644 ${CHROOT_DIR}/etc/localtime $ /etc/init.d/named restart