どーも、hondam です。
なんでこのネタにしたかっていうと(ネタを考える時間が1日しかなかったのでやっつけなんて言えない)、最近よく社内でBIND祭があるのと、過去(3年前)に自分が書いた「[DNS] PowerDNSとAtomia DNSを使ってみる」という投稿が意外?と読まれているようなので、そういえばPowerDNSって最近どうしてるんだろう、息してるのかな?と思ったからです。
PowerDNSおさらい
PowerDNSはGPLライセンスのC++で実装されたDNSサーバです。ほとんどのUNIXライクなOS上で動作します。PowerDNSはシンプルなBINDスタイルのゾーンファイルからRDBMSやロードバランシング/フェイルオーバーアルゴリズムまで多岐に渡る特徴があります。別プログラムとしてDNS recursorも含みます。
PowerDNSはオランダの企業PowerDNS.COM BVとオープンソースコミュニからの多くの貢献によって生み出されました。著名なデベロッパはBer Hubert氏です。
2013年からのバージョンアップ
3年前に使ってたバージョンはAuthoritative Serverの3.2です。そこからのバージョンアップ履歴ですが、SAやCVEでのアップデートがBINDと比べると断然少ないですね。あまり使われてない?という見方もありますが...祭りは少ない。
- 4.0.1 2016年7月29日 CVE-2016-6172.
- 4.0.0 2016年7月11日 ... ALIASレコード対応
- 3.4.9 2016年5月17日
- 3.4.8 2016年2月3日
- 3.4.7 2015年11月3日 Security Advisory 2015-03
- 3.4.6 2015年8月28日 Security Advisory 2015-02
- 3.4.5 2015年6月9日 Security Advisory 2015-01
- 3.4.4 2015年4月23日 Security Advisory 2015-01
- 3.4.3 2015年3月2日
- 3.4.2 2015年2月3日
- 3.4.1 2014年10月30日
- 3.4.0 2014年9月30日 ... REST API対応
- 3.3.1 2013年12月17日
- 3.3 2013年7月5日
とりあえずインストール
インストールする環境は以下となります。たまには他のサービスを使ってみようかなということで某VPS(の月900円くらいの)にしました。
# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
# cat /proc/version
Linux version 3.10.0-327.10.1.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) ) #1 SMP Tue Feb 16 17:03:50 UTC 2016
ではインストール。バックエンドDBはとりあえずMySQLでいきます。
PowerDNSのインストールマニュアルは公式に用意されていますが、DBのインストール方法までは記載されていません。
# yum install mariadb mariadb-server
〜中略〜
インストール:
mariadb.x86_64 1:5.5.50-1.el7_2
mariadb-server.x86_64 1:5.5.50-1.el7_2
完了しました!
必要あれば /etc/my.cnf
など修正してください。
# vi /etc/my.cnf
[mysqld]
character-set-server=utf8 # 追加するとか
systemctlでMySQLを有効にしておきます。
# systemctl list-unit-files --type=service | grep mariadb
mariadb.service disabled
# systemctl enable mariadb.service
# systemctl start mariadb.service
# ps xa | grep mysql
19272 ? Ss 0:00 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
19441 ? Sl 0:00 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
インストールの仕上げに mysql_secure_installation
を実行しておきます。
このコマンドはrootユーザのパスワード変更や、anonymousユーザーの削除などを行うものなので、特に実行しなくてもOKです。実行した場合は適宜設定してください。
# mysql_secure_installation
OTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):
〜中略〜
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
mysql_secure_installation
でrootユーザのパスワードを変更したので、接続可能か確認します。
# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 5.5.50-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
OKですね。ではこの段階でPowerDNS用のデータベースとテーブルを作成しておきましょ。
まずはデータベースを作成します。ここでは pdns
とします。
# mysql -u root -p -e "CREATE DATABASE pdns CHARACTER SET utf8;"
次にPowerDNS用のテーブルを作成します。
# vi pdns_tables.sql
CREATE TABLE domains (
id INT AUTO_INCREMENT,
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,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE UNIQUE INDEX name_index ON domains(name);
CREATE TABLE records (
id INT AUTO_INCREMENT,
domain_id INT DEFAULT NULL,
name VARCHAR(255) DEFAULT NULL,
type VARCHAR(10) DEFAULT NULL,
content VARCHAR(64000) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
disabled TINYINT(1) DEFAULT 0,
ordername VARCHAR(255) BINARY DEFAULT NULL,
auth TINYINT(1) DEFAULT 1,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX recordorder ON records (domain_id, ordername);
CREATE TABLE supermasters (
ip VARCHAR(64) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) NOT NULL,
PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;
CREATE TABLE comments (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(10) NOT NULL,
modified_at INT NOT NULL,
account VARCHAR(40) NOT NULL,
comment VARCHAR(64000) NOT NULL,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE INDEX comments_domain_id_idx ON comments (domain_id);
CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
CREATE TABLE domainmetadata (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
kind VARCHAR(32),
content TEXT,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);
CREATE TABLE cryptokeys (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
flags INT NOT NULL,
active BOOL,
content TEXT,
PRIMARY KEY(id)
) Engine=InnoDB;
CREATE INDEX domainidindex ON cryptokeys(domain_id);
CREATE TABLE tsigkeys (
id INT AUTO_INCREMENT,
name VARCHAR(255),
algorithm VARCHAR(50),
secret VARCHAR(255),
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
先ほど作成したpdns
データベースにインポートします。
# mysql -u root -p -D pdns < pdns_tables.sql
これでMySQLの準備はOKですね。
では次にPowerDNSをインストールします。
# yum info pdns
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: ftp.iij.ad.jp
* epel: ftp.riken.jp
* epel-debuginfo: ftp.riken.jp
* epel-source: ftp.riken.jp
* extras: ftp.iij.ad.jp
* updates: ftp.iij.ad.jp
利用可能なパッケージ
名前 : pdns
アーキテクチャー : x86_64
バージョン : 3.4.10
リリース : 1.el7
容量 : 2.1 M
リポジトリー : epel/x86_64
要約 : A modern, advanced and high performance authoritative-only nameserver
URL : http://powerdns.com
ライセンス : GPLv2
説明 : The PowerDNS Nameserver is a modern, advanced and high performance
: authoritative-only nameserver. It is written from scratch and conforms
: to all relevant DNS standards documents.
: Furthermore, PowerDNS interfaces with almost any database.
3年前のバージョンは3.2でしたが、3.4.10になっているようです。
# yum install pdns pdns-backend-mysql
〜中略〜
インストール:
pdns.x86_64 0:3.4.10-1.el7
pdns-backend-mysql.x86_64 0:3.4.10-1.el7
完了しました!
次に pdns.conf
を修正します。
デフォルトではMySQLを使うようになっていません。
# egrep -v '^\s*(#|$)' /etc/pdns/pdns.conf
setuid=pdns
setgid=pdns
launch=bind
MySQLのユーザやパスワードは適宜変更してください。ここではrootで設定しています。
# vi /etc/pdns/pdns.conf
setuid=pdns
setgid=pdns
launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=root
gmysql-dbname=pdns
gmysql-password=[設定したパスワード]
# systemctl list-unit-files --type=service | grep pdns
pdns.service disabled
# systemctl enable pdns.service
# systemctl start pdns.service
ちなみに pdns.service
の中身はこんな感じですね。
# cat /etc/systemd/system/multi-user.target.wants/pdns.service
[Unit]
Description=PowerDNS Authoritative Server
Wants=network-online.target
After=network-online.target mariadb.service postgresql.service slapd.service
[Service]
Type=forking
ExecStart=/usr/sbin/pdns_server --daemon
ExecStop=/usr/bin/pdns_control quit
Restart=on-failure
RestartSec=2
PrivateTmp=true
[Install]
WantedBy=multi-user.target
ではPowerDNSを起動したところで、名前解決できるかどうか確認してみましょ。
# dig +short www.example.com @127.0.0.1
当然結果は何も返ってきませんね。
ではテストのゾーン情報を登録してみます。
# vi example.com.zone.sql
INSERT INTO domains (name, type) values ('example.com', 'NATIVE');
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'example.com','localhost ahu@ds9a.nl 1','SOA',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'example.com','dns-us1.powerdns.net','NS',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'example.com','dns-eu1.powerdns.net','NS',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'www.example.com','192.0.2.10','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'mail.example.com','192.0.2.12','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'localhost.example.com','127.0.0.1','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES (1,'example.com','mail.example.com','MX',120,25);
# mysql -u root -p -D pdns < example.com.zone.sql
おもむろに再実行すると...
# dig +short www.example.com @127.0.0.1
192.0.2.10
# dig +short example.com MX @127.0.0.1
25 mail.example.com.
OKですね。これでひとまずMySQLを使ってPowerDNSが動く状況になりました。
3年前の記事ではここからAtomia DNSをインストールしましたが、はたして状況は変わってるでしょうか。
PowerDNS向けのツールは、PowerDNSのAPIを呼び出すものと、SQL実行するものがあります。
以下はその一覧です。GitHubのPowerDNSのWikiに記載がありましたので載せておきます。
Atomia DNSも更新はあるようですね。
PowerDNSのAPIを利用するタイプ
名称 | 使用言語 | 更新履歴 |
---|---|---|
nsedit | PHP/JS | Active |
PowerDNS-Admin | Python/JS | Active |
PowerDNS-Shell-Wrapper (API based command-line tool) |
Shell/Curl/JQ | Active |
pdnscontrol | Python/JS | Latest Commit 2016-03-30 |
yapdnsui | express.js | Latest Commit 2016-02-12 |
PoweREST | React.js | Latest Commit 2015-05-31 |
powr | AngularJS | Latest Commit 2015-02-15 |
SQLを利用するタイプ
名称 | 使用言語 | 更新履歴 |
---|---|---|
django-powerdns-manager | Django | Active, Work in progress |
DnsShop | PHP/JS | Active, code is since 2011 in production |
NicTool | Perl | Active |
PDNS Manager | PHP | Active |
Poweradmin | PHP | Active |
atomiadns | JS | Active |
PowerDNS on Rails | Ruby on Rails | Last Commit 2015-09-30 |
pdns-gui | PHP | Last Commit 2014-11-18, but apparently in active use |
freshdns | PHP, AJAX | Last Commit 2014-06-13 |
Powerdns Tango | Perl | Last Commit 2014-05-21 |
JPower Admin | Java | Last Release 2014-02-12 |
pdnsui | Ramaze | Last Commit 2014-01-09 |
ZoneAdmin | PHP | Last Release 2013-10-07 |
GNUPanel | PHP | Last Release 2013-07-20 |
phpDNSAdmin | PHP | Last Release 2013-05-16 |
powerdns-webinterface | PHP | Last Commit 2013-05-14 |
PowerDNS Administration | PHP | Last Release 2013-03-22 |
DNS Master | PHP, jQuery | Released 2012-10-09 |
MoxieDNS | ??? | demo-url & project dead? (2012-05-15) |
GOsa² | PHP | Last Release 2012-05-09 |
PDNSOps | PHP | Last Commit 2012-02-12 |
pdns-ror-admin | Ruby on Rails | First/Last Commit in 2007-06-01 |
TUPA | PHP, AJAX | Last Release 2006-03-16 |
djdns | Django | Last Commit in 2009 |
pdns-tools | Python | Last Commit in 2009 |
pdnsfront | PHP | Last Commit in 2008 |
色々ありますが、息してるのは少ないかな。Atomia DNSは無事なようです。
PowerDNS-Admin
今回チョイスしたのは PowerDNS-Admin です。
単純にGitHubのStarの数と見た目で選びました。
では動くかわかりませんが早速インストールしてみましょう。
pdns.conf
に以下の設定を追加します。
# vi /etc/pdns/pdns.conf
experimental-json-interface=yes
experimental-api-key=[適宜keyを設定してください]
webserver=yes
この設定でPowerDNSのREST APIが有効になります。
ではAPIが有効か確認してみましょう。
# curl -s -H 'X-API-Key: experimental-api-keyの値' http://127.0.0.1:8081/servers/localhost/zones | jq "."
[
{
"id": "example.com.",
"url": "/servers/localhost/zones/example.com.",
"name": "example.com",
"kind": "Native",
"dnssec": false,
"account": "",
"masters": [],
"serial": 1,
"notified_serial": 0,
"last_check": 0
}
]
OKですね。
では次にPowerDNS-Admin用のデータベースを作成します。
# mysql -u root -p -e "CREATE DATABASE powerdnsadmin CHARACTER SET utf8;"
# mysql -u root -p -e "GRANT ALL PRIVILEGES ON powerdnsadmin.* TO powerdnsadmin@'%' IDENTIFIED BY '適宜設定してください';"
ではPowerDNS-Adminを起動します。
起動に伴い、必要なパッケージのインストールと、設定が必要なので行います。
環境によっては既にインストールされているものもあると思いますので、過不足あれば適宜インストールしてください。
PowerDNS-Admin は PythonのマイクロフレームワークFlaskを使用しています。
# python -V
Python 2.7.5
# yum install python-pip
# yum install mariadb-devel
# yum install gcc
# git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git
# cd PowerDNS-Admin
mariadb-devel は MySQL-pythonで必要だったのでインストールしています。
gccはldap関連のモジュールをインストールするのに必要でした。(今回はLDAP認証使ってませんが)
# pip install --upgrade pip
# pip install virtualenv
# pip install MySQL-python
# virtualenv flask
# source ./flask/bin/activate
(flask)# pip install -r requirements.txt
(flask)# cp config_template.py config.py
(flask)# vi config.py
# DATABASE CONFIG
SQLA_DB_USER = 'powerdnsadmin'
SQLA_DB_PASSWORD = '適宜設定してください'
SQLA_DB_HOST = '127.0.0.1'
SQLA_DB_NAME = 'powerdnsadmin'
# POWERDNS CONFIG
PDNS_STATS_URL = '適宜設定してください'
PDNS_API_KEY = '適宜設定してください'
PDNS_VERSION = '適宜設定してください'
config.pyのデフォルトポートが9393だったので、firewall-cmdで9393ポートを開けました。
最後に./run.pyすれば起動されます。
(flask)# ./create_db.py
(flask)# firewall-cmd --add-port=9393/tcp --zone=public
(flask)# ./run.py
ログイン画面 |
---|
ダッシュボード画面 |
---|
レコード編集画面 |
---|
ということで無事PowerDNS-Adminが起動できました。
最初にテストで登録したゾーン情報が閲覧・変更できますね。
まともに権威DNSとして利用するにはもっとちゃんとした設定やSlaveも必要ですが、簡単そうなのは伝わったかと思います。
久しぶりにさわったPowerDNSまとめ
- 祭りは少ない(ただあまり使われてないという見方も)。BINDに疲れたら。
- PowerDNSのインストールは簡単(バックエンドをDBにすると多少運用が面倒)
- いつのまにかREST APIが使えるようになってたので夢は広がりそう
- Atomia DNS以外にイケてそうなUIの管理ツールも誕生してる
ということで12月1日担当の hondam でした。