PowerDNSでローカルDNSサーバー構築

top20190612_pdns

注意

pdns 4.1からrecursorオプションが廃止になっており、この方法は使えなくなっていません。

PowerDNS+MySQL+PowerAdminでローカルのDNSサーバーを構築しました。Web画面から自分の好きなようなレコードを追加する事ができます。また、広告のドメインと同じゾーンを作って、その先をREJECTされるマシンにしておけば広告ブロックも実現可能です。全体の構成は下記のような感じです。

tkp_rPJtX9HLMdoa5mjQAU.png

各機能の役割

PowerDNS

ローカルDNSの本体になる部分。ただこいつはキャッシュDNSの機能がありません。なので、自分の持ってないレコードは次にPowerDNS Recursorに投げる事になります。

PowerDNS Recursor

DNSキャッシュサーバーです。この機能はGooglePublicDNSなどでもいいかもしれません。同じサーバーで動かすとポート番号が競合して面倒なので、この例では127.0.0.1:5300として動作させます。

MySQL

PowerDNSのバックエンドのDBとして使います。PowerDNSで解決するレコードはすべてここのDBに保管します。

PowerAdmin

PHPで書かれたDBを管理するWebアプリケーションです。このアプリはあくまでDBを操作するアプリなので、PowerDNSと連携してるといった事は(多分)なく、独立してます。

インストール手順

なお、ここではDebianを想定してます。

PowerDNS Recursorのインストール

パッケージを入れて設定をちょちょっといじります。

# apt install pdns-recursor

初期設定のバックアップ

# cp /etc/powerdns/recursor.conf /etc/powerdns/recursor.conf~default

設定の変更。今回は下記の3箇所を変更しました。基本的にPowerDNSからの問い合わせを受けるだけなので、allow-fromは127.0.0.1だけにしておきます。

# diff -u /etc/powerdns/recursor.conf~default /etc/powerdns/recursor.conf
--- /etc/powerdns/recursor.conf~default	2017-06-27 21:31:08.000000000 +0900
+++ /etc/powerdns/recursor.conf	2017-10-21 01:18:47.407716257 +0900
@@ -2,7 +2,9 @@
 #################################
 # allow-from	If set, only allow these comma separated netmasks to recurse
 #
-# allow-from=127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10
+#allow-from=127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10
+
+allow-from=127.0.0.1
 
 #################################
 # allow-from-file	If set, load allowed netmasks from this file
@@ -173,12 +175,15 @@
 #################################
 # local-address	IP addresses to listen on, separated by spaces or commas. Also accepts ports.
 #
+#local-address=127.0.0.1
 local-address=127.0.0.1
 
+
 #################################
 # local-port	port to listen on
 #
 # local-port=53
+local-port=5300
 
 #################################
 # log-common-errors	If we should log rather common errors

起動設定・起動

# systemctl enable pdns-recursor
# systemctl start pdns-recursor

動作テスト

# dig @127.0.0.1 -p 5300 example.com
(正しくアドレスが引けていればOK)

PowerAdmin/MySQL

MySQL/Apache/PHPのインストール方法は省略しますが、DocumentRootは/var/www/htmで、PHPは既に動いてる想定で話を進めます。phpldapadmin-1.2.3.zipを取ってきて、/usr/local/src辺りに置いておきます。なお、通常は80や443ポートが使われると思いますが、広告ブロック用にこれらのポートはできればREJECTさせたいので、他のポートでApacheを動かす事をオススメします。SSLを有効にして8443とか。

# cd /var/www/html
# unzip /usr/local/src/phpldapadmin-1.2.3.zip
# mv phpldapadmin-1.2.3 phpldapadmin

MySQLでDBを作成します。DB名(powerdnsDB)、ユーザー名(POWERDNSUSER)、パスワード(POWERPASSWORD)は任意で決めて下さい。

# mysql
MySQL> CREATE DATABASE powerdnsDB;
MySQL> GRANT ALL ON 'powerdnsDB'.* TO 'POWERDNSUSER'@'localhost' IDENTIFIED BY 'POWERPASSWORD'

パッケージの中にテーブル作成用のSQLがあるのでこれを活用します。

# cd poweradmin
# mysql -u POWERDNSUSER -p < ./sql/powerdns-mysql-db-structure.sql
# mysql -u POWERDNSUSER -p < ./sql/poweradmin-mysql-db-structure.sql

SQLを流し込んだらWebからアクセスしてみましょう。初期ユーザーadmin、初期パスワードadminになっているので、一度ログインして変更します。 まだPowerDNSの設定をしていませんが、このツールが独立してるし、DBの構造がちゃんとなってるかの確認も込めて、PowerDNSよりも先に設定しておきます。

ゾーンの作成

PowerDNSの設定をまだしていませんが、WebとSQLができたので試しにローカルなゾーンを作成してみます。

ログインすると「Add master zone」があると思うので、それをクリックします。

ZoneNameを入れる訳ですが、例えばXXX.local.nogisawa.netみたいなサブドメインを運用したいとしたら、local.nogisawa.netというゾーンを作ると良いです。

こうするとnogisawa,netは内部で解決できないゾーンとしてキャッシュサーバーへ転送してくれます。

Zoneを追加するとlocal.nogisawa.net - Zone has been added successfully.と出ると思います。その文字がそのままリンクになってるのでクリックします。もちろんlistしてからでも可。

後は好きな名前を追加していきます。下記の画像ではnote-server.nogisawa.net→192.168.1.134という名前を登録しています。

tkp_SP6boE6t-hPcC.png

PowerDNS

ひとまずWebがちゃんと動いてるのを確認したら今度こそPowerDNSに着手します。まずはインストール。

# apt install pdns-server

設定を変更します。

# diff -u pdns.conf~default pdns.conf
--- pdns.conf~default	2017-01-20 08:05:09.000000000 +0900
+++ pdns.conf	2018-10-14 19:36:57.860616843 +0900
@@ -23,6 +24,7 @@
 # allow-recursion	List of subnets that are allowed to recurse
 #
 # allow-recursion=0.0.0.0/0
+allow-recursion=0.0.0.0/0, ::/0
 
 #################################
 # allow-unsigned-notify	Allow unsigned notifications for TSIG secured domains
@@ -255,6 +257,7 @@
 # local-address	Local IP addresses to which we bind
 #
 # local-address=0.0.0.0
+local-address=0.0.0.0
 
 #################################
 # local-address-nonexist-fail	Fail to start if one or more of the local-address's do not exist on this server
@@ -420,6 +423,8 @@
 # recursor	If recursion is desired, IP address of a recursing nameserver
 #
 # recursor=no
+#recursor=127.0.0.1:5300
+recursor=127.0.0.1:5300
 
 #################################
 # retrieval-threads	Number of AXFR-retrieval threads for slave operation

また、MySQL接続用のファイルも作成します。

# cat pdns.d/pdns.local.gmysql.conf 
# MySQL Configuration
#
# Launch gmysql backend
launch+=gmysql

# gmysql parameters
gmysql-host=localhost
gmysql-port=3306
gmysql-dbname=powerdnsDB
gmysql-user=POWERDNSUSER
gmysql-password=POWERPASSWORD
gmysql-dnssec=no
# gmysql-socket=

終わったら自動起動の設定をします

# systemctl enable pdns-server
# systemctl start pdns-server

広告ブロック対策

さて、ここから広告ブロックの設定をするわけですが、その前にDNSサーバーのアドレスの80/443に対して来たアクセスをすべてREJECTするようにufwで設定します。DROPだとタイムアウトまでブラウザが待ってしまうので必ずREJECTにしましょう。もし何も設定が入っていないならSSHや管理用のWeb(ここでは8443番ポート)の追加も忘れずに。

# ufw allow from any to any app OpenSSH
# ufw allow from any to any port 8443
# ufw reject from any to any app 'WWW'
# ufw reject from any to any app 'WWW Secure'

次にPowerAdminで広告ブロック向けのテンプレートを作成します。 PowerAdminの画面にtemplateを作成する所があるので、そこからadblockをいうテンプレートを作成しましょう。(もちろんテンプレートの名前は何でもいいです。)

tkp_0Eo1W-CGIUe5vYM-xMnhOBRoGfixiafi.png

上で言う192.168.1.3はDNSサーバーのアドレスです。このアドレスの80/443にアクセスするとREJECTされる動きをすれば、特別DNSサーバーにする必要はありません。 IPv6の行はなければなくてもいいです。

後はAdBlockテンプレートを使って広告のドメインをどんどん追加してけば良いです。

手始めにGoogleを追加して、様子を見ましょう。

tkp_X-V2xq70SrWQnzeJBXy6CraXIy6tQ-.png

DHCPサーバーへの設定も忘れずに

様子を見て良い感じに動いているようならDHCPサーバーで配るDNSサーバーにこのDNSを指定してみましょう。そういえばIPv6の時に配るDNSサーバーがあるからローカルDNSにもv6アドレスは何らか振る必要があるかも。。。

ちなみに

ちなみに自分はこの辺のドメインを登録した所、割と快適なネット生活を送れています。

+--------------------------+
| name                     |
+--------------------------+
| googlesyndication.com    |
| microad.jp               |
| i-mobile.co.jp           |
| cxense.com               |
| trafficfactory.biz       |
| i2ad.jp                  |
| gmossp-sp.jp             |
| thench.net               |
| bb-chat.tv               |
| bbchat.tv                |
| adresult.jp              |
| adingo.jp                |
| gsspat.jp                |
| mediad2.jp               |
| astrsk.net               |
| dtiserv.com              |
| adnxs.com                |
| images-amazon.com        |
| advertising.com          |
| hwcdn.net                |
| maist.jp                 |
| trafficjunky.net         |
| exosrv.com               |
| app-adforce.jp           |
| nex8.net                 |
| adjust.com               |
| amoad.com                |
| adcolony.com             |
| ladsp.com                |
| appetizers302vl.xyz      |
| a8.net                   |
| ads.nicovideo.jp         |
| taboola.com              |
| abbp1.pw                 |
| rk.com                   |
| ad-v.jp                  |
| easy2date.net            |
| sea-saw.com              |
| tsyndicate.com           |
| criteo.com               |
+--------------------------+

top20190612_pdns