PowerDNS + PowerDNS-Admin で Docker 上に DNS サーバを構築する
概要
DNS サーバ実装である PowerDNS と、その管理用サードパーティ製 Web GUI である PowerDNS-Admin を使って権威 DNS サーバを構築します。
筆者は DNS の専門家ではないため、詳しい専門家の方から見て用語の誤り等ございましたらコメントでご指摘いただけますと幸いです。
使用する技術等
- Docker, Docker Compose
- PowerDNS
- PowerDNS-Admin
- SQLite
- PowerDNS ではバックエンドとして各種 RDB を使用することができます
- PowerDNS-Admin も DB を使用するようですが、 SQLite を使用できます
- 管理が楽なので SQLite を使うことにしました
目標
- PowerDNS によって DNS 権威サーバを建立する
- PowerDNS-Admin によって GUI でレコードを管理できる
背景
PowerDNS
PowerDNS とは、 PowerDNS 社によって開発された OSS の DNS サーバ実装です。
BIND とは異なり、権威サーバ (Authoritative Server) とリゾルバ (Recursor) でコンポーネントが別れています。
特に大規模なサービスプロバイダ向けとなっているようで、パフォーマンスを売りにしています。
PowerDNS-Admin
PowerDNS-Admin は、 PowerDNS を GUI で管理するためのサードパーティ製ソフトウェアです。
ドメインの作成やレコードの追加を GUI 上で行うことができます。
この GUI がいい感じだったので、これと組み合わせて PowerDNS を使うことにしました。
手順
1. 使用するバージョン等を確認する
PowerDNS, PowerDNS-Admin は両方共公式で Docker での実行をサポートしています。
それぞれ、対応してるバージョンを Docker Hub を見て確認します。
PowerDNS については、マイナーバージョンごとにイメージが別れているようなので、新しそうなものを選びます。
また、今回作りたいのは権威サーバのみなので、 pdns-auth-XX の中から選びます。
Recursor は pdns-recursor-XX です。
PowerDNS-Admin は、他のソフトウェアでもよく見るようにバージョンごとにタグをつけて管理する形になっています。
このため Tags のタブからバージョンを確認します。
2. 各種設定ファイルを作成する
使用するイメージが決まったら、あとはいろいろとファイルを作成するだけです。
まずは Docker Compose の compose.yaml です。
各種ポートはとりあえずローカルでの実験用で設定しています。
services:
auth:
image: powerdns/pdns-auth-48:4.8.1
ports:
- "8053:53"
- "8053:53/udp"
volumes:
- type: bind
source: ./data/powerdns-auth/pdns.sqlite
target: /var/lib/powerdns/pdns.sqlite
- ./pdns.d/pdns.conf:/etc/powerdns/pdns.d/pdns.conf
env_file: .env
admin:
image: ngoduykhanh/powerdns-admin:v0.3.0
ports:
- "8080:80"
volumes:
- type: bind
source: ./data/powerdns-admin/admin.sqlite
target: /data/admin.sqlite
environment:
- "SQLALCHEMY_DATABASE_URI=sqlite:////data/admin.sqlite"
- GUNICORN_TIMEOUT=60
- GUNICORN_workers=2
- GUNICORN_LOGLEVEL=INFO
次は .env です。 PowerDNS の API キーを入れるためだけに使っています。
PDNS_AUTH_API_KEY=<YOUR-TOKEN-STRING>
PowerDNS の設定を行う pdns.conf を作成します。
Docker Compose によるバインドを通じて、コンテナ内の /etc/powerdns/pdns.d/pdns.conf に配置されます。
使用する DB の設定などがあるので、任意で書き換えます。
local-address=0.0.0.0,::
launch=gsqlite3
gsqlite3-dnssec
gsqlite3-database=/var/lib/powerdns/pdns.sqlite
include-dir=/etc/powerdns/pdns.d
primary=yes
secondary=no
allow-axfr-ips=
version=string=powerdns
3. DB をセットアップする
今回は SQLite を使うことにしたので、 .sqlite ファイルを作成します。
作成しないと PowerDNS も PowerDNS-Admin もうまく起動しません。
また、 PowerDNS のものには初期化 SQL を投入する必要があります。
以下の SQL を pdns.schema.sql といった名前でローカルに保存しておきます。
SQLite の使用に関する公式ドキュメント からコピペしましたが、更新されている可能性もあるため改めてそちらを参照することをおすすめします。
SQLite の初期化 SQL
PRAGMA foreign_keys = 1;
CREATE TABLE domains (
id INTEGER PRIMARY KEY,
name VARCHAR(255) NOT NULL COLLATE NOCASE,
master VARCHAR(128) DEFAULT NULL,
last_check INTEGER DEFAULT NULL,
type VARCHAR(8) NOT NULL,
notified_serial INTEGER DEFAULT NULL,
account VARCHAR(40) DEFAULT NULL,
options VARCHAR(65535) DEFAULT NULL,
catalog VARCHAR(255) DEFAULT NULL
);
CREATE UNIQUE INDEX name_index ON domains(name);
CREATE INDEX catalog_idx ON domains(catalog);
CREATE TABLE records (
id INTEGER PRIMARY KEY,
domain_id INTEGER DEFAULT NULL,
name VARCHAR(255) DEFAULT NULL,
type VARCHAR(10) DEFAULT NULL,
content VARCHAR(65535) DEFAULT NULL,
ttl INTEGER DEFAULT NULL,
prio INTEGER DEFAULT NULL,
disabled BOOLEAN DEFAULT 0,
ordername VARCHAR(255),
auth BOOL DEFAULT 1,
FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX records_lookup_idx ON records(name, type);
CREATE INDEX records_lookup_id_idx ON records(domain_id, name, type);
CREATE INDEX records_order_idx ON records(domain_id, ordername);
CREATE TABLE supermasters (
ip VARCHAR(64) NOT NULL,
nameserver VARCHAR(255) NOT NULL COLLATE NOCASE,
account VARCHAR(40) NOT NULL
);
CREATE UNIQUE INDEX ip_nameserver_pk ON supermasters(ip, nameserver);
CREATE TABLE comments (
id INTEGER PRIMARY KEY,
domain_id INTEGER NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(10) NOT NULL,
modified_at INT NOT NULL,
account VARCHAR(40) DEFAULT NULL,
comment VARCHAR(65535) NOT NULL,
FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX comments_idx ON comments(domain_id, name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
CREATE TABLE domainmetadata (
id INTEGER PRIMARY KEY,
domain_id INT NOT NULL,
kind VARCHAR(32) COLLATE NOCASE,
content TEXT,
FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX domainmetaidindex ON domainmetadata(domain_id);
CREATE TABLE cryptokeys (
id INTEGER PRIMARY KEY,
domain_id INT NOT NULL,
flags INT NOT NULL,
active BOOL,
published BOOL DEFAULT 1,
content TEXT,
FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX domainidindex ON cryptokeys(domain_id);
CREATE TABLE tsigkeys (
id INTEGER PRIMARY KEY,
name VARCHAR(255) COLLATE NOCASE,
algorithm VARCHAR(50) COLLATE NOCASE,
secret VARCHAR(255)
);
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
保存できたら、実際に SQLite ファイルの作成と初期化をします。
mkdir -p ./data/powerdns-{auth,admin}
touch ./data/powerdns-admin/admin.sqlite
sqlite3 ./data/powerdns-auth/pdns.sqlite < ./pdns.schema.sql
4. 起動する
docker compose up
コンテナを起動して http://localhost:8080 にアクセスすると、 PowerDNS-Admin の Web GUI を見ることができます。
また、まだ何のゾーン設定も入っていないため確認できませんが、 PowerDNS Authoritative Server 自体も起動しています。
5. 設定する
ここから、 PowerDNS-Admin を操作して PowerDNS との連携やドメイン・レコードの追加を行います。
UI や公式ドキュメントに従えば難しくないと思うので、割愛します。
雑ですが、手順としては以上です。
実際に本番環境で使っていく際には、ポート設定や DB 設定を変えることになるでしょう。
まとめ
PowerDNS と PowerDNS-Admin を使って、 GUI でドメイン/レコードの管理を行える権威 DNS サーバを作成しました。
走り書きのため読みにくい箇所ありましたら恐縮です。
また、誤り・不足等あればご指摘いただけると幸いです。
いじょうです。