Sysadmin Toolbox

第1回RDBMSが使えるPowerDNS

はじめに

以前はDNSサーバと言えば、BINDとdjbdnsくらいしかありませんでしたが、現在ではさまざまなDNSサーバが利用できるようになりました。

DNSはサイト固有の要件が増えることが多く、またテキストファイルによる管理では不都合もなにかとでてきます。このため、RDBMSでレコードを管理できると便利です。BINDをRDBMSに対応させるパッチも存在します

PowerDNSとは

ここでは、RDBMSを利用でき、容易な管理をサポートする機能が豊富なPowerDNSを紹介します。

PowerDNSは豊富なバックエンドをサポートするDNSサーバです。コンテンツDNSサーバとキャッシュDNSサーバの両方をサポートしており、それぞれは別のプロセスとして実行されます。すでに大規模なサービスプロバイダでも採用されており実績も十分あるとされています。バックエンドにはLDAP、PostgreSQL、MySQL、Oracle、BINDのzoneファイルなどが使用でき、移行も容易です。GPL v2のオープンソースソフトウェアですが、開発元による商用サポートも提供されており、DNS管理の商用ソフトウェアとして、ASP向けのPowerDNS Expressという製品もあります。

前提

ここではOSにGentoo/Linuxを使いますが、他のdistributionでも必要な作業は同じです。各distributionに応じて適宜読みかえてください。バックエンドにPostgreSQL以外を使用する場合は、マニュアルを参照してください。

  • 使用するバックエンドはPostgreSQL
  • ドメインはexample.org
  • example.orgのauthoritativeなDNSサーバはns.example.org
  • PostgreSQLサーバはpostgres.example.org
  • PowerDNSは127.0.0.1でlisten
  • 既存のBINDから移行

PostgreSQLへデータの移行

BINDの設定をデータベースに移行します。移行には付属のzone2sqlコマンドを使用します。

> cd /etc/namedb
> zone2sql  --gpgsql > ~/domain.sql

既存のBINDの設定ファイルが利用できない場合は、サンプルのnamed.confおよび設定ファイルを作成します。example.orgは管理下のドメイン名に置き換えてください。

> dig example.org any @ns.example.org > db.example.org
> vim named.conf
zone "example.org" {
    type master;
        file "db.example.org";
};

> zone2sql  --gpgsql > ~/domain.sql

PostgreSQLにユーザを作成します。

> psql -U postgres --password -h postgres.example.org template1
template1=# CREATE USER pdns PASSWORD 'password';
template1=# CREATE DATABASE pdns owner pdns;
template1=# \q

テーブルを作成します。

> vim pdsn.sql
CREATE TABLE domains (
    id              SERIAL PRIMARY KEY,
    name            VARCHAR(255) NOT NULL,
    master          VARCHAR(128) DEFAULT NULL,
    last_check      INT DEFAULT NULL,
    type            VARCHAR(6) NOT NULL,
    notified_serial INT DEFAULT NULL, 
    account         VARCHAR(40) DEFAULT NULL
);
CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
    id              SERIAL PRIMARY KEY,
    domain_id       INT DEFAULT NULL,
    name            VARCHAR(255) DEFAULT NULL,
    type            VARCHAR(6) DEFAULT NULL,
    content         VARCHAR(255) DEFAULT NULL,
    ttl             INT DEFAULT NULL,
    prio            INT DEFAULT NULL,
    change_date     INT DEFAULT NULL, 
    CONSTRAINT domain_exists 
    FOREIGN KEY(domain_id) REFERENCES domains(id)
    ON DELETE CASCADE
);

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

CREATE TABLE supermasters (
    ip VARCHAR(25) NOT NULL, 
    nameserver VARCHAR(255) NOT NULL, 
    account VARCHAR(40) DEFAULT NULL
);

GRANT SELECT ON supermasters TO pdns;
GRANT ALL ON domains TO pdns;
GRANT ALL ON domains_id_seq TO pdns;
GRANT ALL ON records TO pdns;
GRANT ALL ON records_id_seq TO pdns;

> psql -U pdns --password -h postgres.example.org pdns < ~/pdns.sql

データをPostgreSQLにインポートします。

> psql -U pdns --password -h postgres.example.org pdns < ~/domain.sql

PowerDNSのインストールと設定

PostgreSQLを使用するので、USEフラグでpostgresを有効にします。

> sudo vim /etc/portage/package.use
net-dns/pdns   postgres

PowerDNSをemergeします。

> sudo emerge pdns

127.0.0.1でlistenし、PostgreSQLの接続に必要な設定をします。

> sudo vim /etc/powerdns/pdns.conf
local-address=127.0.0.1
launch=gpgsql
gpgsql-host=postgres.example.org
gpgsql-user=pdns
gpgsql-dbname=pdns

PowerDNSの起動

起動時にPowerDNSを起動するように、defaultのrun levelに追加します。

> sudo rc-config add pdns default

BINDが起動している場合は停止します。

> sudo /etc/init.d/named stop

PowerDNSを起動します。

> sudo /etc/init.d/pdns start

状態を確認します。pdns_controlは実行中のPowerDNSを管理するコマンドで、設定の変更や状態の確認などに使用します。詳しくはpdns_control(8)をご覧ください。通信にはUnix socketを使用しますので、適切な権限が必要です。

> sudo -u pdns pdns_control status
17506: Child running on pid 17515
> ps ax | grep 17515
17515 ?        Sl     0:00 /usr/sbin/pdns_server-instance --daemon=yes --guardian=yes
> sudo -u pdns pdns_control uptime
9.8 minutes
> dig example.org any @127.0.0.1

``pdns_control show''の出力はMRTGなどのツールに渡すことで長期的なトレンドを把握するのにも使えます。

> sudo -u pdns pdns_control show udp-queries
1

各種統計データをブラウザから参照することもできます。以下の設定を追加します。

> sudo vim /etc/powerdns/pdns.conf
webserver=yes
webserver-password=password
webserver-address=ip.add.re.ss

PowerDNSを再起動します。

> sudo /etc/init.d/pdns restart

ブラウザでhttp://ip.add.re.ss:8081/を開きます。Basic認証のダイアログボックスが表示されますので、ユーザ名には任意の文字列、パスワードにはwebserver-passwordで指定したpasswordを入力します。

各種統計データをブラウザから参照できる
各種統計データをブラウザから参照できる

SSLには対応していませんので、別途apacheなどを手前に配置して適切な認証と暗号化をはかる必要があります。

レコードとドメインの追加

レコードを追加するには、次のようなSQLを実行します。

INSERT INTO records (
    domain_id,
    name,
    type,
    content,
    ttl
) VALUES (
    1,
    "host.example.org",
    "A",
    "10.10.0.1",
    86400
);

ドメインを追加するには、次のようなSQLを発行します。

INSERT INTO domains ( name, type ) VALUES ( 'example.com', 'NATIVE' );

おまけ:Catalystアプリケーション

PowerDNSにはRDBMSのデータを管理するためのUIがありませんので、おまけとして、Catalystでレコードを表示するだけの、とても簡易なCatalystアプリケーションを作成します。Catalystについての解説は割愛します。詳しくはWebサイトを参照してください。以下のPerlモジュールが必要です。distributionのパッケージ管理システムもしくはCPANなどでインストールします。

  • Catalyst
  • Catalyst::Model::DBIC::Schema
  • Catalyst::View::TT
  • DBD::Pg

執筆時点で、いくつかの依存関係が足りません。依存関係でインストールされないモジュールをインストールします。

> sudo emerge PAR-Dist
> sudo g-cpan --install Module-CoreList Module-ScanDeps DBIx-Class-Schema-Loader Data-Dump

必要なモジュールをインストールします。

> sudo emerge DBD-Pg
> sudo g-cpan --install Catalyst Catalyst-Devel Catalyst-View-TT Catalyst-Model-DBIC-Schema

アプリケーションを作成します。

> catalyst.pl -short Padmin
> cd Padmin

modelを作成します。

> ./script/padmin_create.pl model DNS DBIC::Schema DNS::Schema create=static "dbi:Pg:dbname=pdns;host=postgres.example.org" pdns password

controllerを作成します。

> ./script/padmin_create.pl controller Cat
> vim lib/Padmin/C/Cat.pm
package Padmin::C::Cat;
use strict;
use warnings;
use base 'Catalyst::Controller';
sub index : Private {
    my ( $self, $c ) = @_;
    my @domains = $c->model('M::DNS::Domains')->search(
        {},
    );
    $c->stash->{domains} = \@domains;
    return;
}
sub domain : Local {
    my ( $self, $c ) = @_;
    my ( $domain_name ) = $c->req->arguments;
    my ( $domain ) = $c->model('M::DNS::Domains')->search(
        { name => $domain_name }
    );
    $c->stash->{domain} = $domain;
    return;
}
1;

viewを作成します。

> ./script/padmin_create.pl view TT TTSite

ドメインの一覧を表示するテンプレートを作成します。

> mkdir root/src/cat
> vim root/src/cat/index
[% c = Catalyst %]
<h1>Domains</h1>
[% FOR domain IN domains %]
    <ul>
        <li><a href="[% c.uri_for('/cat/domain') | html %]/[% domain.name | html %]">[% domain.name | html %]</a></li>
    </ul>
[% END %]

ドメインのレコード一覧を表示するテンプレートを作成します。

> vim root/src/cat/domain
<h1>[% domain.name | html %]</h1>
<ul>
[% FOR record IN domain.records %]
    <li>[% record.name | html %]
        <ul>
            <li>ID: [% record.id | html %]</li>
            <li>name: [% record.name | html %]</li>
            <li>type: [% record.type | html %]</li>
            <li>ttl: [% record.ttl | html %]</li>
        </ul>
    </li>
[% END %]
</ul>

アプリケーションを起動します。

> ./script/padmin_server.pl

ブラウザでhttp://localhost:3000/catにアクセスします。

おわりに

サイト固有の要件をフロントエンドに実装すれば、きわめて柔軟性の高いDNS管理が可能です。また、すでに公開されているフロントエンドもありますので、試してみてはいかがでしょうか。

今回は紹介しませんでしたが、PowerDNSにはキャッシュDNSサーバとして動作するpdns_recursorもあります。インストールも設定も簡単ですので、ぜひお試しください。

おすすめ記事

記事・ニュース一覧