MENU

自建DNS解析利器:PowerDNS+PowerDNS-Webinterface

January 7, 2018 • Read: 13975 • Linux阅读设置

偶然间看到PowerDNS的介绍,支持PTR解析,就心血来潮想给手里的自有IP做rDNS。
实现的时候发现国内网上对rDNS的原理介绍几乎为0,更别提怎么用PowerDNS去实现rDNS了,完全靠自己摸索,很蛋疼。还好身边有用过PowerDNS的朋友,遇到问题可以打辅助,折腾了一晚上弄好了,有必要记一下流水账,方便后人。

介绍:
PowerDNS支持的一些特性: EDNS Client Subnet、DNSSEC、GEODNS、IPv6等
同时 PowerDNS 支持超多的解析记录种类: A、AAAA、AFSDB、ALIAS(ANAME)、CAA、CERT、CDNSKEY、CDS、CNAME、DNSKEY、DNAME、DS、HINFO、KEY、LOC、MX、NAPTR、NS、NSEC、NSEC3、NSEC3PARAM、OPENPGPKEY、PTR、RP、RRSIG、SOA、SPF、SSHFP、SRV、TKEY、TSIG、TLSA、TXT、URI等
至于Web前端,PowerDNS官方推荐的是自家的PowerAdmin,然后我比对了一下,都是万年不更新,但是PowerAdmin UI保持上世纪末期的风格,PowerDNS-Webinterface好很多,同样水准下,当然是选择了更好看的后者啊。

工具:
PowerDNS:https://www.powerdns.com
PowerDNS-Webinterface:https://github.com/Spacefish/powerdns-webinterface
其它前端PowerAdmin:http://www.poweradmin.org

参考:
http://arstech.net/install-powerdns-and-powerdns-webinterface-on-centos/
拓展:
https://guozeyu.com/2016/08/self-host-dns/

环境:

Centos6 x64
PHP 5.6
Apache
MariaDB 10+

*本文章一切都是在为实现rDNS反向解析功能前提下进行的,并没有测试其它功能,不保证文章所述可以完全保证其它功能的使用。


PowerDNS部分

安装PowerDNS Mysql版本

yum install -y epel*
yum install -y pdns pdns-backend-mysql

修改配置文件 /etc/pdns/pdns.conf 我贴的是改好的,你只需要改配置文件底部的Mysql信息

setuid=pdns
setgid=pdns
launch=bind
# Autogenerated configuration file template
#################################
# add-superfluous-nsec3-for-old-bind    Add superfluous NSEC3 record to positive wildcard response
#
# add-superfluous-nsec3-for-old-bind=no

#################################
# allow-axfr-ips    Allow zonetransfers only to these subnets
#
# allow-axfr-ips=0.0.0.0/0,::/0

#################################
# allow-recursion    List of subnets that are allowed to recurse
#
allow-recursion=0.0.0.0/0

#################################
# any-to-tcp    Answer ANY queries with tc=1, shunting to TCP
#
# any-to-tcp=no

#################################
# cache-ttl    Seconds to store packets in the PacketCache
#
# cache-ttl=20

#################################
# chroot    If set, chroot to this directory for more security
#
# chroot=

#################################
# config-dir    Location of configuration directory (pdns.conf)
#
# config-dir=/usr/local/etc

#################################
# config-name    Name of this virtual configuration - will rename the binary image
#
# config-name=

#################################
# control-console    Debugging switch - don't use
#
# control-console=no

#################################
# daemon    Operate as a daemon
#
# daemon=no

#################################
# default-ksk-algorithms    Default KSK algorithms
#
# default-ksk-algorithms=rsasha256
    
#################################
# default-ksk-size    Default KSK size (0 means default)
#
# default-ksk-size=0

#################################
# default-soa-mail    mail address to insert in the SOA record if none set in the backend
#
# default-soa-mail=

#################################
# default-soa-name    name to insert in the SOA record if none set in the backend
#
# default-soa-name=a.misconfigured.powerdns.server

#################################
# default-ttl    Seconds a result is valid if not set otherwise
#
# default-ttl=3600

#################################
# default-zsk-algorithms    Default ZSK algorithms
#
# default-zsk-algorithms=rsasha256

#################################
# default-zsk-size    Default KSK size (0 means default)
#
# default-zsk-size=0

#################################
# direct-dnskey    Fetch DNSKEY RRs from backend during DNSKEY synthesis
#
# direct-dnskey=no

#################################
# disable-axfr    Disable zonetransfers but do allow TCP queries
#
# disable-axfr=no

#################################
# disable-tcp    Do not listen to TCP queries
#
# disable-tcp=no

#################################
# distributor-threads    Default number of Distributor (backend) threads to start
#
# distributor-threads=3

#################################
# do-ipv6-additional-processing    Do AAAA additional processing
#
# do-ipv6-additional-processing=yes

#################################
# edns-subnet-option-number    EDNS option number to use
#
# edns-subnet-option-number=20730

#################################
# edns-subnet-processing    If we should act on EDNS Subnet options
#
# edns-subnet-processing=no

#################################
# entropy-source    If set, read entropy from this file
#
# entropy-source=/dev/urandom

#################################
# experimental-json-interface    If the webserver should serve JSON data
#
# experimental-json-interface=no

#################################
# experimental-logfile    Filename of the log file for JSON parser
#
# experimental-logfile=/var/log/pdns.log

#################################
# fancy-records    Process URL and MBOXFW records
#
# fancy-records=no
    
#################################
# guardian    Run within a guardian process
#
# guardian=no

#################################
# include-dir    Include *.conf files from this directory
#
# include-dir=

#################################
# launch    Which backends to launch and order to query them in
#
# launch=

#################################
# load-modules    Load this module - supply absolute or relative path
#
# load-modules=

#################################
# local-address    Local IP addresses to which we bind
#
local-address=0.0.0.0

#################################
# local-ipv6    Local IP address to which we bind
#
# local-ipv6=

#################################
# local-port    The port on which we listen
#
local-port=53

#################################
# log-dns-details    If PDNS should log DNS non-erroneous details
#
# log-dns-details=

#################################
# log-dns-queries    If PDNS should log all incoming DNS queries
#
# log-dns-queries=no

#################################
# log-failed-updates    If PDNS should log failed update requests
#
# log-failed-updates=

#################################
# logging-facility    Log under a specific facility
#
# logging-facility=

#################################
# loglevel    Amount of logging. Higher is more. Do not set below 3
#
# loglevel=4

#################################
# lua-prequery-script    Lua script with prequery handler
#
# lua-prequery-script=

#################################
# master    Act as a master
#
# master=no

#################################
# max-cache-entries    Maximum number of cache entries
#
# max-cache-entries=1000000

#################################
# max-ent-entries    Maximum number of empty non-terminals in a zone
#
# max-ent-entries=100000

#################################
# max-nsec3-iterations    Limit the number of NSEC3 hash iterations
#
# max-nsec3-iterations=500

#################################
# max-queue-length    Maximum queuelength before considering situation lost
#
# max-queue-length=5000

#################################
# max-tcp-connections    Maximum number of TCP connections
#
# max-tcp-connections=10

#################################
# module-dir    Default directory for modules
#
# module-dir=/usr/local/lib

#################################
# negquery-cache-ttl    Seconds to store negative query results in the QueryCache
#
# negquery-cache-ttl=60

#################################
# no-shuffle    Set this to prevent random shuffling of answers - for regression testing
#
# no-shuffle=off

#################################
# out-of-zone-additional-processing    Do out of zone additional processing
#
# out-of-zone-additional-processing=yes

#################################
# overload-queue-length    Maximum queuelength moving to packetcache only
#
# overload-queue-length=0

#################################
# pipebackend-abi-version    Version of the pipe backend ABI
#
# pipebackend-abi-version=1

#################################
# prevent-self-notification    Don't send notifications to what we think is ourself
#
# prevent-self-notification=yes

#################################
# query-cache-ttl    Seconds to store query results in the QueryCache
#
# query-cache-ttl=20

#################################
# query-local-address    Source IP address for sending queries
#
# query-local-address=0.0.0.0

#################################
# query-local-address6    Source IPv6 address for sending queries
#
# query-local-address6=::

#################################
# query-logging    Hint backends that queries should be logged
#
# query-logging=no

#################################
# queue-limit    Maximum number of milliseconds to queue a query
#
# queue-limit=1500

#################################
# receiver-threads    Default number of receiver threads to start
#
# receiver-threads=1

#################################
# recursive-cache-ttl    Seconds to store packets for recursive queries in the PacketCache
#
# recursive-cache-ttl=10

#################################
# recursor    If recursion is desired, IP address of a recursing nameserver
#
# recursor=no

#################################
# retrieval-threads    Number of AXFR-retrieval threads for slave operation
#
# retrieval-threads=2

#################################
# security-poll-suffix    Domain name from which to query security update notifications
#
# security-poll-suffix=secpoll.powerdns.com.

#################################
# send-root-referral    Send out old-fashioned root-referral instead of ServFail in case of no authority
#
# send-root-referral=no

#################################
# server-id    Returned when queried for 'server.id' TXT or NSID, defaults to hostname
#
# server-id=

#################################
# setgid    If set, change group id to this gid for more security
#
# setgid=

#################################
# setuid    If set, change user id to this uid for more security
#
# setuid=

#################################
# signing-threads    Default number of signer threads to start
#
# signing-threads=3

#################################
# slave    Act as a slave
#
# slave=no

#################################
# slave-cycle-interval    Reschedule failed SOA serial checks once every .. seconds
#
# slave-cycle-interval=60

#################################
# slave-renotify    If we should send out notifications for slaved updates
#
# slave-renotify=no

#################################
# smtpredirector    Our smtpredir MX host
#
# smtpredirector=a.misconfigured.powerdns.smtp.server

#################################
# soa-expire-default    Default SOA expire
#
# soa-expire-default=604800

#################################
# soa-minimum-ttl    Default SOA minimum ttl
#
# soa-minimum-ttl=3600

#################################
# soa-refresh-default    Default SOA refresh
#
# soa-refresh-default=10800

#################################
# soa-retry-default    Default SOA retry
#
# soa-retry-default=3600

#################################
# soa-serial-offset    Make sure that no SOA serial is less than this number
#
# soa-serial-offset=0

#################################
# socket-dir    Where the controlsocket will live
#
# socket-dir=/var/run

#################################
# tcp-control-address    If set, PowerDNS can be controlled over TCP on this address
#
# tcp-control-address=

#################################
# tcp-control-port    If set, PowerDNS can be controlled over TCP on this address
#
# tcp-control-port=53000

#################################
# tcp-control-range    If set, remote control of PowerDNS is possible over these networks only
#
# tcp-control-range=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10

#################################
# tcp-control-secret    If set, PowerDNS can be controlled over TCP after passing this secret
#
# tcp-control-secret=

#################################
# traceback-handler    Enable the traceback handler (Linux only)
#
# traceback-handler=yes

#################################
# trusted-notification-proxy    IP address of incoming notification proxy
#
# trusted-notification-proxy=

#################################
# urlredirector    Where we send hosts to that need to be url redirected
#
# urlredirector=127.0.0.1

#################################
# version-string    PowerDNS version in packets - full, anonymous, powerdns or custom
#
# version-string=full

#################################
# webserver    Start a webserver for monitoring
#
# webserver=no

#################################
# webserver-address    IP Address of webserver to listen on
#
# webserver-address=127.0.0.1

#################################
# webserver-password    Password required for accessing the webserver
#
# webserver-password=

#################################
# webserver-port    Port of webserver to listen on
#
# webserver-port=8081

#################################
# webserver-print-arguments    If the webserver should print arguments
#
# webserver-print-arguments=no

#################################
# wildcard-url    Process URL and MBOXFW records
#
# wildcard-url=no

#################################
# xfr-max-received-mbytes    Maximum number of megabytes received from an incoming AXFR
#
# xfr-max-received-mbytes=100

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

接着我们登录mysql,创建一个名为 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                    INT 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);

下载PowerDNS-Webinterface,导入文件夹内包含的 install.sql 文件,在进行前端数据库导入的时候,可能会出现1个mysql报错,忽略掉,不影响本文章功能实现的使用
到这里,PowerDNS部署部分完成,我们使用下面的命令设置开机自启,以及立即启动PowerDNS

chkconfig --levels 235 pdns on
/etc/init.d/pdns start

可以顺便验证下PowerDNS服务是否正常启动

netstat -an | grep 53
cat /var/log/messages //如果没有启动 检查日志


PowerDNS-Webinterface部分

进入搭建好的Web环境根目录,导入PowerDNS-Webinterface中/web内的所有内容,并修改\configs\db.php中的mysql信息

<?php

/**
 * Please insert your MySQL Database in this configfile!
 */
$cfg['db'] = array(
    "default" => array(
        "host" => "localhost",
        "port" => 3306,
        "username" => "powerdns",
        "password" => "password",
        "database" => "powerdns",
    )
);

删除安全文件,并设置templates_c文件夹权限

rm -rf web\tmp\templates_c\DELETEME
chmod 777 \web\tmp\templates_c\

这时候访问你搭建好的PowerDNS-Webinterface,账号密码 admin/admin,登录后马上更改默认密码
20180107105944.png


设置PTR解析部分

切换至Domains菜单,添加你需要设置rDNS的IP段
在解析记录中添加下面的内容
20180107110800.png
图中ID 801-803是示例PTR记录

这时可以使用nslookup来看效果

yum install -y bind-utils
nslookup -qt=ptr 103.107.8.1

20180107114546.png
大功告成。
有问题在底部留言,不是很忙的话我会解答。

Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

2 Comments
  1. Yang Yang

    我只想知道你是如何申请到公网IP的

  2. 野火 野火

    dnssec如何开启的