PowerDNS

IPv6 にも対応した新しいDNS サーバーです。バックエンドにMySQL を使えます。
更新日 2017-01-14

インストール

CentOS7(7.3) にソースからインストールします。

ソースのビルド

公式サイト からダウンロードします。今回はPowerDNS 4.0.2 です。インストールはPowerDNS 3.2: First StepsRaspberry PiにPowerDNSをいれて自宅DNSサーバにした話を参考にしました。
// Depends.
yum install -y mysql mysql-devel
yum install -y boost boost-devel
yum install -y gcc-c++ libstdc++-devel make
yum install -y lua-devel bind-utils

// Download.
cd /usr/local/src
wget "https://downloads.powerdns.com/releases/pdns-4.0.1.tar.bz2"
tar jxvf pdns-4.0.2.tar.bz2
cd pdns-4.0.2

// Build
./configure --with-modules="gmysql" --prefix=/usr/local/pdns-4.0.2
make
make install
ln -s /usr/local/pdns-4.0.2 /usr/local/pdns
chroot とユーザーの作成
// chroot dir
mkdir -p /var/chroot/pdns

// User and group
groupadd pdns
useradd -M -g pdns  -s /sbin/nologin -d /dev/null pdns
pdns.conf を編集します。
cd /usr/local/pdns/etc
cp pdns.conf-dist pdns.conf

chown pdns:pdns pdns.conf
chmod 600 pdns.conf


// Edit
vi pdns.conf

 chroot=/var/chroot/pdns
 daemon=yes
 launch=gmysql
 setgid=pdns
 setuid=pdns

 gmysql-host=192.168.23.6	# ip address only
 gmysql-user=user_powerdns
 gmysql-password=pass_powerdns
 gmysql-dbname=powerdns

 # webserver=yes
 # webserver-password=password
 # webserver-address=192.168.23.77
起動スクリプトを修正します。
// Daemon script.
cp /usr/local/src/pdns-4.0.2/pdns/pdns.init /etc/init.d/pdns
chmod 755 /etc/init.d/pdns
vi /etc/init.d/pdns

 // 環境変数prefix の設定
 prefix=/usr/local/pdns
systemd によるサービスを設定します。
vi /etc/systemd/system/powerdns.service

 [Unit]
 Description=PowerDNS
 After=network.target

 [Service]
 Type=forking
 PIDFile=/var/chroot/pdns/pdns.pid

 ExecStart=/etc/init.d/pdns start
 ExecStop=/etc/init.d/pdns stop
 ExecReload=/etc/init.d/pdns reload

 [Install]
 WantedBy=multi-user.target
起動テストします。
systemctl daemon-reload
systemctl start powerdns
systemctl status powerdns

// port53/udp を開放
firewall-cmd --add-port=53/udp --zone=public --permanent
firewall-cmd --reload

// 返事があればOk
dig @192.168.24.7

MySQL 側の初期設定

既存のMySQL(5.6.23) に所定のデータベース及びテーブルを作成します。ソースに付属のSQL ファイルを使います。
// データベースの作成(mysql コンソールで)
CREATE DATABASE powerdns DEFAULT CHARSET=latin1;

// デーブルの作成
cd /usr/local/src/pdns-4.0.1/modules/gmysqlbackend
mysql -u root -p powerdns < schema.mysql.sql

// user password の設定(mysql コンソール)
GRANT all on powerdns.* to user_powerdns@'localhost' identified by 'pass_powerdns';
GRANT all on powerdns.* to user_powerdns@'192.168.0.0/255.255.0.0' identified by 'pass_powerdns';

PowerDNSAdmin を使う

PowerDNS のレコード管理をブラウザ上から行えるフロントエンドです。GitHub - PowerDNS-Admin にインストール方法が書かれています。非常に便利です。

マスターでのみ使う

バックエンド(MySQL)へのアクセスにはPowerDNS を経由します。MySQL のレプリケーションマスターを参照している PowerDNS において利用する必要があります。

インストール

事前準備としてMySQL のデータベース
// MySQL コンソール

create database powerdnsadmin
GRANT all on powerdnsadmin.* to powerdnsadmin@'localhost' identified by 'powerdnsadminpassword';
GRANT all on powerdnsadmin.* to powerdnsadmin@'192.168.0.0/255.255.0.0' identified by 'powerdnsadminpassword';
PowerDNSAdmin のインストール
yum install -y python-devel MySQL-python virtualenv python-pip python-ldap openldap-devel
pip install --upgrade pip
pip install virtualenv

cd /usr/local/src
git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git
cd PowerDNS-Admin

// 仮想環境(flask) を作成
virtualenv flask
source ./flask/bin/activate

// これ要るかな?
pip install MySQL-python

// ビルドインストール開始
pip install -r requirements.txt
config.py の設定を行います。
cp config_template.py config.py

vi config.py

 SECRET_KEY = 'PowerDNSAdminKey'

 # PowerDNSAdmin のListen アドレス
 BIND_ADDRESS = '0.0.0.0'

 # MySQL ip address
 SQLA_DB_HOST = '192.168.24.6'

 PDNS_STATS_URL = 'http://127.0.0.1:8081/'
 PDNS_API_KEY = 'your-powerdns-api-key'
 PDNS_VERSION = '4.0.1'
データベース powerdnsadmin のテーブル作成を初回に行います。
// データベーステーブル作成(初回のみ)
./create.py
起動してアクセスします。powerdns も起動しておきます。
// 起動
./run.py

// port 9393 を開放
firewall-cmd --add-port=9393/tcp --zone=public --permanent
firewall-cmd --reload

//ブラウザでアクセス
http://192.168.24.7:9393/
アクセスを確認できたら終了します。
// 強制終了
ctrl + c

// 仮想環境も終了
deactivate

systemd でサービス化

起動スクリプトを作成してsystemd に登録します。
vi /etc/init.d/PowerDNSAdmin.sh

 #!/bin/sh

 cd /usr/local/src/PowerDNS-Admin
 virtualenv flask
 source ./flask/bin/activate
 ./run.py
この起動スクリプトをsystemd で起動する。スタンドアローンで動くのでType=simple で。
// サービス
vi /etc/systemd/system/powerdnsadmin.service

 [Unit]
 Description=PowerDNS-Admin
 After=network-online.target

 [Service]
 Type=simple
 ExecStart=/etc/init.d/PowerDNSAdmin.sh
 Restart=always

 [Install]
 WantedBy=multi-user.target
systemctl daemon-reload
systemctl start powerdnsadmin.service
systemctl enable powerdnsadmin.service

ドメインの追加

http://(powerdns server ip):9393/ でログインします(最初はログインユーザーを作成する必要があります)。ドメインを追加し、そこにサブドメインや レコード等をどんどん追加していきます。ドメインのSOA レコードはここからは変更できません。pdns.conf にデフォルト値を設定しておきます。
vi /usr/local/pdns/etc/pdns.conf

 default-soa-mail=admin@qt-space.com
 default-soa-name=ns1.qt-space.com
+New Domain から追加します。Type=Native はMaster slave のレプリケーション対象外になります(今回はMySQLレプリケーションで管理 する為)。SOA-EDIT-API は INCEPTION-INCREMENT にします。

サブドメイン・レコードの追加

MX レコードを設定します。Data 項目はダイアログ入力です。またレコード変更はApplyChanges を押すまで反映されません。
// MX
Name:(empty), Type:MX, Status:Active(default), TTL:60 minutes(default),
Data: 10 mail.qt-space.com (Priority 10)
SPF レコードを設定します。
// SPF(Data は"でくくる)
Name:(empty), Type:SPF, Status:Active(default), TTL:60 minutes(default),
Data: "v=spf1 +ip4:219.117.203.86 mx -all"
NS レコードを設定します。なぜかNS レコードが選べません。PowerDNSAdmin/config.py を編集します。
vi /usr/local/src/PowerDNSAdmin/config.py

 // NS を追加
 RECORDS_ALLOW_EDIT = ['A', 'AAAA', 'CNAME', 'SPF', 'PTR', 'MX', 'TXT', 'NS']

systemctl stop  powerdnsadmin.service
systemctl start powerdnsadmin.service
// NS
Name:ns1, Type:NS, Status:Active(default), TTL:60 minutes(default),
Data: 219.117.203.86
// A
Name:ast, Type:A, Status:Active(default), TTL:60 minutes(default),
Data: 219.117.203.86
// AAAA (IPv6、Data は"でくくる)
Name:ast, Type:AAAA, Status:Active(default), TTL:60 minutes(default),
Data: "2400:2651:42e0:3300::::1001"
// IPv6 の問い合わせ
dig @192.168.24.7 yahoo.co.jpe AAAA

MySQL 用レコード編集ソフト PowerDNSEditor(PowerDNS3.4 を対象)

上記のMySQL レコード管理を行えるソフトをC# で自作してみました。
PowerDNS Editor
[VS2012 C#] PowerDNSEditor プロジェクトファイル一式
[実行ファイル] PowerDNSEditor.exe
実行ファイルを動かす前に MySQL Connector/Net 6.8.3 をインストールしてください。VisualStudio 2012 でビルドする場合は MySQL Installer の方を入れて下さい。

ビルドの説明

MySQLConnector /.Net 6.8.3 以外のバージョンが動かすには、参照設定のMySql.Data を一度削除し、再度追加を行ってください。即興で作ってますのでソースは見苦しい点がありますが、ご容赦くださいませ。ビルドに関する質問はお気軽にどうぞ(ast@qt-space.com)。

PowerDNS をローカル向けプライマリDNS にする

外からの問い合わせだけでなく、ローカルからのプライベートな名前解決にも使えると便利です。プライマリDNS にPowerDNS サーバーを、 セカンダリDNS を8.8.8.8 にすれば良いのですが、非効率です。 幸いPowerDNS はローカルからの問い合わせに限定して、上位への再帰問い合わせをする事ができます。

pdns.conf を編集

ローカルからの接続に限り再帰問い合わせを許可。
vi /usr/local/pdns/etc/pdns.conf

 allow-recursion=127.0.0.1, 192.168.0.0/16
 recursor=8.8.8.8

テスト

PowerDNS に登録されていないドメインを問い合わせてみます。
dig @192.168.24.7 yahoo.co.jp