内部向けにDNSサーバーを構築する "PowerDNS Authoritative & Recursor"

公開日:2019-08-07
最終更新:2019-08-07

概要

内部DNS向けにDNSコンテンツサーバに PowerDNS Authoritative server を、また内部ドメイン・外部ドメインへの再帰問い合わせに対応させるため PowerDNS Recursor を導入する。

導入環境

  • CentOS Linux release 7.6.1810 (Core)
  • PowerDNS Authoritative Server 4.2
  • PowerDNS Recursor 4.2

構築

順番的には下記のような形。

  1. Install EPEL and Remi Repositories
  2. Install and Configure MariaDB
  3. Install PowerDNS & Recursor

レコード管理には PowerDNS-Admin などのツールがあるが、後ほどDNS以外の管理もしたいため、 phpIPAM をインストールする予定。
(phpIPAMは別でまとめる)

Install EPEL and Remi Repositories

最初に、PowerDNSとその依存パッケージをインストールする。
EPEL と PowerDNS のリポジトリとREMI for PHP 7.2をインストール。  

$ sudo yum -y install epel-release  
$ sudo yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm  
$ sudo curl -o /etc/yum.repos.d/powerdns-auth-40.repo https://repo.powerdns.com/repo-files/centos-auth-40.repo  

yum-utilsもインストールし、yum-config-managerでremiを有効にしておく。

$ sudo yum -y install yum-utils  
$ sudo yum-config-manager --enable remi-php72  

Install and Configure MariaDB

PowerDNSのバックエンドDBにMySQLを利用するので、MariaDBをインストールし、初期設定を済ませる。

$ sudo yum -y install mariadb mariadb-server  
$ sudo systemctl start mariadb  
$ sudo systemctl enable mariadb  

初期設定はmysql_secure_installationで行うこと。

$ sudo mysql_secure_installation  

Set root password? [Y/n] Y  
New password: <Tekito-na-Password>  
Re-enter new password: <Tekito-na-Password>  

Remove anonymous users? [Y/n] Y  
Disallow root login remotely? [Y/n] Y  
Remove test database and access to it? [Y/n] Y  
Reload privilege tables now? [Y/n] Y  

MySQLへPowerDNS用のDBを作成する。

$ sudo mysql -u root -p <Password>  
create database powerdns;  
grant all privileges on powerdns.* to [email protected] identified by 'powerdns';  
flush privileges;  

以下MySQLクエリを実行し、PowerDNSのテーブルを作成する。

use powerdns;  

 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                    BIGINT 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);  

 quit;  

上記のクエリを流し込むことでPowerDNSインストールの準備は完了。

Install PowerDNS & Recursor

パッケージをまとめてインストール。

$ sudo yum -y install pdns pdns-backend-mysql bind-utils pdns-recursor  

パッケージをインストール後、/ etc / pdns /に移動し、設定ファイルpdns.confを編集する。
下記はとあるサンプル。

allow-dnsupdate-from=192.168.1.0/24  
api=yes  
api-key=api-key  
api-logfile=/var/log/powerdns/pdns.log  

daemon=yes  
dnsupdate=yes  
guardian=yes  

launch=gmysql  
gmysql-host=localhost  
gmysql-user=powerdns  
gmysql-password=powerdns  
gmysql-dbname=powerdns  

local-address=127.0.0.1  
local-port=8053  

disable-syslog=yes  
log-dns-details=yes  
log-timestamp=yes  
logging-facility=0  
loglevel=6  

setgid=pdns  
setuid=pdns  

webserver=yes  
webserver-address=127.0.0.1  
webserver-port=8081  

通常、コンテンツDNSだけであればlocal-port=はDNS標準の53番ポートを設定するといいが、キャッシュDNSとして Recursor を同一サーバ上に構築しているため、ここではlocal-port=8053としている。
(root.hintsがない場合は IANA から取得して所定の位置に作成しておく)

次に Recursor の設定。
これも某所コンフィグをサンプルに投入。

allow-from=127.0.0.0/8,192.168.1.0/24  

config-dir=/etc/powerdns  
etc-hosts-file=/etc/hosts  
export-etc-hosts=on  

forward-zones=local.aaa.jp=127.0.0.1:8053, local.bbb.local=192.168.2.1;192.168.2.2  
forward-zones-recurse=.=8.8.8.8  

hint-file=/usr/share/dns/root.hints  

include-dir=/etc/powerdns/recursor.d  

local-address=192.168.1.1  
local-port=53  

log-common-errors=yes  
log-timestamp=yes  
logging-facility=0  
loglevel=6  

#quiet=yes  

security-poll-suffix=  
setgid=pdns  
setuid=pdns  

前述の通り、local-port=53とすることで、クライアントからの要求は Recursor が受け取り、内容によって外部か内部か振り分けるようにする。

動作確認

PowerDNS関連の起動と自動起動の有効化し、FWの設定を実行。

$ sudo systemctl start pdns  
$ sudo systemctl enable pdns  
$ sudo systemctl start pdns-recursor  
$ sudo systemctl enable pdns-recursor  
$ sudo firewall-cmd --add-port=53/tcp --permanent  
$ sudo firewall-cmd --add-port=53/udp --permanent  
$ sudo firewall-cmd --add-port=8053/tcp --permanent  
$ sudo firewall-cmd --add-port=8053/udp --permanent  
$ sudo firewall-cmd --reload  

あとはサーバ自身でdigなりnslookupで名前解決ができることを確認。
サーバで問題なければ、クライアント側でDNSサーバへ構築したサーバを指定して名前解決ができるか確認し、完了。
本構成の課題として、DDNS を行う場合にiptablesなどでNAT処理が必要になるが、コンテンツとキャッシュDNSを別建てすればそれも解決する。

記事が少しでもいいなと思ったらクラップを送ってみよう!
19
+1
The opinions expressed in this article are the author's own and do not reflect the view of company.

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする