DNSサーバー PowerDNS の導入

PowerDNSは、高性能で安定したDNSサーバソフトウェアです。オープンソースのプロジェクトとして開発されており広く普及しています。

目次

特徴

  • モジュール式アーキテクチャ: PowerDNSは柔軟なモジュール式アーキテクチャを採用しており、拡張性が高いです。バックエンドシステムとして、MySQL, PostgreSQL, SQLite, LDAPなどを利用することができます。
  • 高いパフォーマンス: PowerDNSは、大規模なDNS設定も効率的かつ高速に管理することができます。
  • API対応: RESTful APIを介して設定や管理が可能であり、自動化やリモートからの操作が容易です。
  • セキュリティ: PowerDNSは、セキュリティに力を入れており、DNSSEC (Domain Name System Security Extensions) やDNS-over-TLS/HTTPSなどのセキュリティ機能をサポートしています。
  • IPv6対応: PowerDNSはIPv6をフルサポートします。

PowerDNS Authoritative Serverをインストールする

必要なリポジトリを追加する

まず、EPEL (Extra Packages for Enterprise Linux) リポジトリとPowerDNS公式リポジトリを追加します。

sudo yum install epel-release -y
sudo curl -o /etc/yum.repos.d/powerdns-auth-48.repo https://repo.powerdns.com/repo-files/centos-auth-48.repo

PowerDNS Authoritative Serverとバックエンドデータベースをインストール

この例では、MySQLバックエンドを使用しています。

sudo yum install pdns pdns-backend-mysql -y

MariaDB(MySQL) をインストールおよび設定する

MariaDB(MySQL)は導入済みという前提です。

あわせて読みたい
MariaDB(MySQL) の導入 MariaDBは、MySQLをベースに開発されたオープンソースのデータベース管理システムです。MySQLからのリレーショナルデータベース管理システムMariaDBは、性能の向上や新...

MariaDB(MySQL) サーバーをインストールし、PowerDNSのためのデータベースとユーザーを作成します。

データベースとユーザーを作成し、権限を付与します。

mysql -u root -p
CREATE DATABASE powerdns;
GRANT ALL ON powerdns.* TO 'powerdns'@'localhost' IDENTIFIED BY 'ここにパスワード';
FLUSH PRIVILEGES;
EXIT;

スキーマをインポートします。

mysql -u powerdns -p powerdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql

PowerDNSを設定する

pdnsから設定ファイルを読み込めるようにします。

chown -R pdns.pdns /etc/pdns

/etc/pdns/pdns.confファイルを編集して、MySQLバックエンドを設定します。

sudo vi /etc/pdns/pdns.conf

最下行に以下を追加します。

launch=gmysql
gmysql-host=localhost
gmysql-user=powerdns
gmysql-password=ここにパスワード
gmysql-dbname=powerdns

設定後、PowerDNSサービスを有効化して起動します。

sudo systemctl enable pdns
sudo systemctl start pdns

ファイアウォールの設定

DNSサーバーに接続できるように、ファイアウォールの設定を変更します。

sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --reload

これで、CentOSでPowerDNSを使用したセキュアなDNSサーバーが構築されました。必要に応じて、レコードをデータベースに追加し、DNSクライアントで名前解決をテストできます。

Poweradmin の導入

Poweradminは、PowerDNSサーバをWebベースで管理するためのPHPアプリケーションです。次の手順に従って、Poweradminを導入します。

前提条件

  • PowerDNSとそのバックエンドデータベース(MySQL, PostgreSQLなど)が設定済みであること
  • Webサーバ(ApacheやNginx等)がインストールされていること
  • PHPがインストールされており動作していること

Poweradminのダウンロード

公式GitHubリポジトリから最新版のPoweradminをダウンロードして解凍します。

wget https://github.com/poweradmin/poweradmin/archive/refs/tags/v3.5.1.tar.gz
tar -zxvf v3.5.1.tar.gz

解凍したファイルをWebサーバのドキュメントルートにコピー

例として、Apacheのドキュメントルート/var/www/html/poweradminにコピーします。

mv poweradmin-3.5.1 /var/www/html/poweradmin

データベースの設定

PoweradminとPowerDNSのデータベースを分ける必要はありません。
PowerDNSで設定したデータベースをそのまま利用します。

Poweradminのインストールウィザードにアクセス

Webブラウザで、Poweradminのインストールウィザードにアクセスします。

https://your_domain/poweradmin/install/

以下のような画面が表示されましたら、インストールウィザードに表示される手順に従い、以下の設定を行います。

データベース情報はPowerDNSに設定したものを入力します。
Poweradmin管理者のパスワードは、Poweradminの初期アカウント admin のパスワードです。

ホストマスター、ネームサーバーは必須です。
設定しないと、SOAレコードが正しく登録されずレコードが参照できなくなりますので、正しく設定してください。

以上で、Poweradminの導入が完了しました。WebブラウザからPowerDNSサーバを管理できるようになります。

日本語でエラーlocale表示がでる不具合を直す

Error: Failed to set locale. Selected locale may be unsupported on this system. Please contact your administrator.

このエラーが日本語にすると、画面上部に表示されます。
localeを $iface_lang . ‘.UTF-8’ によって生成してるプログラムを変更します。

vi inc/i18n.inc.php
    #$locale = setlocale(LC_ALL, $iface_lang, $iface_lang . '.UTF-8');
    $locale = setlocale(LC_ALL, $iface_lang, $iface_lang . '.utf8');

locale -a で表示される方にあわせました。

locale -a
C
C.utf8
POSIX
ja_JP.eucjp
ja_JP.utf8

localectl list-locales
C.UTF-8
ja_JP.UTF-8

トラブルシューティング

PowerDNSのサービスは正常に動作しているのに、digコマンド等で確認すると応答が返ってこない場合は、登録済みのレコードを確認します。当該ドメインに1つでも異常のあるレコードがあると、そのドメインの全てのレコードが使用できません。特に、Poweradminを使用する場合は、SOAレコードに必要情報が不足した状態でも登録されてしまうため、まずSOAレコードを確認されることをお勧めします。
pdnsutil check-zone で確認すると参考になる情報が得られると思います。

pdnsutil check-zone example.com
[Error] SOA lookup failed for zone 'example.com': Out of range exception parsing '  2023060901 28800 7200 604800 86400'
[Info] SOA autocomplete is deprecated, missing field(s) in SOA content: example.com IN SOA '  2023060901 28800 7200 604800 86400'
[Warning] Parsed and original record content are not equal: example.com IN SOA '  2023060901 28800 7200 604800 86400 0 0' (Content parsed as '2023060901. 28800. 7200 604800 86400 0 0')
[Error] No NS record at zone apex in zone 'example.com'
Checked 2 records of 'example.com', 2 errors, 1 warnings.

dig コマンド

dig(Domain Information Groper)はDNS(ドメインネームシステム)の問い合わせと表示を行うコマンドラインツールです。以下に、一般的な使い方とオプションを示します。

あわせて読みたい
dig コマンド と DNS dig コマンドは、DNS クエリを実行し、その結果を表示するためのツールです。AlmaLinux 9.2 でも利用するには、bind-utils パッケージをインストールする必要があります...

基本的な使用方法

ドメイン名のIPアドレスを調べる場合、次のように実行します。

dig example.com

特定のレコードタイプの問い合わせ

特定のレコードタイプ(A, AAAA, MX, NS, CNAME, SOA, TXT など)を指定して問い合わせます。

dig MX example.com

短い結果の表示

結果を短くする場合(回答セクションのみ表示)、+short オプションを使用します。

dig example.com +short

特定のDNSサーバーからの問い合わせ

特定のDNSサーバーに対して問い合わせる場合、サーバーのIPアドレスまたはホスト名を指定します。

dig @8.8.8.8 dns.google

; <<>> DiG 9.16.23-RH <<>> @8.8.8.8 dns.google
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59341
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;dns.google.			IN	A

;; ANSWER SECTION:
dns.google.		625	IN	A	8.8.8.8
dns.google.		625	IN	A	8.8.4.4

;; Query time: 3 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Jun 10 12:12:33 JST 2023
;; MSG SIZE  rcvd: 71

逆引きの問い合わせ

IPアドレスからドメイン名を取得するために、-x オプションを使用します。

dig -x 8.8.8.8

; <<>> DiG 9.16.23-RH <<>> -x 8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24363
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;8.8.8.8.in-addr.arpa.		IN	PTR

;; ANSWER SECTION:
8.8.8.8.in-addr.arpa.	86400	IN	PTR	dns.google.

;; Query time: 358 msec
;; SERVER: 157.7.180.133#53(157.7.180.133)
;; WHEN: Sat Jun 10 12:12:59 JST 2023
;; MSG SIZE  rcvd: 73

PowerDNS を Native運用する

PowerDNSをMariaDBのレプリケーション機能とともにNativeで運用するためには、以下のようなステップが必要です。これらのステップを通じて、一つのMariaDBサーバ(マスター)上の変更が他のMariaDBサーバ(スレーブ)に同期される設定を行います。

Master側の設定

レプリケーションを開始する前に、すでにレコードが登録されている場合は、予めSlave側にインポートしておきましょう。

sudo vi /etc/my.cnf.d/mariadb-server.cnf 
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid

# 以下を追加する binlog_do_dbにレプリケーションしたいデータベースを指定する
server-id   = 1
log_bin     = /var/log/mariadb/mariadb-bin.log
binlog_do_db  = powerdns

外部からの接続を許可するために
bind-address=0.0.0.0をコメントアウトします。

[galera]
# Mandatory settings
#wsrep_on=ON
#wsrep_provider=
#wsrep_cluster_address=
#binlog_format=row
#default_storage_engine=InnoDB
#innodb_autoinc_lock_mode=2
#
# Allow server to accept connections on all interfaces.
#
bind-address=0.0.0.0
#
# Optional setting
#wsrep_slave_threads=1
#innodb_flush_log_at_trx_commit=0

# this is only for embedded server

MariaDB サーバを再起動します。

sudo systemctl restart mariadb.service 

レプリケーション用ユーザーを作成し、そのユーザーがスレーブから接続できるように許可する。

mysql -u  root -p

passwordは任意のものに変更してください。 replication_userは任意のものに問題ありませんが、レプリケーション用と分かりやすい名前にしておくと良いでしょう。

GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
MariaDB [(none)]> SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000001 |      330 | powerdns     |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.000 sec)

Position のところにある、数字を覚えておきます。 ここでは「330」です。

firewalld の設定

slaveサーバーから 3306/tcp を許可する必要があります。

firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="***.***.***.*" port protocol="tcp" port="3306" accept'

firewall-cmd --reload

firewall-cmd --list-all

Slave側の設定

レプリケーション開始前に、master側にレコードがある場合は、予めインポートしておいてください。

sudo vi /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid

# 以下を追加
server-id      = 2
relay_log      = /var/log/mariadb/mariadb-relay-bin.log
log_bin        = /var/log/mariadb/mariadb-bin.log
binlog_do_db   = powerdns

MariaDB サーバを再起動します。

sudo systemctl restart mariadb.service 
mysql -u root -p
CHANGE MASTER TO MASTER_HOST='master_host_ip',
MASTER_USER='replication_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mariadb-bin.000001', 
MASTER_LOG_POS= 330;


START SLAVE;

Slave側のMariaDBの再起動は不要です。

MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: ***.***.***.**
                   Master_User: replication_user
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mariadb-bin.000002
           Read_Master_Log_Pos: 344
                Relay_Log_File: mariadb-relay-bin.000002
                 Relay_Log_Pos: 557
         Relay_Master_Log_File: mariadb-bin.000002
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
               Replicate_Do_DB: 
           Replicate_Ignore_DB: 
            Replicate_Do_Table: 
        Replicate_Ignore_Table: 
       Replicate_Wild_Do_Table: 
   Replicate_Wild_Ignore_Table: 
                    Last_Errno: 0
                    Last_Error: 
                  Skip_Counter: 0
           Exec_Master_Log_Pos: 344
               Relay_Log_Space: 868
               Until_Condition: None
                Until_Log_File: 
                 Until_Log_Pos: 0
            Master_SSL_Allowed: No
            Master_SSL_CA_File: 
            Master_SSL_CA_Path: 
               Master_SSL_Cert: 
             Master_SSL_Cipher: 
                Master_SSL_Key: 
         Seconds_Behind_Master: 0
 Master_SSL_Verify_Server_Cert: No
                 Last_IO_Errno: 0
                 Last_IO_Error: 
                Last_SQL_Errno: 0
                Last_SQL_Error: 
   Replicate_Ignore_Server_Ids: 
              Master_Server_Id: 1
                Master_SSL_Crl: 
            Master_SSL_Crlpath: 
                    Using_Gtid: No
                   Gtid_IO_Pos: 
       Replicate_Do_Domain_Ids: 
   Replicate_Ignore_Domain_Ids: 
                 Parallel_Mode: optimistic
                     SQL_Delay: 0
           SQL_Remaining_Delay: NULL
       Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
              Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
    Slave_Transactional_Groups: 0
1 row in set (0.000 sec)

ERROR: No query specified
          Slave_IO_Running: Yes
         Slave_SQL_Running: Yes

このような表示になれば動作しているかと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次