14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Raspberry PiにPowerDNSをいれて自宅DNSサーバにした話

Last updated at Posted at 2017-01-02

#はじめに

手元に余っているRaspberry Pi 1 Model Aがあったので、自宅のLAN内で動作するDNSサーバをたてた話をします。

#前提

  • raspbian wheezy
root@raspberry-pi:~# lsb_release -da
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 7.11 (wheezy)
Release:	7.11
Codename:	wheezy

今回、Raspberry Piが初代の古いもののためか、raspberrypi.orgのRASPBIAN JESSIE だとうまくsshで接続できなかったので、wheezyを使っています。

また、ドメイン登録のためのWebFrontEndにPowerDNS-Adminを使いたかったので、WebAPIの機能からexperimentalが抜けている現時点で最新のPowerDNS 4.0.1を ソースコードからコンパイルしてインストールしています。

全体としてとりあえず動かすことを重視しています。セキュリティ的な観点が欠落しているので、ご留意ください。

PowerDNSのインストール

ソースコードのダウンロード

前提で話したように、現時点で最新のバージョンを使いたかったので、4.0.1のソースコードをダウンロードして解凍する。

# wget https://downloads.powerdns.com/releases/pdns-4.0.1.tar.bz2
# tar xvfj pdns-4.0.1.tar.bz2

依存のインストール

# apt-get update && apt-get upgrade
# apt-get install g++ libboost-all-dev libtool make pkg-config libmysqlclient-dev libssl-dev
# apt-get install flex
# apt-get install libbison-dev
# apt-get install libmysqld-dev mysql-server mysql-client

バックエンドにgmysqlを使うので、MySQLもインストールします。

コンパイルとインストール

# cd pdns-4.0.1
# ./configure
# make
# make install

./configure --helpすると、いろいろなオプションがでるので、必要なものを設定してください。今回は、とくに設定を加えることなく、そのままコンパイルしました。

また、コンパイル途中でエラーがでたら、エラーを確認して、足りないライブラリなどをインストールしてください。実際、コンパイルしている時に、boostに関連するエラーがでたので、libboost-devからlibboost-all-devを追加でインストールして解決しました。

MySQLの設定

DNSのレコードを管理するデータベースとテーブルをMySQL上に作成します。今回は、面倒だったので、rootで管理するようにしてしまっていますが、実際はセキュリティのために専用のMySQLのユーザを作成してください。

# mysql -uroot -p -e 'CREATE DATABASE powerdns'
# mysql -uroot -p powerdns < modules/gmysqlbackend/schema.mysql.sql

ソースコードの中のmodules/gmysqlbackend/schema.mysql.sqlにスキーマ情報があるので、それを実行します。

設定

gmysqlを使うための設定と、PowerDNS-Adminを使うためのAPIの設定をします。
ソースコードからコンパイルしてインストールした場合は、設定ファイルは/usr/local/etc/になります。pdns.conf-distを複製して編集します。

# cp /usr/local/etc/pdns.conf-dist /usr/local/etc/pdns.conf

編集箇所は以下になります。

diff pdns.conf-dist pdns.conf
50c50
< # api=no
---
> api=yes
55c55
< # api-key=
---
> api-key=your-powerdns-api-key
245c245
< # launch=
---
> launch=gmysql
540c540
< # webserver=no
---
> webserver=yes
---
> gmysql-host=localhost
> gmysql-dbname=powerdns
> gmysql-user=root
> gmysql-password=yourpassword

api-keyは、PowerDNSのWebAPIを使うための任意の文字列になります。PowerDNS-Adminの設定でも使います。

起動

動作確認のために、コマンドから実行して動作を確認します。

# pdns_server
Jan 02 04:28:46 Reading random entropy from '/dev/urandom'
Jan 02 04:28:46 This is a standalone pdns
Jan 02 04:28:46 Listening on controlsocket in '/var/run/pdns.controlsocket'
Jan 02 04:28:46 UDP server bound to 0.0.0.0:53
Jan 02 04:28:46 UDPv6 server bound to [::]:53
Jan 02 04:28:46 TCP server bound to 0.0.0.0:53
Jan 02 04:28:46 TCPv6 server bound to [::]:53
Jan 02 04:28:46 PowerDNS Authoritative Server 4.0.1 (C) 2001-2016 PowerDNS.COM BV
Jan 02 04:28:46 Using 32-bits mode. Built using gcc 4.7.2 on Dec 31 2016 07:28:24 by root@raspberry-pi.
Jan 02 04:28:46 PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
Jan 02 04:28:46 Listening for HTTP requests on 0.0.0.0:8081
Jan 02 04:28:46 Polled security status of version 4.0.1 at startup, no known issues reported: OK
Jan 02 04:28:46 Creating backend connection for TCP
Jan 02 04:28:46 About to create 3 backend threads for UDP
Jan 02 04:28:46 Done launching threads, ready to distribute questions

試しに別のshellを起動してdigを実行してみます。

# dig @127.0.0.1

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @127.0.0.1
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 8397
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;.				IN	NS

;; Query time: 14 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Jan  2 04:27:27 2017
;; MSG SIZE  rcvd: 17

正常に動作していないと、not foundと表示されると思います。

一度、Ctrl + cでpdns_serverを終了して、サービス起動スクリプトを用意します。
スクリプトはソースコード内のpdns/pdns.initを利用します。

# cp pdns/pdns.init /etc/init.d/pdns
# chmod +x /etc/init.d/pdns

複製したスクリプトのコメントの下、変数を定義する最初のところにPowerDNSをインストールしたフォルダのプリフィックスを追加します。

diff pdns/pdns.init /etc/init.d/pdns
18c18
<
---
> prefix=/usr/local

サービスから実行してみます。

# service pdns start
Starting PowerDNS authoritative nameserver: started
# service pdns status
16887: Child running on pid 16889

service pdns statusと実行して、pdnsが動いていることが確認できます。
以上で、PowerDNSの設定は完了です。

PowerDNS-Adminのインストール

まず、githubからソースコードをcloneしてきます。

# git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git

MySQLの設定

PowerDNS-Adminのデータを管理するようのデータベースをMySQL上に作ります。

# mysql -uroot -p -e 'CREATE DATABASE powerdnsadmin'

依存のインストール

pythonを使うので、それに関連するものをインストールします。

# apt-get install python-pip
# pip install MySQL-python
# pip install virtualenv
# cd PowerDNS-Admin
# virtualenv flask
# source ./flask/bin/activate
(flask)# pip install -r requirements.txt

設定

設定ファイルの雛形があるので、複製します。

(flask)# cp config_template.py config.py

必要となる設定は、上で作成したMySQLへ接続するための設定とPowerDNSのWebAPIにアクセスするための情報になります。

diff config_template.py config.py
6,7c6,7
< SECRET_KEY = 'We are the world'
< BIND_ADDRESS = '127.0.0.1'
---
> SECRET_KEY = 'abcdefghijkl' # 適当な文字列
> BIND_ADDRESS = '0.0.0.0' # とりあえず外部からみえるように一時的に
25,27c25,27
< SQLA_DB_USER = 'powerdnsadmin'
< SQLA_DB_PASSWORD = 'powerdnsadminpassword'
< SQLA_DB_HOST = 'mysqlhostorip'
---
> SQLA_DB_USER = 'root'
> SQLA_DB_PASSWORD = 'yourpassword'
> SQLA_DB_HOST = '127.0.0.1'
73,75c73,75
< PDNS_STATS_URL = 'http://172.16.214.131:8081/'
< PDNS_API_KEY = 'you never know'
< PDNS_VERSION = '3.4.7'
---
> PDNS_STATS_URL = 'http://127.0.0.1:8081/'
> PDNS_API_KEY = 'your-powerdns-api-key' # PowerDNSの設定で作成したAPI Keyを記述
> PDNS_VERSION = '4.0.1'

起動

起動する前に、データベースにスキーマの情報を流します。

(flask)# ./create_db.py

無事、成功したらPowerDNS-Adminを実行します。

(flask)# ./run.py
[INFO]  * Running on http://0.0.0.0:9393/ (Press CTRL+C to quit)
[INFO]  * Restarting with stat
[WARNING]  * Debugger is active!
[INFO]  * Debugger pin code: 246-032-548

9393ポートにブラウザでアクセスして、ログイン画面が表示されることを確認してください。

Screen Shot 2017-01-02 at 14.15.25 1.png

初期ユーザは用意されていないので、Create an accountをクリックして、ユーザを登録してログインできることを確認します。

ドメインの登録とドメインを使ったアクセス

次に、せっかくなのでPowerDNS-Adminへドメイン名pdns.rp.localを使ってアクセスできるようにします。

PowerDNS-Adminからドメインを登録

左側のメニューのNew Domainをクリックします。

表示されたページの、Enter a valid domain name (required)と書かれている入力エリアにrp.localと入力します。他は、そのままでSubmitをクリックします。

Screen Shot 2017-01-02 at 14.27.21.png

登録が完了すると、Dashboardの下部のHosted Domainsに登録したドメインが表示されていることが確認できます。

Screen Shot 2017-01-02 at 14.27.35.png

次に、rp.localのManageをクリックします。ここからレコードを登録することができるのでpdnsという名前でAレコードを追加します。IPアドレスは、Raspberry PiのIPアドレスを登録します。

Screen Shot 2017-01-02 at 14.28.14.png

Saveしたあと、右上にある、Apply Changesをクリックします。確認のモーダルが表示されるので、Applyをクリックすると設定が反映されます。

Nginxのインストール

特に最新のNginxの機能などを使う予定はないので、apt-getで普通にインストールします。

# apt-get install nginx

VirtualHostとプロキシの設定

9393ポートで動いているPowerDNS-Adminをドメイン付きでプロキシします。/etc/nginx/conf.dに設定ファイルを追加します。

pdns.rp.local.conf
server {
        listen 80;
        server_name pdns.rp.local;

        location / {
                proxy_pass http://localhost:9393;
        }
}

必要最低限の設定なので、必要に応じて設定を追加してください。

念のためconfigtestをしてスクリプトに問題がないことを確認したあとNginxを再起動します。

# service nginx configtest
Testing nginx configuration: nginx.
# service nginx restart

クライアント側のDNSの設定

最後にクライアント側の参照するDNSサーバに、Raspberry PiのIPアドレスを追加します。

通常ですと、ルータのDHCPサーバの設定に追加したりすると思うのですが、設定する場所が見つけられなかったので……。今回はMacのネットワーク設定に追加しました。自分の場合は、Raspberry PiのローカルIPが192.168.179.2となっているので、これを追加します。

Screen Shot 2017-01-02 at 14.37.45.png

ブラウザから、http://pdns.rp.local/にアクセスしてページが表示できることを確認します。

Screen Shot 2017-01-02 at 14.40.52.png

あとがき

当初、別のUbuntuマシンにDockerを使ってPowerDNSとPowerDNS-Adminを立てようと考えてました。ところが、libvirtが使っているdnsmasqと53/udpで衝突してしまい、どう頑張っても解決できませんでした。

そこで、Dockerを動かしていないまっさらなRaspberry Pi上のLinuxならできるだろうと思い、なんとか動作させることができました。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?