前書き
2018年に投稿した内容では古くてそのままでは動作しなくなっているので2022年版として改めて検証も兼ねてメモを残しておきます。
背景
DNSの実装と言えば古くからBINDが使われていますが、昨今では脆弱性が度々発覚してセキュリティ的に運用が難しい状況にあります。
BINDに代わるDNSの実装が他にもあり主要なLinuxディストリビューションでも公式パッケージ化されて最新バージョンにも追随しています。
動作環境
ホスト側
- OS:Ubuntu Server 22.04.1LTS
- Docker CE version 20.10.18
- docker compose version v2.10.2
Docker環境の準備
以下のページにて紹介していますので参考にしてみて下さい。
Dockerコンテナ環境で動かす理由
Dockerコンテナの特徴と利点が有用であれば使ってみるのも有りだと思います。
- ホストOS側とコンテナ分離する事でホストOS側への影響が少ない
- 構築したコンテナ環境を他の別環境に移設やバックアップがしやすい
- Kubernetesなどのクラウド・コンテナオーケストレーション環境に展開出来る
権威DNSサーバー PowerDNS Authoritative Server
コンテンツサーバーとも呼ばれる自組織や他組織のゾーンを管理しているDNSサーバーです。
一般の利用者がドメイン検索で使用するキャッシュDNSサーバーと呼ばれるフルリゾルバーのDNSサーバーが権威DNSサーバーのルートサーバーから順繰りに問い合わせてドメイン検索する仕組みがDNSです。
今回はBINDではなくPowerDNS Authoritative Serverを使用します。一部TLDでも採用されています。
ゾーンの管理にSQLite3やMySQLなどのDBを利用して、WebインターフェースによるGUI操作が出来ます。
ローカルホスト側のリゾルバ設定
ubuntuの場合、systemdでDNSの53番ポートがサービス起動していて、他のDNSサービスとは競合してしまうので、名前解決のローカルリゾルバは動作させたまま53番ポートのListenを無効化させます。
[Resolve]
DNSStubListener=no
なおnameserverの指定はnetplanの記述に自動修正されます。
$ cd /etc
$ sudo ln -sf ../run/systemd/resolve/resolv.conf resolv.conf
$ sudo systemctl restart systemd-resolved
サービスポート変換
クラウドのインスタンス環境などの場合はローカルリゾルバを変更せずに、Dockerコンテナ側の1053番ポートなどの別のサーピスポート番号で動作しているので、クラウド側のセキュリティグループ設定でグルーバルIPアドレス側の53番ポートとNAPT変換させます。
ports:
- 1053:53/tcp
- 1053:53/udp
PowerDNS(pdns)
PowerDNSの公式Dockerが提供されているので利用します。
このPowerDNS(pdns)コンテナには権威DNS(Auth)、フルリゾルバ(Recursor)、ロードバランサ(dnsdist)の3つのサービスが提供されています。
今回は権威DNS(Auth)だけ利用します。
docker compose設定
適当なディレクトリを作成して「docker compose」設定ファイルを作成します。
$ mkdir -p pdns
$ cd pdns
services:
auth:
image: powerdns/pdns-auth-master:latest
container_name: pdns_auth
environment:
- PDNS_AUTH_API_KEY
ports:
- "53:53"
- "53:53/udp"
volumes:
- powerdns:/var/lib/powerdns
- ./pdns.d/pdns.conf:/etc/powerdns/pdns.d/pdns.conf
volumes:
powerdns:
driver: local
Docker Volumeで永続化している「powerdns」はsqlite3のデータベースファイルが保存されるディレクトリなのでバックアップも考慮しておきましょう。
PowerDNS設定ファイルの作成
各種設定ファイル類はカレントディレクトリ以下に配置してPowerDNS(pdns)コンテナ側にマウントさせています。次に各設定ファイルを作成します。
権威DNS(Auth)
適当なディレクトリを作成して設定ファイル「pdns.conf」を作成します。
$ mkdir -p pdns.d
local-address=0.0.0.0,::
launch=gsqlite3
gsqlite3-dnssec
gsqlite3-database=/var/lib/powerdns/pdns.sqlite3
include-dir=/etc/powerdns/pdns.d
primary=no # プライマリの場合=yes
secondary=no # セカンダリの場合=yes
allow-axfr-ips=1.2.3.4 # zoneの転送許可IPアドレス番号
version-string=powerdns
権威DNSサーバーは1つのprimaryサーバーと複数のsecondaryサーバーで構成されますが、PowerDNSではこれを明確に設定します。
ドメインのZone転送はsecondaryサーバー側に限定してZone情報が他に漏洩しないようにZone転送許可するIPアドレス番号を記述します。
バージョン表示の応答も詳細を隠しておきます。
環境設定
各APIのkeyを設定します。
PDNS_AUTH_API_KEY=[Auth APIのkey文字列]
PowerDNS-Admin
PowerDNS用のフロントエンドのGUIツールでは活発に開発されているのがPowerDNS-Adminです。
各種ユーザー認証にも対応していて複数ドメインとユーザー管理が出来るのが特徴です。画面表示はpoweradminと違って日本語には対応していませんが、特に難しい事は無く使えると思います。
docker compose設定
services:
admin:
image: ngoduykhanh/powerdns-admin:latest
container_name: pdns_admin
ports:
- "80:80"
logging:
driver: json-file
options:
max-size: 50m
environment:
- GUNICORN_TIMEOUT=60
- GUNICORN_WORKERS=2
- GUNICORN_LOGLEVEL=DEBUG
- OFFLINE_MODE=True # True for offline, False for external resources
volumes:
- powerdnsadmin-data:/data
volumes:
powerdnsadmin-data:
driver: local
PowerDNS(pdns_auth)+PowerDNS-Admin(pdns_admin)コンテナ起動
以上で必要な設定ファイルが用意出来たので、docker composeコマンドでコンテナを起動させます。
$ docker compose up -d
$ docker compose ps
NAME COMMAND SERVICE STATUS PORTS
pdns_admin "entrypoint.sh gunic…" admin running (healthy) 0.0.0.0:80->80/tcp
pdns_auth "/usr/bin/tini -- /u…" auth running 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, 8081/tcp
バージョンの確認方法
設定ファイルでバージョン表示を隠匿した場合はDNSの応答では表示されません。
Dockerコンテナからコマンドを実行しましょう。
$ docker exec pdns_auth /usr/local/sbin/pdns_server --version
Sep 26 08:17:06 PowerDNS Authoritative Server 4.8.0-alpha0.272.master.ga31f39c20 (C) 2001-2022 PowerDNS.COM BV
Web設定画面
PowerDNS-AdminのGUI画面はブラウザで指定すれば表示されます。最初はアカウント作成のログイン画面になります。