Web GUI が使える権威 DNS サーバー PowerDNS ft. Poweradmin


一般的な LAN 内で使用する権威サーバーとして構築した例です。
## 環境
サーバー IP アドレス: `192.168.182.10`
AlmaLinux 9.5
PostgreSQL 16.8
PowerDNS 権威サーバー 4.9.5
Poweradmin 3.9.2
SELinux 有効

## PostgreSQLの準備
バックエンドには MySQL や MariaDB、汎用ODBC、SQLite、また DB 以外だと BIND 形式ファイル、LDAP なども使用できますが、今回は PostgreSQL を使用します。
```
# dnf module install postgresql:16/server
# postgresql-setup --initdb
```
以下の通り編集します。
```/var/lib/pgsql/data/postgresql.conf
listen_addresses = 'localhost'
```
```/var/lib/pgsql/data/pg_hba.conf

host    all             all             127.0.0.1/32            scram-sha-256
```
自動起動を有効化して起動します。
```
# systemctl enable postgresql
# systemctl start postgresql
```
データベースとユーザーを作成します。
```
# sudo -u postgres psql
# create database pdns;
# create role pdns with login password '<パスワード>';
# grant all on database pdns to pdns;
# alter database pdns owner to pdns;
# quit
```
## PowerDNS 権威サーバーのインストール・設定
PowerDNS のリポから最新バージョンが手に入ります。
インストール後、DB にテーブル・インデックスをセットアップします。
```
# dnf install epel-release && dnf upgrade
# curl https://repo.powerdns.com/repo-files/el-auth-49.repo -o /etc/yum.repos.d/powerdns-auth-49.repo 
# dnf install pdns pdns-backend-postgresql
# psql -h 127.0.0.1 -U pdns < /usr/share/doc/pdns-backend-postgresql/schema.pgsql.sql
```
DB への接続設定とログの設定を行います。
``` /etc/pdns/pdns.conf
version-string=anonymous

daemon=no
guardian=no

launch=gpgsql
gpgsql-host=127.0.0.1
gpgsql-port=5432
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password=<パスワード>

setgid=pdns
setuid=pdns

loglevel=6
log-dns-details=yes
```
以下で確認。`Done launching threads, ready to distribute questions`が出れば OK です。
```
# pdns_server --daemon=no --guardian=no --loglevel=9
```
PowerDNS 権威サーバーの自動起動を有効化して起動します。
```
# chown pdns:pdns -R /etc/pdns/
# systemctl enable pdns
# systemctl start pdns
```
## Poweradmin の準備
PowerDNS 用の GUI は複数存在しますが、今回は使用例が多くメンテナンスも多く行われている Poweradmin を使用します。
Poweradmin の前提となるパッケージと、apache、unzip をインストールします。
最新版の PHP をインストールするため、Remi リポジトリを使用します。
```
# dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
# dnf module install php:remi-8.4
# dnf install php php-intl php-pgsql httpd unzip
```
apache を起動します。
```
# systemctl enable httpd
# systemctl start httpd
```
SELinux ブール値を変更し、httpd がデータベースに接続できるようにします。
```
# setsebool -P httpd_can_network_connect_db 1
```
## Poweradmin のインストール
Poweradmin のリソースをダウンロードし、解凍します。
```
# curl -Lo v3.9.2.zip https://github.com/poweradmin/poweradmin/archive/refs/tags/v3.9.2.zip
# unzip v3.9.2.zip
```
Poweradmin のリソースを apache のデフォルトドキュメントルートにコピーし、またドキュメントルートの所有者を変更します。
```
# cp -r poweradmin-3.9.2/* /var/www/html/
# chown -R apache:apache /var/www/html/
```
FW の設定を実施します。
```
# firewall-cmd --add-service=http --permanent
# firewall-cmd --add-service=dns --permanent
# firewall-cmd --reload
```
## Poweradmin の設定
`http://192.168.182.10/install` にアクセスし、設定を行います。
まずは言語設定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/3aea2dee-f6c9-4ea2-bfdc-b9930ecbd738.png)
「DB が上書きされるが良いか？」という趣旨の質問ですが、初めてのインストールなので気にせず Step 3 に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/c6fe6443-3ab9-43df-b6a9-644b26c2a6f4.png)
データベースの接続設定と、Poweradmin の管理者パスワードを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/490deb0e-a41a-403c-8a32-2a9cb4df85b3.png)
Poweradmin が作成するデータベース用のユーザーとそのパスワード、またSOAレコードの hostmaster のメールアドレス、プライマリ/セカンダリ DNS の FQDN を設定します。（セカンダリまで必須です。ターシャリー以降は任意です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/76831eab-7aae-4f3c-a199-7e36674c61c9.png)
画面に表示の SQL 文を実行して次のステップに進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/7d4016de-e4d3-4a52-ae1f-1fa7fa7179d7.png)
```
# sudo -u postgres psql
# \c pdns
# <SQL文>
```
以下のファイルを作成します。
![スクリーンショット 2025-04-30 172418.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/6a333d96-ae6a-4016-a03c-805c35f63b64.png)
```/var/www/html/inc/config.inc.php
<?php 
$db_host = '127.0.0.1'; 
$db_name = 'pdns'; 
$db_user = 'padmin'; 
$db_pass = '<padmin password>'; 
$db_type = 'pgsql'; 

$session_key = '#zhYHWb3lENcvxc4mCDkSc!*SsZV-@tCA$F*%AHM9qBA^I'; 

$iface_lang = 'ja_JP'; 

$dns_hostmaster = 'hostmaster.example.com'; 
$dns_ns1 = 'dns1.example.com'; 
$dns_ns2 = 'dns2.example.com'; 
```
画面の指示の通りに`install/`ディレクトリを削除します。
これで Poweradmin がインストールできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/fa881470-74ee-4b56-b265-a91b943e136e.png)
```
# rm -f -R /var/www/html/install/
```
## 確認
ログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/682ac35d-8178-4ae6-8895-996d94e12ad6.png)
以下の画面に遷移します。「マスターゾーンを追加」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/c15ee747-5f38-415f-b00d-d93f29037edb.png)
ゾーン名を入力し、「ゾーンを追加」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/fbedf34e-2e96-4f70-b4cb-9991672bb497.png)
「Edit」を押下します。
![スクリーンショット 2025-04-30 173620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/e0d82b8e-352d-4a16-ad6c-c3ff9b1c7150.png)
以下のような SOA を持つゾーンが作成されます。
![スクリーンショット 2025-04-30 173707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/05ea0931-be3a-4e96-8ca8-45d9b1b83840.png)
ゾーンファイル形式で表示させると、このようになっています。
```
# pdnsutil edit-zone example.com.
; Warning - every name in this file is ABSOLUTE!
$ORIGIN .
example.com     86400   IN      SOA     dns1.example.com hostmaster.example.com 2025043000 28800 7200 604800 86400
```
レコードを追加します。A と NS を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/a2375b5f-28e9-49f6-af0e-35311c5f9446.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/8996a714-372c-4e60-8835-b1f662e73768.png)
以下のようなレコードの登録状態での名前解決を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/5c4e393c-9155-4a06-8034-53e3458c546c.png)
```
Resolve-DnsName dns1.example.com. -server 192.168.182.10

Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
dns1.example.com                               A      86400 Answer     192.168.182.10

Resolve-DnsName example.com. -server 192.168.182.10

Name                        Type TTL   Section    PrimaryServer               NameAdministrator           SerialNumber
----                        ---- ---   -------    -------------               -----------------           ------------
example.com                 SOA  86400 Authority  dns1.example.com            hostmaster.example.com      2025043011

Resolve-DnsName example.com. -server 192.168.182.10 -type NS

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
example.com                    NS     86400 Answer     dns1.example.com

Name       : dns1.example.com
QueryType  : A
TTL        : 86400
Section    : Additional
IP4Address : 192.168.182.10
```
逆引きゾーンを追加してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/ddd9141a-8478-4e70-b48f-70e4cf742375.png)
PTR と NS を登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/cdbac37b-9dc4-4173-88cb-62a6bf4a411b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/cf795e78-482a-4d3a-b3a1-41c2b0bef1de.png)
こちらも正常にクエリが返ります。
```
Resolve-DnsName 182.168.192.in-addr.arpa -server 192.168.182.10 -type NS

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
182.168.192.in-addr.arpa       NS     86400 Answer     dns1.example.com


Resolve-DnsName 192.168.182.10 -server 192.168.182.10

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
10.182.168.192.in-addr.arpa    PTR    86400 Answer     dns1.example.com
```
A/AAAA レコードを登録する際に「Also add a PTR record in the matching zone」にチェックを入れていると、該当する逆引きゾーンが存在する場合に自動的に PTR を登録してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/89abc0b9-3512-4861-b33a-9a11c18c7976.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/278b3a4f-7b87-4275-92da-2f5d0d8ff0fd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/703c96d6-e8fd-49d9-b1aa-856defcce335.png)
その逆として、PTR レコードを登録する際に「Also add an A/AAAA record in the matching zone」にチェックを入れていると該当の正引きゾーンが存在する場合に A/AAAA を登録してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/1f7072ae-f95d-457d-b494-f822b3aebdc1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/a95afbfc-e405-4193-85c4-1a64ed57ad0e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/dbe816f5-3ab7-44f8-b694-d465c8ef824b.png)