連載
» 2004年05月15日 00時00分 UPDATE

実用 BIND 9で作るDNSサーバ(最終回):BIND 9を徹底活用するためのTips集 (1/2)

BINDには、運用・管理に使える標準機能あるいは外部ツールがある。これらを利用して、BINDをとことん活用しよう。(編集局)

[鶴長鎮一,@IT]

 本連載を締めくくるに当たり、これまでに紹介し切れなかったことをTipsとして紹介します。

ゾーンデータをRDBMSで管理

 DNSの規模が大きくなると、情報の追加や削除が簡単で、更新・検索を確実かつ高速に処理できるシステムへゾーン情報を移行する必要に迫られます。

sdbとは

 BIND 9には、そのような事態を想定してsdbインターフェイス(Simplified Database Interface)が提供されています。sdbインターフェイスを利用することで、データベースに限らずさまざまなシステムをゾーン情報のバックエンドに利用できます。ソース中のcontrib/sdbには、Berkeley DBやLDAP、PostgreSQLなどのsdbドライバが用意されているので、規模や用途に合わせて適切なドライバを選択しましょう。

 ただし、「Simplified」とうたっているように、通常のゾーンファイルでできていたことが、sdbインターフェイスを利用した場合でもそのまま実現できるとは限りません。ゾーン転送やDynamic DNS、DNSSECなど、いくつかの機能はドライバ依存のため実装されていません。

 ここでは、sdbの使用例として、MySQLをバックエンドに利用する方法を紹介します。MySQLについては、インストール方法も含めてエンタープライズ市場に向かうMySQL 5.0快速MySQLでデータベースアプリ!を参照してください。

 なお、MySQLが動作しているホストにBINDをインストールする必要はありませんが、mysql.hやlibmysqlclient.soなどの開発環境を用意する必要があります。

MySQL用sdbドライバのインストール

 BIND 9のソースアーカイブにMySQLのsdbドライバは含まれていないため、別途用意します。以前はBind-Mysql Project(http://gw.netbastards.org/bm/)で公開されているものが利用されていましたが、これはすでに開発を終了しています。同sdbはbind-9.2.3でも利用可能ですが、将来性も考えてMySQL BIND SDB Driver(http://mysql-bind.sourceforge.net/)を利用します。

 パッチファイルが用意されていないため多少複雑な作業になりますが、順を追って見ていきましょう。

 http://sourceforge.net/projects/mysql-bind/からmysql-bind-0-1.tgzをダウンロードし、展開します。また、展開されたディレクトリの実行権限が外れているので修正します。

# wget http://twtelecom.dl.sourceforge.net/sourceforge/mysql-bind/mysql-bind-0-1.tgz
# tar xvfz mysql-bind-0-1.tgz
# chmod +x mysql-bind-0.1

 次に、BIND 9のソースをダウンロードして展開します。

# wget ftp://ftp.isc.org/isc/bind9/9.2.3/bind-9.2.3.tar.gz
# tar xvfz bind-9.2.3.tar.gz

 mysql-bind-0.1下のmysqldb.hとmysqldb.cを、それぞれbind-9.2.3/bin/named/includeとbind-9.2.3/bin/named下にコピーします。

# cp mysql-bind-0.1/mysqldb.h bind-9.2.3/bin/named/include/
# cp mysql-bind-0.1/mysqldb.c bind-9.2.3/bin/named/

 bind-9.2.3/bin/named/Makefile.inファイルを修正します。「mysql_config」実行時の--cflagsの値をDBDRIVER_INCLUDESに、--libsの値をDBDRIVER_LIBSに記入します。

(26行目)
#
# Add database drivers here.
#
DBDRIVER_OBJS = mysqldb.@O@
DBDRIVER_SRCS = mysqldb.c
DBDRIVER_INCLUDES = -I/usr/include/mysql -mcpu=i486 -fno-strength-reduce
DBDRIVER_LIBS = -L/usr/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -lc -lnss_files -lnss_dns -lresolv -lc -lnss_files -lnss_dns -lresolv
bind-9.2.3/bin/named/Makefile.in

 続いて、bind-9.2.3/bin/named/main.cファイルの以下の行を修正します。

(66行目)
/* #include "xxdb.h" */
    ↓
#include "mysqldb.h"

(546行目)
/* xxdb_init(); */
    ↓
mysqldb_init();

(560行目)
/* xxdb_clear(); */
    ↓
mysqldb_clear();
bind-9.2.3/bin/named/main.c

 ここからはBIND 9の通常インストールと同様の作業です。configure、make、make install、namedユーザーの作成、/var/named、/var/run/namedの順に実行します。

# ./configure
# make
# make install
# groupadd named
# useradd -g named -d /var/named -s /bin/false named
# mkdir /var/named/
# chown named.named /var/named/
# mkdir /var/run/named/
# chown named.named /var/run/named/

 ここまで終了したら、第2回を参考に、/etc/named.confと各ゾーンファイルをいったん用意します。

sdbの設定

 example.jpのゾーン情報にMySQL sdbドライバを組み込みます。ここではMySQLサーバとDNSサーバが同一ホストであるという前提で紹介しています。ホストが異なる場合は、以降の「localhost」を適宜サーバのアドレスに置き換えます。

 MySQLに次のデータベースとテーブルを作成し、namedユーザーへの権限を設定します。

MySQLサーバ :localhost
データベース :bind_mysql
テーブル :example_zone
データベース接続ユーザー(パスワード) :named(pass)
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| name   | varchar(255) | YES  |     | NULL    |       |
| ttl    | int(11)      | YES  |     | NULL    |       |
| rdtype | varchar(255) | YES  |     | NULL    |       |
| rdata  | varchar(255) | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
example_zoneの構成

 example_zoneテーブルでは、キーやインデックスを作成していません。必要なら適宜作成します。

 では具体的な手順です。まず、bind_mysqlデータベースを作成します。

# mysqladmin create bind_mysql

 次に、GRANTクエリー文でnamedユーザーへの権限を設定し、example_zoneテーブルを作成します。なお、作成に当たってはexample_zone.sqlファイルを使用することもできます。example_zone.sqlファイルを使用した場合、サンプルレコードも登録されます。

# mysql bind_mysql

mysql> GRANT ALL PRIVILEGES ON bind_mysql.* TO named@localhost
 IDENTIFIED BY 'pass';    #権限の設定
Query OK, 0 rows affected (0.20 sec)

mysql> CREATE TABLE example_zone (   #テーブルの作成
    ->   name varchar(255) default NULL,
    ->   ttl int(11) default NULL,
    ->   rdtype varchar(255) default NULL,
    ->   rdata varchar(255) default NULL
    -> );
Query OK, 0 rows affected (0.15 sec)

 example_zone.sqlファイルを使用する場合は、

# mysql bind_mysql < example_zone.sql

とします。

 example_zoneテーブルを作成したら、example_zone.sqlファイルを参考にSOA、NS、Aなどのレコードをデータベースに登録します。

mysql> select * from example_zone;  #レコードの表示(登録されている場合)
+-----------------+-------+--------+-----------------------------
------------------------+
| name            | ttl   | rdtype | rdata                       
                        |
+-----------------+-------+--------+-----------------------------
------------------------+
| example.jp      | 86400 | SOA    | example.jp. root.example.jp.
 2004042001 3H 2M 1W 1D |
| example.jp      | 86400 | NS     | dns.example.jp.             
                        |
| example.jp      | 86400 | MX     | 10 mail.example.jp.         
                        |
| dns.example.jp  | 86400 | A      | 192.168.1.11                
                        |
| mail.example.jp | 86400 | A      | 192.168.1.12                
                        |
| pc1.example.jp  | 86400 | A      | 192.168.1.13                
                        |
+-----------------+-------+--------+-----------------------------
------------------------+
5 rows in set (0.00 sec)
リスト1 折り返しなし表示

GRANT ALL PRIVILEGES ON bind_mysql.* TO named@localhost IDENTIFIED 
BY 'pass';

CREATE TABLE example_zone (
  name varchar(255) default NULL,
  ttl int(11) default NULL,
  rdtype varchar(255) default NULL,
  rdata varchar(255) default NULL
);

INSERT INTO example_zone VALUES ('example.jp','86400','SOA',
'example.jp. root.example.jp. 2004042001 3H 2M 1W 1D');
INSERT INTO example_zone VALUES ('example.jp', 86400, 'NS',
 'dns.example.jp.');
INSERT INTO example_zone VALUES ('example.jp', 86400, 'MX',
 '10 mail.example.jp.');
INSERT INTO example_zone VALUES ('dns.example.jp', 86400, 'A',
 '192.168.1.10');
INSERT INTO example_zone VALUES ('mail.example.jp', 86400, 'A',
 '192.168.1.12');
INSERT INTO example_zone VALUES ('pc1.example.jp', 86400, 'A',
 '192.168.1.13');
リスト2 折り返しなし表示
参考:example_zone.sql

 以上で、MySQL側の準備は終了です。

 BIND 9側の設定は単純です。通常のゾーンファイルを使用した場合との違いは、named.confのexample.jpゾーンの記述のみです。

(省略)
/* example.jpゾーンにMySQL sdbドライバを用いた場合 */

zone "example.jp" {
        type master;
        database "mysqldb bind_mysql example_zone localhost named
 named"; (1)
};

(省略)
/etc/named.conf

 (1)の書式は、

database "mysqldb データベース名 テーブル名 MySQLサーバ ユーザー名 パスワード";

です。mysqldbはMySQL用sdbドライバの指定です。

 準備が整ったら、namedを起動します。

# /usr/local/sbin/named -u named

 もし、

/usr/local/sbin/named: error while loading shared libraries: libmysqlclient.so.14: ...

のようなエラーが出る場合は、ldconfigを使ってlibmysqlclient.soを共有ライブラリに登録します。

(省略)
/usr/lib/mysql
/etc/ld.so.conf
注:ソースからインストールした場合は/usr/local/lib/mysql。

# ldconfig
参考:共有ライブラリをシステムに認識させるには

 /var/log/messageにエラーが出力されていないかを確認します。

loading zone: creating database: failure...

と表示される場合は、MySQLサーバとの接続を確認します。MySQLサーバ側のログを確認するには、快速MySQLでデータベースアプリ! 第13回中の「ロギング機能と動作ステータスの取得」を参照してください。

 共有ライブラリのバージョンの問題でSegmentation faultを起こす場合は、各ライブラリを最新版に更新します。

sdbの動作チェック

 正常に動作しているか否か、digを用い検証します。

# dig @127.0.0.1 pc1.example.jp a
(省略)
;; QUESTION SECTION:
;pc1.example.jp.                        IN      A
(省略)
;; ANSWER SECTION:
pc1.example.jp.         86400   IN      A       192.168.10.13
(省略)

 MySQLをBINDのバックエンドにした利点を確認しましょう。BIND 9を介さず、直接MySQLに対してレコードの更新を行います。

# mysql bind_mysql
mysql> UPDATE example_zone SET rdata = '192.168.1.14' WHERE
 name = 'pc1.example.jp'; ←IPアドレスをアップデート
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

# dig @127.0.0.1 pc1.example.jp a

;; ANSWER SECTION:
pc1.example.jp.         86400   IN      A       192.168.1.14 ←更新されている

 上記のように、ゾーン情報の変更が即座に反映されていることが分かります。

 また、JDBCやDBIなど、データベースが使えるさまざまなインターフェイス利用することで、Webを介したゾーン情報の更新などに活用できます。ただし、MySQL sdbドライバではDyanmic DNSやDNSSECが使用できず、ゾーン転送にも制限が付くため、利用に当たっては十分な検討が必要です。

 パフォーマンスは、ゾーン情報がどれだけキャッシュされるかが結果に大きく影響します。キャッシュされる割合が少ない場合はMySQL sdbドライバの方が効果的ですが、ゾーンレコードが数百、数千程度の場合は通常のゾーンファイルで管理した方が高速です。MySQL sdbドライバを使用した場合、named自体ではキャッシュが行われず、該当ゾーン情報のDNS問い合わせはすべてSQLクエリーに置き換わります。

 sdbインターフェイスの詳細については、ソース中のdoc/misc/sdbファイルを参照してください。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。