#author("2019-01-01T22:08:43+09:00","default:nowsky","nowsky") #author("2019-09-08T00:09:28+09:00","default:nowsky","nowsky") *PowerDNS [#xe753079] バックエンドにMySQL・PostgreSQLなどのデータベースを利用出来る権威DNSサーバ(PowerDNS Authoritative Server)と、 端末からのDNSクエリを中継するキャッシュDNSサーバ(PowerDNS Recursor)の二種類がある。 DNS専用リバースプロキシのdnsdistも組み合わせる事で、 BIND相当の権威DNS・キャッシュDNSの同居DNSサーバを構築する事も出来る。 PowerDNSはAPIも用意されており、スクリプトで直にAPIを叩いたり、WebGUIから間接的に操作する事も出来る。 BINDのテキストゾーンファイルを読み込んだりTinyDNSとの連携もでき、他の権威DNSサーバとの親和性も高い。 WebGUIでゾーン編集ができる事から、PowerDNSをHiddenPrimaryにして実クエリは別の権威DNSで処理させる構成が多い。 ~ *参考サイト [#rf3adb39] -[[PowerDNS:+https://www.powerdns.com/]] -[[PowerDNS 3.1 On Debian 7 (Wheezy):+https://stacksetup.com/DNS/PowerDNSDebian]] ~ *構築環境 [#kd7a873d] OSはopenSUSEを利用しているがプログラムはソースからビルドしているので、 他ディストリビューションでも同様の手順で構築する事が出来る。 - 共通環境 OS :openSUSE Leap 42.3 PDNS:PowerDNS v4.1.4 #region(PowerDNS Authoritative Server) 今回は下記構成のPowerDNSをchrootモードで構築する。 バックエンドにはMySQLを利用するので事前にビルドしておく。 - [[Linux/Source/MySQL]] > PDNS Parameter user :pdns group:pdns --- > DB Parameter database:pdns_zone user :pdns_user password:pdns_pass #endregion ~ *インストール [#b38ee685] -&size(16){&font(b){1. インストール};}; 最近のOSはsystemdを使っている事が多いので、systemdモジュールを有効化する。 また、今回はバックエンドにMySQLを使うのでDBモジュールもビルドする。 luaは使う時が来そうなので一応ビルド。必要なければconfigureオプションから外す。 # zypper install lua53 lua53-devel systemd systemd-devel # wget https://downloads.powerdns.com/releases/pdns-4.1.4.tar.bz2 # tar jxvf pdns-4.1.4.tar.bz2 # cd pdns-4.1.4 # ./configure --prefix=/usr/local/powerdns --enable-tools --enable-systemd --with-lua --with-mysql=/usr/local/mysql # make # make install # ln -s /usr/local/powerdns/etc /etc/powerdns # cp /etc/powerdns/pdns.conf-dist /etc/powerdns/pdns.conf -&size(16){&font(b){2. コンフィグ作成};}; PowerDNSのコンフィグはテキストで作成する必要がある。 APIはPowerDNS単体では使わないので無効化しておき、APIを利用する外部ツールを使う時に有効化する。 DB接続は別ファイル化して必要に応じてパーミッションを絞っておく。 起動スクリプトについては、ソースコード同梱の物が上手く動かないので自作する。 #region(/etc/powerdns/pdns.conf) 8bit-dns=no # 8bitDNSクエリを拒否 allow-axfr-ips=127.0.0.1,::1 # DNSゾーン転送(AXFR)の許可IP # also-notify= # DNSゾーンに記載したNSサーバ以外にもゾーン更新(NOTIFY)を送信 # 通常はコメント化するか、パラメータ未設定にする any-to-tcp=yes # TCPリモート参照に応答させる。DNSリフレクション攻撃の防止になる api=no # REST APIを無効化 api-key=API-PASSWORD # REST APIの事前共有キー cache-ttl=60 # PowerDNSのDNSクエリ応答ローカルキャッシュ # この値はDNSゾーンのキャッシュとは違うので注意 chroot=/var/powerdns/chroot # PowerDNSをchroot動作させる時の起点ディレクトリ config-dir=/etc/powerdns # コンフィグを読み取るディレクトリ # コンフィグ自体に設定しても読めないので、pdns.serviceにも設定 disable-axfr=no # DNSゾーン転送を許可 disable-syslog=no # ログをsyslog出力する。標準出力に出す時はyesに変更 disable-tcp=no # TCPクエリにも応答させる disable-tcp=no # TCPクエリにも応答させる。"4.2.0-rc2"で削除された dnsupdate=no # DNS Update(DynamicDNS)を無効化 guardian=no # GuardianProcess内でのPDNS動作を無効化 # 有効にした方がセキュリティが向上するが、chrootと組み合わせるとハマる include-dir=/etc/powerdns/extra # 外部ファイルを保存するディレクトリ launch=gmysql # PowerDNSのバックエンドプログラム。2台のMySQLを参照させて冗長化も可能 local-address=0.0.0.0 # PowerDNSでLISTENするIPv4アドレス local-ipv6=:: # PowerDNSでLISTENするIPv6アドレス local-port=53 # Listenする時に利用するポート番号 log-dns-details=no # 詳細ログの出力を停止。Yesにするとログ出力が増えてパフォーマンスが下がる log-dns-queries=yes # DNSクエリログを出力。 Yesにするとログ出力が増えてパフォーマンスが下がる log-timestamp=yes # ログにタイムスタンプを追加 logging-facility=0 # 出力ログのsyslog-facility番号。local[0-7]のみ設定可能 loglevel=6 # ログ出力レベル。1~3は基本的に使わない。デバッグ時は9を設定 master=yes # PowerDNSをマスターとして動作 slave=yes # PowerDNSをスレーブとして動作 query-local-address=0.0.0.0 # PowerDNS自体が名前解決する時に利用する送信IPv4アドレス query-local-address6=:: # PowerDNS自体が名前解決する時に利用する送信IPv6アドレス query-logging=no # PowerDNS自体が名前解決したログ出力を無効化 setgid=pdnsd # daemon実行グループ setuid=pdnsd # daemon実行ユーザ daemon=yes # daemonとして動作 socket-dir=/var/run/powerdns # PowerDNSのソケットファイルとPIDの保存先 # chroot環境下ではchroot配下の絶体パスを設定 version-string=unknown # DNSのバージョン応答。秘匿する為にunknownに設定 webserver=no # Webサーバ機能。REST API利用時は有効にする webserver-address=127.0.0.1 # WebサーバのLISTEN IPアドレス webserver-allow-from=127.0.0.1,::1 # Webサーバにアクセス出来るIPアドレス webserver-password=PASSWORD # Webサーバにアクセスする際のパスワード webserver-port=8081 # Webサーバ/REST APIが待受けるポート番号 #endregion #region(/etc/powerdns/extra/gmysql.conf) gmysql-host=localhost gmysql-port=3306 gmysql-dbname=pdns_zone gmysql-user=pdns_user gmysql-password=pdns_pass gmysql-dnssec=no #endregion #region(/usr/lib/systemd/system/pdns.service) [Unit] Description=PowerDNS Authoritative Server Documentation=https://doc.powerdns.com/ Wants=network-online.target After=network-online.target mysqld.service mariadb.service rsyslog.service [Service] Type=forking ExecStart=/usr/local/powerdns/sbin/pdns_server --config-dir=/etc/powerdns ExecStop=/usr/local/powerdns/bin/pdns_control quit ExecReload=/usr/local/powerdns/bin/pdns_control reload ## OPTION Restart=on-failure RestartSec=1 StartLimitInterval=0 PrivateTmp=true PrivateDevices=true NoNewPrivileges=true ProtectSystem=full ProtectHome=true [Install] WantedBy=multi-user.target #endregion -&size(16){&font(b){3. 起動準備};}; chrootディレクトリの作成、パーミッション設定、DBスキーマの流し込みを行う。 PowerDNSはログ出力をsyslog経由でしか出来ない為、ログを書き出せる様にsyslogサーバの設定も変更する。 ただし、chroot環境下でPowerDNSのログをsyslog出力させるには、 PowerDNSのログを&color(#ff0000){syslog側でフックさせる為に、&font(b){ソケット(ログ出力デバイス)を作成する};};必要がある。 ・ユーザ作成と起動スクリプト設定 --- # groupadd pdnsd # useradd -g pdnsd -s /sbin/nologin -d /var/powerdns pdnsd # chmod 644 /usr/lib/systemd/system/pdns.service # chown root.root /usr/lib/systemd/system/pdns.service # systemctl enable pdns ・chrootディレクトリ作成 --- # mkdir -p /var/powerdns/chroot # mkdir -p /var/powerdns/chroot/dev # mkdir -p /var/powerdns/chroot/var/log # mkdir -p /var/powerdns/chroot/var/run/pdnsd # chmod 755 /var/powerdns/chroot/var/run/pdnsd # chown root.pdnsd /var/powerdns/chroot/var/run/pdnsd # cd /var/powerdns/chroot # touch ./var/log/api # chmod -R 755 ./var/log # chown -R pdnsd.pdnsd ./var/log # cd /var/powerdns/chroot/dev # mknod -m 644 ./null c 1 3 # mknod -m 644 ./zero c 1 5 # mknod -m 644 ./full c 1 7 # mknod -m 644 ./random c 1 8 # mknod -m 644 ./urandom c 1 9 ・DBスキーマ登録 --- MariaDB [(none)]> create database pdns_zone; MariaDB [(none)]> grant all on pdns_zone.* to pdns_user identified by 'pdns_pass'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> quit --- # cd ${PDNS_SRC}/modules/gmysqlbackend/ # mysql -u pdns_user -p pdns_zone < schema.mysql.sql ・rsyslog設定変更 --- # vi /etc/rsyslog.conf --- ## PowerDNS chroot log device $AddUnixListenSocket /var/powerdns/chroot/dev/log local0.* /var/log/powerdns & stop ~ *DNSゾーン登録 [#oe42fac7] バックエンドにMySQLを使っている場合、SQLコマンドでDNSゾーンを流し込むか、 BINDテキスト形式でゾーンを作った後に変換しながらDBに登録する方法がある。 今回はテスト用にDNSゾーンを登録する為、SQLコマンドで登録を行う。 # vi example.com-sql --- INSERT INTO domains (name,type) values ('example.com','NATIVE'); INSERT INTO records (domain_id,name,content,type,ttl,prio) VALUES (1,'example.com','localhost postmaster@example.com 1','SOA',86400,NULL); INSERT INTO records (domain_id,name,content,type,ttl,prio) VALUES (1,'example.com','ns1.example.com','NS',86400,NULL); INSERT INTO records (domain_id,name,content,type,ttl,prio) VALUES (1,'ns1.example.com','127.0.0.1','A',120,NULL); # mysql -u pdns_user -p pdns_zone < example.com-sql # dig @127.0.0.1 ns1.example.com ~ *起動テスト [#e739e825] 起動テストを行う場合、『pdns_server』コマンドをそのまま実行するとログが出てくる。 コンフィグを書き換えれば、ログを標準出力にしながらdaemon起動させる事も出来る。 ・起動 --- systemctl start pdns ・停止 --- systemctl stop pdns ・リロード --- systemctl reload pdns PowerDNSに登録したゾーン情報の書式確認を行う場合、チェックユーティリティを利用する。 セカンダリサーバへのゾーン転送が出来ない時は、書式間違いが多いので都度確認すること。 # /usr/local/powerdns/bin/pdnsutil check-all-zones --- Nov 09 23:32:41 Reading random entropy from '/dev/urandom' Checked 3 records of 'example.com', 0 errors, 0 warnings. Checked 1 zones, 0 had errors. ~ *PDNS Manager [#m5c0f702] PowerDNSをGUIで操作するフロントWebアプリケーション。 PHPで出来ているので、LAMPを構築してあれば大抵の環境で動作する。 &color(#ff0000){アプリの構造上、&font(b){サブディレクトリを掘ってPDNS Managerを動かす事が出来ない};};ので、 他にもWebアプリを動かしている環境下では、VirtualHostで別FQDNにホスティングする必要がある。 なお、PowerDNSのバックエンドDBをPDNS Manager用に作り直す必要があるので注意。 頑張れば、DB設定を直書きしたり個別にInsertすれば既存DBでも動くが説明は割愛。 - [[PDNS Manager:+https://pdnsmanager.org/]] #region(インストール) # wget https://dl.pdnsmanager.org/pdnsmanager-2.0.1.tar.gz # tar zxvf pdnsmanager-2.0.1.tar.gz # mv pdnsmanager-2.0.1 /var/www/pdnsmanager # chown -R root.www /var/www/pdnsmanager # chmod -R g-w,o-rwx /var/www/pdnsmanager # chown www.www /var/www/pdnsmanager/backend/config #endregion #region(VirtualHost設定) Listen 10080 <VirtualHost *:10080> ServerAdmin postmaster@localhost ServerName pdnsmanager.example.com DocumentRoot /var/www/pdnsmanager/frontend RewriteEngine On RewriteRule ^index\.html$ - [L] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d RewriteRule !^/api/\.* /index.html [L] <Directory /var/www/pdnsmanager/frontend> Require all granted </Directory> Alias /api /var/www/pdnsmanager/backend/public <Directory /var/www/pdnsmanager/backend/public> Require all granted RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [QSA,L] </Directory> </VirtualHost> #endregion #region(データベース再生成) DBにDNSゾーン情報が登録されていると、PDNS Managerからスキーマを流し込め無くなる。 そんな時はデータベースを別名で作成して、PowerDNSとPDNS ManagerのDB設定を切り替えるか、 既存のデータベースを一度削除した上で再登録を行う。 MariaDB [(none)]> drop database pdns_zone; MariaDB [(none)]> create database pdns_zone; MariaDB [(none)]> quit #endregion #region(データベース登録) 今回設定したFQDNを用いて、 Webブラウザで『h++p://pdnsmanager.example.com:10080/setup』を開く 細かい設定内容は[[公式ドキュメント:+https://pdnsmanager.org/quickstart/]]を確認しつつ設定する事。 #ref(Linux/Source/PowerDNS/wiki_powerdns_01.png,70%,left,nowrap) #endregion