BIND 10 1.0.0ベータ版レビュー前編:BIND 10の紹介

BIND 10の開発プロジェクトは終了しました。(注記: 2014年9月)

BINDの次世代バージョンBIND 10 1.0.0のベータ版がISC(Internet Systems Consortium)から2012年12月20日にリリースされました。正式リリースは来年の1月か2月になると思われますが、現時点での状況を探ってみましょう。

なお、本記事は2回に分けて紹介します。

BIND 10の概要

まず、次の画面を見てください。BIND 10を権威サーバとして動かしているときのpsコマンドの出力結果です。

$ ps axf
  PID TTY      STAT   TIME COMMAND
21071 ?        Ss     0:00 /usr/local/sbin/bind10                              
21072 ?        S      0:00  \_ b10-sockcreator
21073 ?        S      0:00  \_ b10-msgq                                        
21074 ?        S      0:00  \_ b10-cfgmgr                                      
21075 ?        S      0:02  \_ b10-stats                                       
21076 ?        Sl     0:00  \_ b10-cmdctl                                      
21112 ?        Sl     0:00  \_ b10-zonemgr                                     
21113 ?        S      0:00  \_ b10-xfrin                                       
21114 ?        Sl     0:00  \_ b10-xfrout                                      
21115 ?        Sl     0:00  \_ b10-auth

次のBIND 9のpsコマンドの出力結果とはまったく違いますね。

$ ps axf
  PID TTY      STAT   TIME COMMAND
12085 ?        Ssl    0:02 /usr/sbin/named -u bind

BIND 10はBIND 9の単なるバージョンアップではなく、次世代のバージョンです。BIND 9ではnamedという1つのバイナリのモノリシックなアーキテクチャでしたが、BIND 10では先のpsコマンドの出力例からもわかるとおり、マスタープロセスから機能毎のコンポーネントを制御する今時のアーキテクチャになっています。BIND 9とはアーキテクチャが全く異なる別のソフトウェアであることがわかります。

このBIND 10の開発プロジェクトは公式には2009年4月1日に開始しました。5年計画で開発が進められており、現在は4年目の後半半ばに入っています。権威サーバとしての機能はほぼ完成しており、今回のリリースは権威サーバのベータ版という位置づけになります。フルサービスリゾルバの機能は現時点でも利用可能ですが、こちらは開発途中のものとなります。なお、現時点では開発途中ですが、DHCPv4サーバ、DHCPv6サーバのコンポーネントも含まれます。

余談ですが、マスコットキャラクタはBundy君です。

それではBIND 10の特徴を見ていきましょう。

アーキテクチャ

コンポーネント化

BIND 10の大きな特徴の1つはコンポーネント化にあります。権威サーバ、フルサービスリゾルバ、ゾーン転送など、各機能毎にコンポーネント化されており、別プロセスとして動作します。これにより、必要な機能だけを呼び出して利用することができるため、用途に応じてフットプリントを最適化することができます。

次の例はpsコマンドの出力例です。bind10というマスタープロセス(Boss(ボス)と呼んでいる)に各サービスが子プロセスとして動作しているのがわかります。ちなみに、b10-authが権威サーバ、b10-resolverがフルサービスリゾルバのプロセスです。

  PID TTY      STAT   TIME COMMAND
21071 ?        Ss     0:00 /usr/local/sbin/bind10                              
21072 ?        S      0:00  \_ b10-sockcreator
21073 ?        S      0:00  \_ b10-msgq                                        
21074 ?        S      0:00  \_ b10-cfgmgr                                      
21075 ?        S      0:02  \_ b10-stats                                       
21076 ?        Sl     0:00  \_ b10-cmdctl                                      
21112 ?        Sl     0:00  \_ b10-zonemgr                                     
21113 ?        S      0:00  \_ b10-xfrin                                       
21114 ?        Sl     0:00  \_ b10-xfrout                                      
21115 ?        Sl     0:00  \_ b10-auth
21116 ?        S      0:00  \_ b10-resolver

権威サーバとフルサービスリゾルバが別のサービスとして動作するため、権威サーバとフルサービスリゾルバを兼用できてしまうようなサービスができなくなります。これにより、兼用していることにより発生している様々な問題が減るのではないかと期待できます。

なお、権威サーバとリゾルバを別のサービスとして同居させることは可能です。例えば、ホスト自身のリゾルバ用として127.0.0.1や::1のようなループバックインターフェイスでフルサービスリゾルバのサービスを行い、ホストの外部からアクセスできるネットワークインターフェイスで権威サーバのサービスを行うといったことはできます。

なお、権威サーバもフルサービスリゾルバもデフォルトでは起動していません。明示的に起動する設定を行う必要があります。

各コンポーネントの説明

各コンポーネントの役割について簡単に紹介します。

b10-sockcreatorソケット作成デーモン。
root権限で動作し、ソケットを作成してソケットを必要とするデーモンに割り当てる。
b10-msgqコマンド チャネルのためのメッセージ ルーティング デーモン。
各プロセス間のメッセージを中継するメッセージバスの役割を持つ。
b10-cfgmgr設定マネージャ。
BIND 10のすべてのシステム設定を扱う。
設定用のデータベース(/var/bind10/b10-config.db)を扱うのもこのデーモン。
設定が変更されたときの通知も行う。
b10-stats統計収集デーモン。
BIND 10の各モジュールから統計データを集める。
bindctlあるいはb10-stats-httpdにより統計情報を報告できる。
b10-stats-httpd統計レポートのためのHTTPサーバ。
統計モジュールのHTTP/XMLインターフェイスを持つ。
b10-cmdctlBIND 10リモート制御デーモン。
コマンドをBIND 10サービスへ送る。
ダイジェスト認証付きの軽量HTTPSサーバとして動作。
RESTfulインターフェース。
b10-auth権威サーバ
b10-xfrinゾーン転送受信サービス
b10-xfroutゾーン転送送信サービス
b10-zonemgrセカンダリ ゾーン マネージャ
スレーブとして動作するために必要な時間や情報を管理する。
b10-ddnsダイナミック アップデート(DDNS)サービス
b10-resolverフルサービスリゾルバ

b10-sockcreatorとb10-msgqとb10-cfgmgrがコアコンポーネントとなっており、さらにb10-statsとb10-cmdctlのコンポーネントと合わせてデフォルトで起動するようになっています。

他のコンポーネントを利用するためには明示的に設定を行う必要があります。

ユーティリティ コマンド

BIND 10では以下のようなユーティリティ コマンドを提供しています。

bindctlBIND 10の設定制御ツール。
BIND 10サービスのコマンドラインユーザインターフェイスのツール。
b10-cmdctl-usermgrcmdctlユーザ保守ツール。b10-cmdctl用のユーザを管理する。
b10-loadzoneゾーンファイルのロード。
ゾーンファイルをロードして、BIND 10のデータストアに保存するユーティリティ。
b10-hostDNS検索ユーティリティ。
hostコマンドのBIND 10用のクローン。
b10-dbutilゾーンデータベース保守ユーティリティ。
BIND 10のSQLデータベースの管理ユーティリティ。

通常の運用で利用するのはbindctlとb10-loadzoneでしょう。

なお、digやDNSSEC関連のユーティリティは現時点では用意されていません。

設定と制御

設定

BIND 10の設定ファイルは/etc/named.confではなく、設定データベース/var/bind10/b10-config.dbになります。このファイルは次のようなJSONの形式で記述されています。

{"version": 2, "Logging": {"loggers": [{"name": "*", "output_options": [{"output": "bind10", "destination": "syslog"}], "severity": "INFO"}]}, "Auth": {"listen_on": [{"port": 53, "address": "192.0.2.53"}]}, "Boss": {"components": {"b10-xfrin": {"kind": "dispensable", "address": "Xfrin"}, "b10-cmdctl": {"kind": "needed", "special": "cmdctl"}, "b10-xfrout": {"kind": "dispensable", "address": "Xfrout"}, "b10-auth": {"kind": "needed", "special": "auth"}, "b10-zonemgr": {"kind": "dispensable", "address": "Zonemgr"}, "b10-stats": {"kind": "dispensable", "address": "Stats"}}}}

設定を行うためには、この設定データベースを直接編集するのではなく、bindctlという設定制御ツールを使います。

設定データベースを直接扱うのはb10-cfgmgrという設定マネージャであり、b10-cmdctlというリモート制御デーモン経由で設定ファイルの更新を行います。bindctlはb10-cmdctlのフロントエンドのコマンドラインインターフェイスとして使います。bindctlと他のモジュールとの通信は次のようになっています。

bindctl --[HTTP/JSON]-- b10-cmdctl --[コマンドチャネル b10-msgq]-- b10-cfgmgr -- 設定データベース

参考として、bindctlコマンドを使ってログ出力の設定を行う例を紹介します。ネットワークアプライアンスのコンソールと似たような操作を行います。

$ bindctl
["login success "] login as root
> config add Logging/loggers
> config show Logging/loggers
Logging/loggers[0]/name	""	string	(default)
Logging/loggers[0]/severity	"INFO"	string	(default)
Logging/loggers[0]/debuglevel	0	integer	(default)
Logging/loggers[0]/additive	false	boolean	(default)
Logging/loggers[0]/output_options	[]	list	(default)
> config set Logging/loggers[0]/name *
> config set Logging/loggers[0]/severity INFO 
> config add Logging/loggers[0]/output_options
> config show Logging/loggers[0]/output_options
Logging/loggers[0]/output_options[0]/destination        "console"       string (default)
Logging/loggers[0]/output_options[0]/output     "stdout"        string  (default)
Logging/loggers[0]/output_options[0]/flush      true    boolean (default)
Logging/loggers[0]/output_options[0]/maxsize    0       integer (default)
Logging/loggers[0]/output_options[0]/maxver     0       integer (default)
> config set Logging/loggers[0]/output_options[0]/destination syslog
> config set Logging/loggers[0]/output_options[0]/output bind10
> config show all Logging/loggers
Logging/loggers[0]/name	"*"	string	(modified)
Logging/loggers[0]/severity	"INFO"	string	(modified)
Logging/loggers[0]/debuglevel	0	integer	(default)
Logging/loggers[0]/additive	false	boolean	(default)
Logging/loggers[0]/output_options[0]/destination	"syslog"	string	(modified)
Logging/loggers[0]/output_options[0]/output	"bind10"	string	(modified)
Logging/loggers[0]/output_options[0]/flush	true	boolean	(default)
Logging/loggers[0]/output_options[0]/maxsize	0	integer	(default)
Logging/loggers[0]/output_options[0]/maxver	0	integer	(default)
> config diff
{'Logging': {'loggers': [{'name': '*', 'output_options': [{'output': 'bind10', 'destination': 'syslog'}], 'severity': 'INFO'}]}}
> config commit
> quit
$

設定項目の階層はJSONの形式のデータであることを意識すると設定の構成が理解しやすいでしょう。

なお、'config commit'を実行するとすぐに設定は反映されます。BIND 9のようにリロードを行う必要はありません。

ランタイム制御

BIND 9までの制御はrndcコマンドにより行われていましたが、BIND 10では、REST APIによる制御になります。このREST APIを提供するサービスb10-cmdctlとこのフロントエンドになるコマンドラインツールbindctlにより、より細かい制御が可能になります。

REST API

リモート制御デーモンのb10-cmdctlはHTTPSでの通信を行うWebサーバとして動作し、REST APIを用意しています。やりとりされるデータの形式はJSONです。そのため、管理用のWebアプリケーションの開発が行いやすいのではないかと思われます。

上述のbindctlはこのREST APIと通信するコマンドラインインターフェイスのアプリケーションです。

バックエンド データストレージ

バックエンド データストレージのエンジンはモジュール化されており、様々なものが利用できるような仕組みになっています。

1.0.0ベータ版では次のようなモジュールのファイルがあります。

$ cd /usr/libexec/bind10/backends/
$ ls -1
memory_ds.a
memory_ds.la
memory_ds.so
sqlite3_ds.a
sqlite3_ds.la
sqlite3_ds.so
static_ds.a
static_ds.la
static_ds.so

memory_dsはイン メモリ、sqlite3_dsはSQLite3、static_dsは静的ファイルのバックエンドです。将来のリリースではMySQLやBerkeley DBのような様々なデータストレージを利用可能になる予定です。

z10-loadzoneとSQLite3データストレージ

ゾーンの新規追加や更新はb10-loadzoneコマンドにより行います。このコマンドを実行するとゾーンファイルを読み込んで、構文チェックを行い、SQLite3のデータベース(/var/bind10/zone.sqlite3)に新規追加・更新を行います。

$ sudo b10-loadzone example.jp example.jp.zone
2012-12-21 17:55:51.863 INFO  [b10-loadzone.loadzone/2094] LOADZONE_SQLITE3_USING_DEFAULT_CONFIG Using default configuration with SQLite3 DB file /usr/local/var/bind10/zone.sqlite3
2012-12-21 17:55:51.875 INFO  [b10-loadzone.loadzone/2094] LOADZONE_ZONE_CREATED Zone example.jp./IN does not exist in the data source, newly created
2012-12-21 17:55:51.881 INFO  [b10-loadzone.loadzone/2094] LOADZONE_DONE Loaded (at least) 0 RRs into zone example.jp./IN in 0.00 seconds

このコマンドを実行したらロードしたゾーンの内容がすぐに反映されます。

BIND 9では大量のゾーンがあるときに起動時のゾーンのロードに時間がかかりましたが、BIND 10ではこのSQLite3バックエンドを使うことにより起動処理を短くできます。

セキュリティ

攻撃耐性

BIND 9ではサービス不能(DoS)攻撃によりサービスが止まったり落ちたりする脆弱性が頻繁に見つかってきました。

BIND 10ではbind10というマスタープロセスが各機能のサービスを子プロセスとして管理しており、子プロセスが死んでも子プロセスを自動的に起動し直します。そのため、子プロセスがサービス不能攻撃により落ちても、自動的に起動し直して、サービスを継続することができます。

ただし、コアコンポーネントであるb10-sockcreator, b10-msgq, b10-cfgmgrについてはそのプロセスが死んだときにはマスタープロセスと共に関連するプロセスを一緒に終了させます。こちらの対策についてはrespawn機能を持つinitデーモン(最近のLinux系ディストリビューションであればsystemdやupstart)により行えばよいでしょう。

オープンリゾルバの防止

第三者が利用できるフルサービスリゾルバをオープンリゾルバと言います。オープンリゾルバはDNS amp攻撃に利用されたり、キャッシュ汚染の攻撃を受けやすかったり、とセキュリティ上問題があります。そのため、オープンリゾルバの状態にしてはいけません。しかし、設定ミスや設定漏れによりオープンリゾルバになっているサーバが散見されました。それでは、BIND 10では設定ミスや設定漏れによりオープンリゾルバになりやすいのか確認してみましょう。

BIND 10のフルサービスリゾルバ自体はデフォルトでは起動しません。利用するためには明示的に設定を行う必要があります。そのため、BIND 10をインストールしたままの状態ではフルサービスリゾルバのサービス自体が起動していないため、オープンリゾルバにはなりません。

さらに、フルサービスリゾルバを起動させても、デフォルトでは127.0.0.1と::1にのみリッスンしていて、さらにデフォルトのACL(アクセス制御リスト)も127.0.0.1と::1からのみアクセスを許可しています。そのため、デフォルトではホスト自身のリゾルバとしてしか利用できないようになっており、オープンリゾルバにはなりません。

また、フルサービスリゾルバは権威サーバと兼用できないため、権威サーバを公開したら、うっかりフルサービスリゾルバも公開してしまったということにはなりません。

以上より、BIND 10では、明示的に設定しない限り、オープンリゾルバにはなりません。

開発言語

BIND 9とは異なる遺伝子

BIND 10は異なる開発言語で新たに作り直していて、さらにアーキテクチャも異なるため、BIND 9の遺伝子を引き継いでいません。BIND 9では頻繁に脆弱性が見つかっていますが、BIND 9の遺伝子を引き継いでいないため、BIND 9に起因する脆弱性の影響を受けることはありません。ただし、このことはBIND 10に脆弱性がないことを意味することではありません。

開発言語

BIND 10では開発言語にC++とPythonを使っていて、性能が必要なところをC++で、それ以外のところをPythonで開発しているとのことです。性能が要求される権威サーバやリゾルバの部分はC++で書かれており、管理系のサービスやツールのフロントエンドはPythonで書かれています。さらにPythonのプログラムからはC++で書かれたライブラリを呼び出して実行しています。

BIND 9からBIND 10への移行

BIND 9からBIND 10への移行が簡単にできるか気になっていると思います。

BIND 10はBINDの次世代バージョンと言いつつ、アーキテクチャが異なるため、BIND 9の設定ファイルやゾーンファイルをコピーしてすぐに移行という訳にはいきません。現時点では別のソフトウェアへの移行と考えた方がよいでしょう。既存サービスから移行しようとしたら、構成や設計および運用の見直しを行う必要があるのではないかと思います。

ゾーンの登録そのものはb10-loadzoneコマンドで簡単にできますが、ゾーン転送関連の設定を考えると一手間設定が必要です。管理しているゾーンが多ければ手動でのbindctlコマンドの設定は苦痛になるので、移行ツールが欲しいところです(言い出しっぺの法則への振りじゃないですよ)。

まとめというかレビューアの感想

BIND 9までは曖昧な理解で運用できてしまい、望ましくない設定により様々なトラブルが発生している事例が多くありました。BIND 10では機能毎にコンポーネント化され、権威サーバやフルサービスリゾルバがデフォルトでは起動していないこともあり、曖昧な理解での運用がしにくくなります。現状のbindctlによる設定ではそれなりに理解していないと設定そのものができません。そのため、ネームサーバの運用状況が改善されるとよいなと期待しています。しかし、このことがBIND 10への移行への阻害になるかもしれません。

また、bindctlでの対話的な設定は大量のゾーンを扱いたいときには現実的ではありません。そのため、REST APIが用意されているのでそれを利用すればよいのですが、皆が皆プログラミングができるわけではないのでbindctlのバッチ処理対応版があればよいなと思ったりもします(だから振りじゃないですよ)。2012-12-25 22:00修正: bindctlのコンソールで"execute file コマンドセットファイル"によりバッチ処理を実施できました。

以上で、BIND 10の紹介を終わりとします。中編と後編は明日に公開します。

参考情報

株式会社ハートビーツのインフラエンジニアから、ちょっとした情報をお届けします。