Total Pageviews

Tuesday, 21 August 2012

powerdns 的安装


 
如果你不想使用BIND配置DNS服务器,那么PowerDNS会是一个不错的选择.

介绍 powerdns 结合 mysql 的安装配置方法
      

介绍

powerdns + mysql + webadmin 简单管理域名服务器

系统环境

centos 或者 debian

申请域名,并把域名解析权转移到自己的服务器上

申请域名服务器,推荐到 namecheap 申请,申请完成域名以后,需要把自己的域名转移到自己的dns服务器中,方法如下,折腾好namecheap 以后,开始自己搭建 dns server

安装mysql server 及必须的软件包

debian
apt-get install mysql-server mysql-client  pdns-server pdns-backend-mysql 
centos
yum install pdns-backend-mysql -y

软件包安装完成以后,开始配置

  1. mysql server 配置
修改/etc/mysql/my.cnf 修改监听端口为 127.0.0.1 如下
[...]
bind-address           = 127.0.0.1
[...]
然后重启 mysql server
  • 创建 powerdns 默认是数据库
登陆mysql ,并创建数据库,命令如下
mysql -u root -p# 创建所需数据库
CREATE DATABASE powerdns;
# 为powerdns 数据库创建用户并指派权限, power_admin_password 为密码,可以自己修改
GRANT ALL ON powerdns.* TO 'power_admin'@'localhost' IDENTIFIED BY 'power_admin_password';
GRANT ALL ON powerdns.* TO 'power_admin'@'localhost.localdomain' IDENTIFIED BY 'power_admin_password';
FLUSH PRIVILEGES;
# 导入基本数据
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)
);
# 创建索引
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(6) DEFAULT NULL,
content VARCHAR(255) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
primary key(id)
);
#
CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
#
CREATE TABLE supermasters (
ip VARCHAR(25) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) DEFAULT NULL);
# 退出
quit
  • 编辑powerdns 配置文件 /etc/powerdns/pdns.conf ,使其使用mysql 数据库,找到如下字段,修改如下, recursor 表示如果查询的域名不在本机上,则向上级域名服务器查询,查询的地址为 192.168.1.254
[...]
# 注释如下行
#################################
# allow-recursion       List of netmasks that are allowed to recurse
allow-recursion#allow-recursion
#################################
# launch        Which backends to launch and order to query them in
#
# launch=
launch=gmysql[...]
#################################
# recursor      If recursion is desired, IP address of a recursing nameserver
#
recursor=192.168.1.254
#################################

debian 需要如下步骤

修改如下文件
vim /etc/powerdns/pdns.d/pdns.local
修改成如下
# Here comes the local changes the user made, like configuration of
# the several backends that exists.

gmysql-host=127.0.0.1
gmysql-user=power_admin
gmysql-password=power_admin_password
gmysql-dbname=powerdns

centos 需要如下步骤

centos 的系统,不需要创建 pdns.local 文件,直接把上面的几句话,添加到 pdns.conf 文件的末尾,如下
gmysql-host=127.0.0.1
gmysql-user=power_admin
gmysql-password=power_admin_password
gmysql-dbname=powerdns
然后重启 powernds 服务
/etc/init.d/pdns restart
到此步骤,powernds 安装设定完毕

检查安装是否成功

打开日志文件 tail /var/log/messages,内容应该如下
Jan 10 15:59:43 ip-10-150-167-111 pdns[29860]: TCP server bound to 0.0.0.0:53
Jan 10 15:59:43 ip-10-150-167-111 pdns[29860]: PowerDNS 2.9.22 (C) 2001-2009 PowerDNS.COM BV (Dec 14 2010, 18:18:42, gcc 4.4.4 20100726 (Red Hat 4.4.4-13)) starting upJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: 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 10 15:59:43 ip-10-150-167-111 pdns[29860]: Creating backend connection for TCPJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: gmysql Connection succesfulJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: About to create 3 backend threads for UDPJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: gmysql Connection succesfulJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: gmysql Connection succesfulJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: gmysql Connection succesfulJan 10 15:59:43 ip-10-150-167-111 pdns[29860]: Done launching threads, ready to distribute questions

安装 powerdns admin

基于web的管理方式,很好用
apt-get install apache2 libapache2-mod-php5 php5 php5-common\
 php5-curl php5-dev php5-gd php-pear php5-imap php5-mcrypt\
 php5-mhash php5-ming php5-mysql php5-xmlrpc gettext
如果提示如下,选 yes
Continue installing libc-client without Maildir support? <-- Yes

debian 系统

安装完成基本包以后,安装如下
pear install DB
pear install pear/MDB2#mysql

centos 系统

yum install php-pear-DB php-pear-MDB2 php-pear-MDB2-Driver-mysqli php-pear-MDB2-Driver-mysql
php包安装完成以后,下载 powerdns admin 软件包,并配置 其官方网站为 https://www.poweradmin.org/trac/wiki/GettingPoweradmin 下载开始安装,最新的为 2.1.5
cd /tmp
wget https://www.poweradmin.org/download/poweradmin-2.1.5.tgz
tar xvfz poweradmin-2.1.5.tgz
mkdir -p /var/www/poweradmin
mv poweradmin-2.1.5/* /var/www/poweradmin
touch /var/www/poweradmin/inc/config.inc.php
chown -R www-data:www-data /var/www/poweradmin/
安装完成以后,打开浏览器 如 (http://server1.example.com/poweradmin/install or http://192.168.0.100/poweradmin/install).

继续下一步

继续,输入 mysql 的root 密码,非 刚才创建的 powerdns 用户的密码 ,这里注意哦

继续,这里输入power_admin 密码,也就是创建的 powerdns 的数据库密码,主机名就是你的主机名字,nameserver 就是你刚才在namecheap 注册的dns 名字,一般自己写个就可以了

接着下一步

继续

继续,默认即可

系统为了安装期间,安装完成以后,需要删除 install 目录
rm -fr /var/www/poweradmin/install/
到这里,web管理页面安装完成,输入 http://server1.example.com/poweradmin or http://192.168.0.100/poweradmin 看看吧


创 建 zone, go to Add master zone and fill in the domain name (e.g. example.com). You can already fill in the IP addresses for the www A record ("webserver") and the MX record ("mailserver") for that zone. If you leave the Create zone without applying records-template checkbox unchecked, Poweradmin will automatically create some NS, A (e.g. www) and MX records for that zone.

FROM http://code.google.com/p/unxmail/wiki/powerdns
---------------


近期在琢磨DNS的东西,目的是相弄一个智能DNS,分国家来解析到不同的主机,访问各个主机上的内容.
bind搞了,powerDNS也搞了,整体看下来,虽然Bind是大多数的选择,但是powerDNS却也是个不错的选择. 本文记录下powerDNS的一些东西
首先找到官网,看文档,部署很简单 https://doc.powerdns.com/md/authoritative/installation/
powerDNS部署完后,可以考虑部署一个poweradmin,方便管理
yum -y install httpd php php-devel php-gd php-imap php-ldap php-mysql php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-mhash gettext
yum install php-pear-DB php-pear-MDB2-Driver-mysql
cd /tmp
wget http://soft.laozuo.org/powerdns/poweradmin-2.1.7.tgz
tar zxvfpoweradmin-2.1.7
mv poweradmin-2.1.7 /var/www/html/poweradmin
touch /var/www/html/poweradmin/inc/config.inc.php
chown -R apache:apache /var/www/html/poweradmin/
最后,如果要做转发,可以修改/etc/pdns/pdns.conf配置文件
加上这段
# 外网权威服务器(可以多个)
# 对于本地并没有记录的域名将转发到其他递归DNS服务器解析
recursor=8.8.8.8
recursor=119.29.29.29
# 开启的线程数(根据访问量设置)
distributor-threads=100
# 最大链接数(根据访问量设置)
max-tcp-connections=1000
#web控制面板默认端口:8081(可以用于通过web监控DNS服务器的解析数据)
webserver=yes
webserver-address=0.0.0.0
参考
https://doc.powerdns.com/md/authoritative/installation/
http://onlyzq.blog.51cto.com/1228/526504/
http://www.laozuo.org/3924.html
http://baijindong.cn/index.php/archives/7/
---------------------

HOWTO install PowerDNS on CentOS

PowerDNS Authoritative Server is a great choice for handling DNS for your organization. For a successful install (and for this howto in particular) you’ll need a Linux server running CentOS. This HOWTO will show you how to get a working pdns nameserver going along with a great web front-end.
The most common way to set up PowerDNS (pdns) on multiple servers (ns1, ns2, etc…) is to enable MySQL replication from the master (ns1) and the slave(s) (ns2, ns3). That’s going to be part 2 of this HOWTO. Let’s just get pdns set up on our master and answering queries for now…
First, let’s make sure mysql is installed:
1
2
yum install mysql mysql-server -y

Let’s edit the /etc/my.cnf file and make sure that skip-networking is commented out
1
2
#skip-networking

Now make sure it starts when booting into levels 2, 3, 5 and we can start it up
1
2
3
chkconfig --levels 235 mysqld on
service mysqld start

Check via netstat that mysql is listening on all interfaces:
1
2
3
netstat -tap |grep "*:mysql"
tcp 0 0 *:mysql *:* LISTEN 20319/mysqld

Set the mysql root password (without it showing up in your bash history!)
1
2
3
/usr/bin/mysql_secure_installation
(follow the prompts/questions)

Now we’re ready to install powerdns:
1
2
yum install pdns pdns-backend-mysql

Connect to mysql, create the database, set the permissions, add some tables for pdns: (make sure to replace ‘pdns_admin_pass’ with something else!)
1
2
3
mysql -u root -p
CREATE DATABASE powerdns;

Modify the following two lines with your own password
1
2
3
GRANT ALL ON powerdns.* TO 'pdns_admin'@'localhost'IDENTIFIED BY 'pdns_admin_pass';
GRANT ALL ON powerdns.* TO 'pdns_admin'@'localhost.localdomain' IDENTIFIED BY 'pdns_admin_pass';

Feel free to paste the rest of this in all at once
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
FLUSH PRIVILEGES;
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)
);
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(6) DEFAULT NULL,
content VARCHAR(255) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
primary key(id)
);
CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE TABLE supermasters (
ip VARCHAR(25) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) DEFAULT NULL
);

No issues?  Ok, quit out..
1
2
quit

Edit /etc/pdns/pdns.conf and tell it how to connect:
1
2
3
4
5
6
launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=pdns_admin
gmysql-password=pdns_admin_password
gmysql-dbname=powerdns

Make sure pdns starts on boot & start it up:
1
2
3
chkconfig --levels 235 pdns on
service pdns start

This server should now answer on domains its authoritative for. Other domains, however, it has no idea. Let’s tell pdns to look at another server for recursion. Edit the /etc/pdns/pdns.conf file and modify your recursion lines:
1
2
3
4
5
# allow recursion for our subnet only (default allows recursion for everyone)
allow-recursion=192.168.0.0/24
# recursion server
recursor=192.168.0.1

Web based frontend:There are many web based frontends out there for pdns. We’re going to use ‘PowerDNS-Webinterface‘ It’s a great looking, simple GUI that uses easy templates so that you can make it your own once you’re done. Plus, it has multi-user support – create sub-accounts for your users!
Let’s make sure we have some pre-reqs installed:
1
2
yum install httpd php php-mysql gettext -y

Make sure you’re running at least PHP 5.2:
1
2
3
4
php -v
PHP 5.3.8 (cli) (built: Oct 31 2011 18:26:52) 
Copyright (c) 1997-2011 The PHP Group

Download the latest powerdns-webinterface package: http://code.google.com/p/powerdns-webinterface/downloads/list Unpack it and install:
1
2
3
4
5
6
7
tar zxvf powerdns-webinterface-1.4.1.tar.gz
cd powerdns-webinterface
mysql -u pdns_admin -p powerdns < install.sql
mv web/* /var/www/html/
chmod 777 /var/www/html/tmp/templates_c
vim /var/www/html/configs/db.php (enter your db info)

Login and test it – user: admin pass: admin (change that password once you log in please!)
-----------

安装powerdns

PowerDNS简介
PowerDNS是高性能的域名服务器,除了支持普通的BIND配置文件,PowerDNS还可以从 MySQL,Oracle,PostgreSQL等的数据库读取数据。PowerDNS安装了Poweradmin,能实现Web管理DNS记录,非常的 方便。本文我们以MySQL为后端数据库和Poweradmin网页管理DNS,在CentOS-5安装PowerDNS。
安装MySQL
yum -y install mysql mysql-server
设置mysql开机自启并启动mysql
chkconfig –levels 235 mysqld on
/etc/init.d/mysqld start
修改mysql root密码:
mysqladmin -u root password yourrootsqlpassword
安装PowerDNS
yum -y install pdns pdns-backend-mysql
连接mysql:
mysql -u root -p
创建powerdns数据库:
CREATE DATABASE powerdns;
为PowerDNS创建powerdns数据库用户:
GRANT ALL ON powerdns.* TO ‘power_admin’@'localhost’ IDENTIFIED BY ‘power_admin_password’;
FLUSH PRIVILEGES;
请替换power_admin_password成自己的密码。
现在创建数据表:
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)
);
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(6) DEFAULT NULL,
content VARCHAR(255) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
primary key(id)
);
CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE TABLE supermasters (
ip VARCHAR(25) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) DEFAULT NULL
);
最后退出mysql shell:
quit;
现在配置PowerDNS以使用mysql后端:
vi /etc/pdns/pdns.conf
增加如下内容到pdns.conf
[...]
#################################
# launch Which backends to launch and order to query them in
#
# launch=
launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=power_admin
gmysql-password=power_admin_password
gmysql-dbname=powerdns
[...]
设置PowerDNS自启动并立即启动PowerDNS。
chkconfig –levels 235 pdns on
/etc/init.d/pdns start
现在PowerDNS已经正常运行,下面我们为PowerDNS安装Poweradmin实现Web管理。
安装Poweradmin
Poweradmin运行在PHP环境中,我们现在配置Web环境。
yum -y install httpd php php-devel php-gd php-imap php-ldap php-mysql php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-mhash gettext
设置apache自启动,并启动apache。
chkconfig –levels 235 httpd on
/etc/init.d/httpd start
Poweradmin还需要安装两个PEAR软件包。
yum install php-pear-DB php-pear-MDB2-Driver-mysql
现在Poweradmin所需的环境已经配置完成,我们将把Poweradmin安装在目录/var/www/html,这是apache默认的文档根目录。
到https://www.poweradmin.org/trac/wiki/GettingPoweradmin找到最新的版本下载:
cd /tmp
wget https://www.poweradmin.org/download/poweradmin-2.1.5.tgz
然后安装在/var/www/html/poweradmin目录。
tar xvfz poweradmin-2.1.5.tgz
mv poweradmin-2.1.5 /var/www/html/poweradmin
touch /var/www/html/poweradmin/inc/config.inc.php
chown -R apache:apache /var/www/html/poweradmin/
------------------

centos vps下,搭建自己的DNS服务器:PowerDNS

PowerDNS是高性能的域名服务器,除了支持普通的BIND配置文件,PowerDNS还可以从MySQL,Oracle,PostgreSQL等的数据库读取数据。PowerDNS安装了Poweradmin,能实现Web管理DNS记录,非常的方便。本文我们以MySQL为后端数据库和Poweradmin网页管理DNS,在CentOS-5安装PowerDNS 。


安装MySQL
yum -y install mysql mysql-server

设置mysql开机自启并启动mysql
chkconfig --levels 235 mysqld on
/etc/init.d/mysqld start

修改mysql root密码:
mysqladmin -u root password yourrootsqlpassword

安装PowerDNS
yum -y install pdns pdns-backend-mysql

连接mysql:
mysql -u root -p

创建powerdns数据库:
CREATE DATABASE powerdns;

为PowerDNS创建powerdns数据库用户:

GRANT ALL ON powerdns.* TO 'power_admin'@'localhost' IDENTIFIED BY 'power_admin_password';
FLUSH PRIVILEGES;

请替换power_admin_password成自己的密码。
现在创建数据表:

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

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(6) DEFAULT NULL,
content VARCHAR(255) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
primary key(id)
);

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

CREATE TABLE supermasters (
ip VARCHAR(25) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) DEFAULT NULL
);

最后退出mysql shell:
quit;

现在配置PowerDNS以使用mysql后端:
vi /etc/pdns/pdns.conf

增加如下内容到pdns.conf
[...]
#################################
# launch        Which backends to launch and order to query them in
#
# launch=
launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=power_admin
gmysql-password=power_admin_password
gmysql-dbname=powerdns
[...]

设置PowerDNS自启动并立即启动PowerDNS:
chkconfig --levels 235 pdns on
/etc/init.d/pdns start

现在PowerDNS已经正常运行,下面我们为PowerDNS安装Poweradmin实现Web管理。

安装Poweradmin
Poweradmin运行在PHP环境中,我们现在配置Web环境。
yum -y install httpd php php-devel php-gd php-imap php-ldap php-mysql php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-mhash gettext

设置apache自启动,并启动apache。
chkconfig --levels 235 httpd on
/etc/init.d/httpd start

Poweradmin还需要安装两个PEAR软件包。
yum install php-pear-DB php-pear-MDB2-Driver-mysql

现在Poweradmin所需的环境已经配置完成,我们将把Poweradmin安装在目录/var/www/html,这是apache默认的文档根目录。
到https://www.poweradmin.org/trac/wiki/GettingPoweradmin找到最新的版本下载:
cd /tmp
wget https://www.poweradmin.org/download/poweradmin-2.1.5.tgz

然后安装在/var/www/html/poweradmin目录。
tar xvfz poweradmin-2.1.5.tgz
mv poweradmin-2.1.5 /var/www/html/poweradmin
touch /var/www/html/poweradmin/inc/config.inc.php
chown -R apache:apache /var/www/html/poweradmin/

现在打开浏览器运行安装程序(如:http://www.urdomain.com/poweradmin/install或http://192.168.0.100/poweradmin/install)。
1、选择语言为英文,并点击Go to step 2

2、点击“Go to step 3”到安装的第三步,填入数据库详细信息。输入root用户和密码,和输入Poweradmin的admin用户的密码。

3、点击下一步,填入在安装powerdns那一步所创建的power_admin mysql用户的信息,并且填入域名服务器地址。

4、下一步是需要执行mysql语句,我们不需要执行了,因为前面我们已经执行过了,直接点击下一步即可。

5、继续点击下一步。

6、现在poweradmin安装完成。

7、为了安全,需要删除安装目录。
rm -fr /var/www/html/poweradmin/install/

现在你可以进入http://www.urdomain.com/poweradmin或者http://192.168.0.100/poweradmin页面,输入用户admin和执行安装程序时设置的密码进入管理界面。
 -------------------------------------------------------------------------------

POWERDNS WITH SQLITE

 

Generic SQLite backend (2 and 3)


Table A.5. Generic SQLite backend capabilities
Native Yes
Master Yes
Slave Yes
Superslave Yes
DNSSEC gsqlite3 only (set gsqlite3-dnssec)
Module name gsqlite and gsqlite3
Launch name gsqlite and gsqlite3

[Warning] Warning
When importing large amounts of data, be sure to run ‘analyze;’ afterwards as SQLite3 has a tendency to use sub-optimal indexes otherwise.
This backend retrieves all data from a SQLite database, which is an RDBMS that’s embedded into the application itself, so you won’t need to be running a separate server process. It also reduces overhead, and simplifies installation. At http://www.sqlite.org you can find more information about SQLite.
As this is a generic backend, built on top of the gSql framework, you can specify all queries as documented in Generic MySQL and PgSQL backends.
SQLite exists in two incompatible versions, numbered 2 and 3, and from 2.9.21 onwards, PowerDNS supports both. It is recommended to go with version 3 as it is newer, has better performance and is actively maintained. To use version 3, choose ‘launch=gsqlite3′.

5.1. Compiling the SQLite backend

Before you can begin compiling PowerDNS with the SQLite backend you need to have the SQLite utility and library installed on your system. You can download these from http://www.sqlite.org/download.html, or you can use packages (if your distribution provides those).
When you’ve installed the library you can use: ./configure –with-modules=”gsqlite” or ./configure –with-modules=”gsqlite3″ to configure PowerDNS to use the SQLite backend. Compilation can then proceed as usual.
SQLite is included in most PowerDNS binary releases.

5.2. Setting up the database

Before you can use this backend you first have to set it up and fill it with data. The default setup conforms to the following schema:
create table domains (
  id                INTEGER PRIMARY KEY,
  name              VARCHAR(255) NOT NULL COLLATE NOCASE,
  master            VARCHAR(128) DEFAULT NULL,
  last_check        INTEGER DEFAULT NULL,
  type              VARCHAR(6) NOT NULL,
  notified_serial   INTEGER DEFAULT NULL,
  account           VARCHAR(40) DEFAULT NULL
);

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
  id              INTEGER PRIMARY KEY,
  domain_id       INTEGER DEFAULT NULL,
  name            VARCHAR(255) DEFAULT NULL,
  type            VARCHAR(10) DEFAULT NULL,
  content         VARCHAR(65535) DEFAULT NULL,
  ttl             INTEGER DEFAULT NULL,
  prio            INTEGER DEFAULT NULL,
  change_date     INTEGER DEFAULT NULL
);

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

create table supermasters (
  ip          VARCHAR(25) NOT NULL,
  nameserver  VARCHAR(255) NOT NULL COLLATE NOCASE,
  account     VARCHAR(40) DEFAULT NULL
);

This schema contains all elements needed for master, slave and superslave operation.
To support DNSSEC, or to migrate to DNSSEC, the following statements must be issued:

alter table records add ordername      VARCHAR(255);
alter table records add auth bool;
create index orderindex on records(ordername);

create table domainmetadata (
 id   INTEGER PRIMARY KEY,
 domain_id       INT NOT NULL,
 kind   VARCHAR(16) COLLATE NOCASE,
 content TEXT
);

create index domainmetaidindex on domainmetadata(domain_id);

create table cryptokeys (
 id  INTEGER PRIMARY KEY,
 domain_id      INT NOT NULL,
 flags  INT NOT NULL,
 active  BOOL,
 content TEXT
);   

create index domainidindex on cryptokeys(domain_id);           

create table tsigkeys (
 id  INTEGER PRIMARY KEY,
 name  VARCHAR(255) COLLATE NOCASE,
 algorithm VARCHAR(50) COLLATE NOCASE,
 secret  VARCHAR(255)
);

create unique index namealgoindex on tsigkeys(name, algorithm);

For full migration notes, please see Section 3, “Migration”.
After you have created the database you probably want to fill it with data. If you have a BIND zone file it’s as easy as: zone2sql –zone=myzonefile –gmysql | sqlite powerdns.sqlite, but you can also use AXFR (or insert data manually).
To communicate with a SQLite database, use either the ‘sqlite’ or ‘sqlite3′ program, and feed it SQL.

5.3. Using the SQLite backend

The last thing you need to do is telling PowerDNS to use the SQLite backend.

            # in pdns.conf
            launch=gsqlite # or gsqlite3
            gsqlite-database=<path to your SQLite database>   # or gsqlite3-database

Then you can start PowerDNS and it should notify you that a connection to the database was made.
------------
https://github.com/ngoduykhanh/PowerDNS-Admin
https://github.com/fwenzel/powerdns-dyndns
-------------

编译powerdns
(文档:https://doc.powerdns.com/md/appendix/compiling-powerdns/#compiling-powerdns

首先要编译boost:(参见http://www.briten.info/2016/08/boostsockssocksserver.html
wget http://downloads.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.bz2
tar jxvf boost_1_61_0.tar.bz2
cd boost_1_61_0

root@AR:~/boost_1_61_0# ls
b2 boost-build.jam  bootstrap.bat index.htm   libs rst.css
bin.v2 boostcpp.jam  bootstrap.log index.html  LICENSE_1_0.txt stage
bjam boost.css  bootstrap.sh INSTALL     more status
boost boost.png  doc Jamroot     project-config.jam tools
root@AR:~/boost_1_61_0# ./bootstrap.sh
root@AR:~/boost_1_61_0# ./b2 (此步骤耗时1 hour to 2 hours and 34 minutes)或者./bjam
root@AR:~/boost_1_61_0# ./b2 install或者./bjam install
这样,boost就编译好了。
(装好后,默认的头文件在/usr/local/include/boost目录下。库文件在/usr/local/lib/目录下。默认不用修改。如果编译好程序后,在运行时提示无法加载某个库文件,则把/usr/local/lib下的所有boost的库文件mv到/usr/lib目录下就可以了。)


wget https://downloads.powerdns.com/releases/pdns-4.2.0-rc2.tar.bz2
tar jxvf pdns-4.2.0-rc2.tar.bz2
cd  pdns-4.2.0-rc2
./configure --disable-lua-records
make && make install

但是运行 which pdns ,没有显示pdns在哪里。
----------------------------------------------------------


自建 PowerDNS 智能解析服务器


本文的自建 DNS 是指的是权威 DNS,即给自己的域名配置的 DNS,而非在客户端配置的缓存 DNS。

    优缺点

    首先,我先说用自建 DNS 服务器的致命坏处
    1. 如果那天自己的服务器挂了,整个域名相关服务都会挂,即使你邮件收信服务器是用的是第三方的,你也不能收信了
    2. 基本上必须是开放端口,并有固定 IP(而且最好还需要至少两个 IP) 的 VPS(当然也可以是两个主机,只需要保证配置文件完全相同即可),对于服务提供商要求高
    3. 个人一般关于 DNS 运维经验不足,容易导致配置错误
    4. 第三方 DNS 提供商基本都有 DDOS 防御,而你的服务器可不一定有,攻击者可以直接通过 L7 DNS Flood 攻击掉你的服务器,然后又回到第一个问题上了
    使用自建 DNS 服务器优点:
    1. 可 DIY 程度极大,各种 DNS 方面功能几乎都能配置,但却又都十分复杂
    2. 可以建在已有的服务器上,不用额外花钱
    最终我还是选择了使用 PowerDNS 软件(这其实也是很多提供 DNS 服务的服务商所使用的),我安装它的最近才出的 4.0 版本,这个版本支持的一些特性:
    • 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 等,还有不常用的没有列出来,见所有支持的记录。说实话有一些冷门的记录很多解析商都不支持,但我又需要用,比如 LOC、SSHFP 和 TLSA。不知道这一堆记录是干什么的?请见维基百科

    简述安装过程

    详情安装方法见官方文档,需要先安装 pdns-server ,然后再安装 pdns-backend-$backend 。Backend 是你可以自己选的,常用的有 BIND 和 Generic MySQL ,需要 GEODNS 可以用 GEOIP ,所有列表见此。如果想做网页版控制后台,使用 MySQL 的可能比较方便。如果只是通过文件形式控制,那么 BIND 和 GEOIP 都可以。
    我使用 GEOIP 版本的,GEOIP 版本可拓展性强,使用 YAML 文件,更灵活、优雅,本文就讲讲 GEOIP 版本:
    在 Ubuntu 上安装(系统软件源里就有):
    $ sudo apt install pdns-server
    $ sudo apt install pdns-backend-geoip
    
    然后修改配置文件:
    $ rm /etc/powerdns/pdns.d/* # 删除 Example
    

    安装更新版本的 PowerDNS

    很多特性,如 CAA 记录等,需要新版 PowerDNS。请前往官网配置软件源

    安装地理位置数据库

    注意,你应该已经有 MaxMind GeoIP Lite 数据库,如果没有,通过如下方式安装:
    重要更新:2018 年 4 月 1 日起已经无法通过软件自动下载到 DAT 格式的 GeoIP 数据库,请前往官网手动下载对应数据库。需要的是 Binary 格式的。
    创建文件 /etc/GeoIP.conf 内容是:
    # The following UserId and LicenseKey are required placeholders:
    UserId 999999
    LicenseKey 000000000000
    
    # Include one or more of the following ProductIds:
    # * GeoLite2-City - GeoLite 2 City
    # * GeoLite2-Country - GeoLite2 Country
    # * GeoLite-Legacy-IPv6-City - GeoLite Legacy IPv6 City
    # * GeoLite-Legacy-IPv6-Country - GeoLite Legacy IPv6 Country
    # * 506 - GeoLite Legacy Country
    # * 517 - GeoLite Legacy ASN
    # * 533 - GeoLite Legacy City
    ProductIds 506 GeoLite-Legacy-IPv6-Country
    
    DatabaseDirectory /usr/share/GeoIP
    
    然后安装 geoipupdate,执行 sudo apt install geoipupdate && mkdir -p /usr/share/GeoIP && geoipupdate -v ,你的数据库就已经下载完毕了。

    配置 PowerDNS

    创建文件 /etc/powerdns/pdns.d/geoip.conf 内容是:
    launch=geoip
    geoip-database-files=/usr/share/GeoIP/GeoLiteCountry.dat /usr/share/GeoIP/GeoIPv6.dat # 选择 IPv4 和 IPv6 国家模块
    geoip-database-cache=memory
    geoip-zones-file=/share/zone.yaml # 你的 YAML 配置文件的位置,随便哪个地方都行
    geoip-dnssec-keydir=/etc/powerdns/key
    
    创建那个 YAML 文件,然后开始写 Zone,这是一个例子(IPv6 不是必须的,所有 IP 应该都填写外部 IP,本文以精确到国家举例,并列内容的顺序无所谓):
    # @see: https://doc.powerdns.com/md/authoritative/backend-geoip/
    domains:
    - domain: example.com
      ttl: 300 # 默认 TTL 时长
      records:
    
    
    ##### Default NS
        ns1.example.com:
          - a: # 你的服务器的第一个 IPv4 地址
              content: 10.0.0.1
              ttl: 86400
          - aaaa: # 你的服务器的第一个 IPv6 地址
              content: ::1
              ttl: 86400
        ns2.example.com: # 你的服务器的第二个 IPv4 地址(如果没有就和上面一样)
          - a:
              content: 10.0.0.2
              ttl: 86400
          - aaaa: # 你的服务器的第二个 IPv6 地址(如果没有就和上面一样)
              content: ::2
              ttl: 86400
    
    
    ##### Root domain
        example.com: # 根域名下的记录
          - soa:
              content: ns1.example.com. admin.example.com. 1 86400 3600 604800 10800
              ttl: 7200
          - ns:
              content: ns1.example.com.
              ttl: 86400
          - ns:
              content: ns2.example.com.
              ttl: 86400
          - mx:
              content: 100 mx1.example.com. # 权重 [空格] 主机名
              ttl: 7200
          - mx:
              content: 100 mx2.example.com.
              ttl: 7200
          - mx:
              content: 100 mx3.example.com.
              ttl: 7200
          - a: 103.41.133.70 # 如果想使用默认 TTL,那就不用区分 content 和 ttl 字段
          - aaaa: 2001:470:fa6b::1
    
    ##### Servers list 你的服务器列表
        beijing-server.example.com: &beijing
          - a: 10.0.1.1
          - aaaa: ::1:1
        newyork-server.example.com: &newyork
          - a: 10.0.2.1
          - aaaa: ::2:1
        japan-server.example.com: &japan
          - a: 10.0.3.1
          - aaaa: ::3:1
        london-server.example.com: &uk
          - a: 10.0.4.1
          - aaaa: ::4:1
        france-server.example.com: &france
          - a: 10.0.5.1
          - aaaa: ::5:1
    
    
    ##### GEODNS 分区解析
        # @see: https://php.net/manual/en/function.geoip-continent-code-by-name.php
        # @see: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
        # unknown also is default
        # %co.%cn.geo.example.com
        # 默认
        unknown.unknown.geo.example.com: *newyork # 默认解析到美国
        # 洲
        unknown.as.geo.example.com: *japan # 亚洲解析到日本
        unknown.oc.geo.example.com: *japan # 大洋洲解析到日本
        unknown.eu.geo.example.com: *france # 欧洲解析到法国
        unknown.af.geo.example.com: *france # 非洲解析到法国
        # 国家
        chn.as.geo.example.com: *beijing # 中国解析北京
        gbr.eu.geo.example.com: *uk # 英国解析到英国
    
    
      services:
        # GEODNS
        www.example.com: [ '%co.%cn.geo.example.com', 'unknown.%cn.geo.example.com', 'unknown.unknown.geo.example.com']
    
    
    这个配置,就相当于把 www.example.com 给分区解析,由于目前这个解析存在一些问题,导致不能同时在根域名和子域名下设置 GEODNS,这个 Bug 我已经提交反馈了。
    如果你想只把解析精度设在洲级别,那么就直接 %cn.geo.example.com 这样少写一级就行了。如果你需要精确到城市,那么多写一级就行,但是需要在配置文件中添加 GeoIP 城市的数据库。然而免费的城市数据库的城市版本并不精准,你还需要去购买商业数据库,这又是一个额外开销。

    配置域名

    前往你的域名注册商,进入后台修改设置,添加子域名(ns1.mydomain.com和ns2.mydomain.com)的a记录,均指向你的服务器的ip.
    由于要设置的 NS 是在自己服务器下的,所以务必要在域名注册商上向上级域名(如 .com)注册你的 NS 服务器 IP 地址,这样上级域名就能解析道 NS 的 IP,自建 DNS 才能使用,比如 icann.org 下就有一个属于自己的 NS:
    $ dig icann.org ns +short
    a.iana-servers.net.
    b.iana-servers.net.
    c.iana-servers.net.
    ns.icann.org.
    
    然后再看它的上级域名 org:
    $ dig org ns +short
    a2.org.afilias-nst.info.
    b0.org.afilias-nst.org.
    d0.org.afilias-nst.org.
    c0.org.afilias-nst.info.
    a0.org.afilias-nst.info.
    b2.org.afilias-nst.org.
    
    随便找一个服务器,查询权威记录(我就不用 +short 了):
    $ dig @a0.org.afilias-nst.info icann.org ns
    
    ;; QUESTION SECTION:
    ;icann.org.   IN NS
    
    ;; AUTHORITY SECTION:
    icann.org.  86400 IN NS c.iana-servers.net.
    icann.org.  86400 IN NS a.iana-servers.net.
    icann.org.  86400 IN NS ns.icann.org.
    icann.org.  86400 IN NS b.iana-servers.net.
    
    ;; ADDITIONAL SECTION:
    ns.icann.org.  86400 IN A 199.4.138.53
    ns.icann.org.  86400 IN AAAA 2001:500:89::53
    
    可以看到,在这个 org 的 NS 服务器就已经把 ns.icann.org. 的记录返回来了,这也就是你需要在域名注册商填写 IP 地址的原因。然而你最好在你域名下的 DNS 服务器上也返回相同的 NS 和相同的 IP。
    最后,不要忘了域添加名的 NS 记录:
    ns1.mydomain.com和ns2.mydomain.com

    YAML 的一些高级写法

    我刚才的 YAML 中其实就已经用到了 YAML 的高级写法,就是 &variable 设置变量,*variable 使用变量,这很像 CloudXNS 下的 LINK 记录,比如在 CloudXNS 下你可以这么写:
    www.example.com    600   IN    A       10.0.0.1
    www.example.com    600   IN    A       10.0.0.2
    www.example.com    600   IN    AAAA    ::1
    www.example.com    600   IN    AAAA    ::2
    sub.example.com    600   IN    LINK    www.example.com
    
    然后在你的 YAML 记录里就可以这么写:
    www.example.com: &www
      - a: 10.0.0.1
      - a: 10.0.0.2
      - aaaa: ::1
      - aaaa: ::2
    sub.example.com: *www
    
    这就是 YAML 的一种高级写法,不需要其他额外支持。

    添加 DNSSEC 支持

    详情可以参考文档,运行以下指令:
    $ mkdir /etc/powerdns/key
    $ pdnsutil secure-zone example.com
    $ pdnsutil show-zone example.com
    
    最后一个指令所返回的结果就是你需要在域名注册商设置的记录,不推荐都设置,只设置 ECDSAP256SHA256 – SHA256 digest 就行了。
    最后在线检查设置即可 测试地址1 测试地址2,可能有几天缓存时间。

    其他一些有趣的东西

    你可以在 YAML 里写上这个,为了方便你调试:
    "*.ip.example.com":
      - txt:
          content: "IP%af: %ip, Continent: %cn, Country: %co, ASn: %as, Region: %re, Organisation: %na, City: %ci"
          ttl: 0
    
    这些变量都能作为你 GEODNS 的标准,也可以检查你的 GEOIP 数据库情况。
    然后,正确检查的姿势:
    $ random=`head -200 /dev/urandom | md5` ; dig ${random}.ip.example txt +short
    "IPv4: 42.83.200.23, Continent: as, Country: chn, ASn: unknown, Region: unknown, Organisation: unknown, City: unknown"
    IP 地址就是 DNS 缓存服务器地址(如果你开启了 EDNS Client Subnet,且缓存服务器支持,那么就是自己的 IP,但是如果使用 8.8.8.8,那么会看到自己的 IP 最后一位是 0),如果你在本地指定了从你自己的服务器查,那就直接返回你自己的 IP 地址。由于我只安装了国家数据库,所以除了洲和国家之外其余都是 Unknown。

    进阶使用

    建立分布式 DNS

    一般情况下,是一个 Master 和一个  Slave 的 DNS 解析服务器,但是这样的话对 DNSSEC 可能有问题,于是我就建立了两个 Master 服务器,自动同步记录,并设置了相同的 DNSSEC Private Key,好像并没有什么错误发生(毕竟包括 SOA 在内的所有记录也都是完全一样的),我的服务器目前的配置
    $ dig @a.gtld-servers.net mydmain.com
    ;; QUESTION SECTION:
    ;mydmain.com.   IN A
    
    ;; AUTHORITY SECTION:
    mydmain.com.  172800 IN NS a.geo.ns.tloxygen.net.
    mydmain.com.  172800 IN NS c.geo.ns.tloxygen.net.
    
    ;; ADDITIONAL SECTION:
    a.geo.ns.tloxygen.net. 172800 IN A 198.251.90.65
    a.geo.ns.tloxygen.net. 172800 IN AAAA 2605:6400:10:6a9::2
    c.geo.ns.tloxygen.net. 172800 IN A 104.196.241.116
    c.geo.ns.tloxygen.net. 172800 IN AAAA 2605:6400:20:b5e::2
    
    其中是两个 IPv4 两个 IPv6,其中 a.geo.ns.tloxygen.net. 是使用了 Anycast 技术的 IP 地址,其背后由三台服务器提供。c.geo.ns.tloxygen.net. 属于另一家服务商的主机,这样一个挂了之后还有备份,更加稳定。

    Anycast or Unicast?

    像我这种分布式的 DNS,其实是 Unicast 和 Anycast 的组合,这样存在的一个问题就是在一个地方连接其中一个会比较快,但是另一个会比较慢。只有在用支持异步查询,或者是带 GeoIP 的 DNS 缓存服务器,才有可能连接到最快的 DNS 权威服务器,其他情况下则是随机连接,而且如果一个服务器挂掉了,那么服务器对应的 IP 就废了。
    Anycast 是一个 IP 对应多个主机,然而我却没有条件用,这个对于个人来说也许成本会比较高,要么你自己有 AS 号然后让主机商给你接入,要么你的主机商提供跨区域的 Load Balancing IP。我的 VPS 在两个不同的主机商,也没有 AS,就不能用 Anycast 了。我觉得 DNS 服务如果可能还是要用 Anycast,因为 DNS 服务器对应的 IP 不能 GEODNS(因为这是根域名给你解析的),使用 Anycast 后就基本能保障最快的连接速率,并且一个服务器挂了 IP 还能用。此外,DNS 必须要同时转发 TCP 和 UDP 的 53 端口。

    宕机自动切换

    如何实现宕机自动切换?实现这个的流程是:
    监控服务发现宕机 -> 向服务器发送已经宕机的请求 -> 服务器对宕机处理,解析到备用 IP/暂停解析
    监控服务发现服务正常 -> 向服务器发送服务正常的请求 -> 服务器对服务正常处理,恢复解析
    可以建立两个 YAML file,一个是默认使用,一个是服务器宕机时使用的,当监控服务发现服务器宕机后,重新加载另一个 YAML file,然后这就是宕机模式了。
    ------------


    自建 PowerDNS 进阶:分区解析,dnsdist,Lua 记录


    本文将讲一下使用 PowerDNS 的 GeoIP Backend 建立自己的 DNS 权威服务器(服务于自己的域名,这不是公共 DNS 缓存服务器)。
    通过使用 PowerDNS,你可以在自己的服务器上搭建支持分区解析(精细到国家、城市、ASN、自定义 IP 段)、EDNS-Client-Subnet、DNSSEC、IPv6 的 DNS 服务器。
    本文面向域名所有者和站长,讲述的是权威 DNS 服务器而非 DNS 缓存服务器.
    本文主要更新以下内容:
    1. 本文适用于最新的 PowerDNS 4.2.0
    2. 使用 MaxMind GeoIP 2 mmdb 格式的数据库
    3. 讲述如何为根域名设置分区解析
    4. 使用 dnsdist 以实现 IP 访问速率的限制,防御 DOS 攻击。

    安装 PowerDNS Authoritative Server 和 dnsdist

    考虑到操作系统软件源默认版本不一,建议前往 PowerDNS repositories 重新为 PowerDNS Authoritative Server 配置软件源(请添加 4.2 或以上版本)。同样你也可以配置 dnsdist 的软件源(请添加 1.2 或以上版本)。
    添加软件源后,更新软件列表并安装 pdns-server 和 pdns-backend-geoip 即可。在 Debian/Ubuntu 下:
    sudo apt-get install pdns-server pdns-backend-geoip
    需要注意的是,在 Ubuntu 18.04 LTS 后可能默认包含了 systemd-resolved 服务,这个服务占用了 loopback 地址的的 53 端口,这与 PowerDNS 所需要使用的端口(0.0.0.0:53)冲突。你可以:1. 禁用这个服务,2. 修改 PowerDNS 的 local-address 和 local-ipv6 配置仅监听外网 IP 地址,3. 修改 local-port 为非 53 端口,并使用 dnsdist 进行转发(详见后文)。
    如果你想要配置用户侧 IP 访问速率,请安装 dnsdist:
    sudo apt-get install dnsdist

    禁用 systemd-resolved

    如果你选择禁用 systemd-resolved,可以执行以下代码:
    sudo systemctl disable systemd-resolved.service
    sudo systemctl stop systemd-resolved

    安装 geoipupdate 并下载 GeoIP2

    为了实现分区解析,我们需要 GeoIP 数据库。最新版的 PowerDNS GeoIP Backend(4.2.0)已经支持了 GeoIP2 的 mmdb 格式,同时也支持 dat 格式。而老板的只支持 dat 格式的数据库。由于 MaxMind 已经停止维护免费的 dat 格式数据库,因此强烈建议使用 4.2 版本及以上的 PowerDNS 并换用 mmdb 格式的 IP 数据库
    首先建立配置文件,创建 /etc/GeoIP.conf 为如下内容(包含了 IPv4 和 IPv6 的国家、城市、ASN 数据):
    ProductIds GeoLite2-Country GeoLite2-City GeoLite2-ASN
    DatabaseDirectory /usr/share/GeoIP
    建议安装 geoipupdate,在 Ubuntu 下可以这样安装:
    sudo add-apt-repository ppa:maxmind/ppa
    sudo apt update
    sudo apt install geoipupdate
    然后下载/更新 GeoIP2:
    sudo geoipupdate -v
    All done!
    同时建议配置 Crontab 定期执行上面指令更新数据库文件(并重载 PowerDNS 服务),以更新 GeoIP 数据库。

    配置 PowerDNS

    PowerDNS(下简称 pdns)的配置文件位于 /etc/powerdns,首先删除 PowerDNS 原本的 demo 配置,然后建立文件夹以存储 DNSSEC 的密钥文件:
    sudo rm /etc/powerdns/pdns.d/*
    sudo mkdir /etc/powerdns/keys
    然后创建文件,创建 /etc/powerdns/pdns.d/geoip.conf 为如下内容:
    launch=geoip
    geoip-database-files=/usr/share/GeoIP/GeoLite2-Country.mmdb /usr/share/GeoIP/GeoLite2-City.mmdb /usr/share/GeoIP/GeoLite2-ASN.mmdb
    geoip-zones-file=/etc/powerdns/zones.yaml
    geoip-dnssec-keydir=/etc/powerdns/key
    在 geoip-database 选项中,你可以按照需要设置自己所需要的一个或多个 GeoIP 数据库。

    配置 DNS 记录

    你可以建立文件 /etc/powerdns/zones.yaml 以配置 DNS 记录。具体格式参见 Zonefile format
    需要注意的是,若使用 mmdb,则 %re 是 ISO3166 的两位区域缩写。若使用 dat,则是 GeoIP 的区域代码
    由于 PowerDNS GeoIP Backend 仅支持按域名配置分区解析,而不支持按记录配置按记录配置分区解析,所以若要配置根域名分区解析,可以参考如下配置(YAML 格式,下同):
    domains:
    - domain: example.com
      ttl: 300
      records:
        unknown.cn.example.com:
          - soa: &soa ns1.example.com hostmaster.example.com 2014090125 7200 3600 1209600 3600
          - ns: &ns1
               content: ns1.example.com
               ttl: 600
          - ns: &ns2 ns2.example.com
          - mx: &mx 10 mx.example.com
          - a: 10.1.1.1
        bj.cn.example.com:
          - soa: *soa
          - ns: *ns1
          - ns: *ns2
          - mx: *mx
          - a: 10.1.2.1
        unknown.unknown.example.com:
          - soa: *soa
          - ns: *ns1
          - ns: *ns2
          - mx: *mx
          - a: 10.1.3.1
        ns1.example.com:
          - a: 10.0.1.1
          - aaaa: ::1
        ns2.example.com:
          - a: 10.0.2.1
      services:
        example.com: [ '%ci.%cc.service.geo.example.com', 'unknown.%cc.service.geo.example.com', 'unknown.unknown.service.geo.example.com']
    可以看到,为了配置跟域名分区域解析,我们需要为每个区域配置所有类型的记录。而根域名通常有很多记录类型,所以配置起来相对繁琐。上述 YAML 写法使用了变量,这样可以减少配置重复的记录。(&variable 设置变量,*variable 使用变量)

    调试

    你可以通过配置如下记录进行调试:
    debug.tlo.xyz:
      - a: "%ip4"
      - aaaa: "%ip6"
      - txt: "co: %co; cc: %cc; cn: %cn; af: %af; re: %re; na: %na; as: %as; ci: %ci; ip: %ip"
    在客户端通过类似下方的指令进行测试(替换 10.11.12.13 为服务所监听的 IP 地址),有如下结果:
    $ dig @10.11.12.13 debug.example.com 
    
    debug.example.com.        3600    IN  TXT "co: us; cc: us; cn: na; af: v4; re: ca; na: quadranet enterprises llc; as: 8100; ci: los angeles; ip: 10.11.12.13"
    debug.example.com.        3600    IN  A   10.11.12.13
    这样你就可以看到每一个变量的具体值了。

    Lua 记录

    在 PowerDNS 4.2 中,新增了 Lua 记录功能。其 Lua 记录的最主要的功能是可以配置宕机自动切换记录。
    由于 Lua 记录可以使用 Lua 编程语言执行任意代码,相对危险,所以 PowerDNS 默认关闭了这个功能,需要在配置文件中开启:
    enable-lua-records=yes
    配置如下记录,将返回动态的可用 A 记录。如果两个 IP 的端口都可用(这里是 443 端口),则随机返回一个 IP 地址,若有一个不可用,则只返回可用 IP 的地址,否则同时返回两个 IP:
    sub.example.com:
      - lua: A "ifportup(443, {'192.0.2.1', '192.0.2.2'})"
    配置如下记录,就可以自动对指定 URL 进行状态检查,默认返回第一组 IP 地址,若第一组 IP 地址不可用,则返回第二组:
    sub.example.com:
      - lua: A "ifurlup('https://sub.example.com/', {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}})"
    Lua 记录可以与 GeoIP 功能共同使用,且可以与其他类型的记录共存。另外,状态检查并非与请求同步,而是在后台周期性的检查是否可用,所以使用状态检查不会增加 DNS 请求的延迟。

    配置 dnsdist

    截止到现在,你的 DNS 服务器应该已经可以工作了。下面将介绍配置 dnsdist。
    dnsdist 相当于在 pdns 之上加了一层代理,可以为其配置访问速率的限制,起到抗 DOS 的作用。正常情况下,安装完成 dnsdist 后,其服务就自动启动了。
    在这个样例中,将 pdns 的主程序监听改为 127.0.0.1:8053。创建或修改文件 /etc/dnsdist/dnsdist.conf 为以下内容:
    newServer{address="127.0.0.1:8053",useClientSubnet=true}
    setLocal("10.0.1.1")
    setACL({'0.0.0.0/0', '::/0'})
    setECSSourcePrefixV4(32)
    setECSSourcePrefixV6(128)
    addAction(MaxQPSIPRule(10, 32, 56), TCAction())
    addAction(MaxQPSIPRule(20, 32, 56), DropAction())
    addAction(MaxQPSIPRule(40, 24, 48), TCAction())
    addAction(MaxQPSIPRule(80, 24, 48), DropAction())
    addAction(MaxQPSIPRule(160, 16, 40), TCAction())
    addAction(MaxQPSIPRule(320, 16, 40), DropAction())
    newServer 语句设置了 dnsdist 所代理的服务器,也就是 pdns 所监听的 IP 地址和端口号。setLocal 设置了 dnsdist 的监听 ip 地址。setACL 设置了允许的 IP 地址,这里允许了所有的 IPv6 和 IPv4 访问。setECSSourcePrefixV4 和 setECSSourcePrefixV6 设置了 EDNS Client Subnet Client 功能传输 IP 地址的比特数,这里为 IPv4 设置了 32 位,IPv6 设置了 128 位,也就是保留了 IP 地址的完整长度。实际生产中也可以设置比这个更小的值。
    后几行 addAction 和 MaxQPSIPRule 定义了访问速率限制。其中 MaxQPSIPRule 拥有三个参数。第一个参数是 qps,即 queries per second,每秒钟请求数。第二个参数是 IPv4 的 CIDR 值,默认为 32,第三个参数是 IPv6 的 CIDR 值,默认为 64。TCAction 代表要求客户端使用 TCP 请求,DropAction 代表拒绝请求。普通的客户端在收到 DNS 服务器要求使用 TCP 时,会使用 TCP 进行 DNS 请求,这样不影响普通用户的使用。而 DOS 一般不会对 TCP DNS 服务进行攻击。
    举例,下面语句的意思是:
    addAction(MaxQPSIPRule(40, 24, 48), TCAction())
    限制 /24 的 IPv4 地址(256 个)和 /48 的 IPv6 地址(2^80 个)的 qps 为 40,若超出则要求客户端使用 TCP 请求。
    除了 TCAction 和 DropAction,还可以使用 DelayAction(一个整数参数,代表为延迟的毫秒数)和 NoRecurseAction(专门用于限制标记了递归((RD))的请求)。
    因此,将 dnsdist 与 pdns 配合使用,就可以使 DNS 服务有一定的抗 ddos 能力.
    -----------------------------------

    Self-built PowerDNS GeoDNS Server

    Today, I changed the DNS server to a self-built one, and shared my experience (PS: Now in order to realize the root domain CDN, I used Route 53 instead):

    The self-built DNS in this article refers to the authoritative DNS, that is, the DNS configured for your own domain name, not the cache DNS configured on the client.

    Advantages and Disadvantages

    First of all, let me talk about the fatal disadvantages of using a self-built DNS server:

    1. If your server is down that day, the entire domain name related services will be down. Even if your mail receiving server is a third-party, you will not be able to receive mail.
    2. Basically, it must be a VPS with an open port and a fixed IP (and preferably at least two IPs) (of course it can be two hosts, just make sure that the configuration files are exactly the same), High requirements for service providers
    3. Individuals generally have insufficient experience in DNS operation and maintenance, which can easily lead to configuration errors
    4. Third-party DNS providers basically have DDOS defense, but your server may not have it. An attacker can directly attack your server through L7 DNS Flood, and then go back to the first problem.

    Advantages of using a self-built DNS server:

    1. The degree of DIY is extremely high, almost all DNS functions can be configured, but they are all very complicated
    2. Can be built on an existing server without extra cost

    In the end, I chose to use PowerDNS software (which is actually used by many service providers that provide DNS services). I installed its recently released version 4.0. Some features supported by this version:

    • EDNS Client Subnet
    • DNSSEC
      *GEODNS
    • IPv6

    Wait, that’s just what came to my mind. At the same time, PowerDNS supports many types of resolution records (at least the most I have seen so far): A, AAAA, AFSDB, ALIAS (also 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, etc., and there are no columns that are not commonly used out, see all supported records. To be honest, there are some unpopular records that many resolvers do not support, but I need to use them, such as LOC, SSHFP and TLSA. Don’t know what this pile of records is for? See Wikipedia.

    Briefly Describe the Installation Process

    For detailed installation method see official documentation, you need to install pdns-server first, and then install pdns-backend-$backend . Backend is something you can choose by yourself. Commonly used ones are BIND and Generic MySQL. If you need GEODNS, you can use GEOIP. All lists see here . If you want to control the background of the web version, it may be more convenient to use MySQL. Both BIND and GEOIP are fine if it is only controlled by file. I use the GEOIP version. The GEOIP version is highly scalable and uses YAML files, which is more flexible and elegant. This article will talk about the GEOIP version: Install on Ubuntu (available in the system software source):

    $ sudo apt install pdns-server
    $ sudo apt install pdns-backend-geoip

    Then modify the configuration file:

    $ rm /etc/powerdns/pdns.d/* # delete Example
    

    Install a Newer Version of PowerDNS

    Many features, such as CAA records, require the new version of PowerDNS. Please go to the official website to configure the software source.

    Install Geolocation Database

    Note that you should already have the MaxMind GeoIP Lite database, if not, install it as follows:

    Important update⚠️: Since April 1, 2018, the GeoIP database in DAT format cannot be automatically downloaded by the software. Please [go to the official website to manually download the corresponding database](https://dev.maxmind.com/geoip/legacy/geolite /). It needs to be in Binary format.

    Create a file /etc/GeoIP.conf with:

    # The following UserId and LicenseKey are required placeholders:
    UserId 999999
    LicenseKey 000000000000
    # Include one or more of the following ProductIds:
    # * GeoLite2-City - GeoLite 2 City
    # * GeoLite2-Country - GeoLite2 Country
    # * GeoLite-Legacy-IPv6-City - GeoLite Legacy IPv6 City
    # * GeoLite-Legacy-IPv6-Country - GeoLite Legacy IPv6 Country
    # * 506 - GeoLite Legacy Country
    # * 517 - GeoLite Legacy ASN
    # * 533 - GeoLite Legacy City
    ProductIds 506 GeoLite-Legacy-IPv6-Country
    DatabaseDirectory /usr/share/GeoIP
    

    Then install geoipupdate, execute sudo apt install geoipupdate && mkdir -p /usr/share/GeoIP && geoipupdate -v , your database has been downloaded.

    Configure PowerDNS

    Create a file /etc/powerdns/pdns.d/geoip.conf with:

    launch=geoip
    geoip-database-files=/usr/share/GeoIP/GeoLiteCountry.dat /usr/share/GeoIP/GeoIPv6.dat # Select IPv4 and IPv6 country modules
    geoip-database-cache=memory
    geoip-zones-file=/share/zone.yaml # The location of your YAML configuration file, anywhere
    geoip-dnssec-keydir=/etc/powerdns/key
    

    Create that YAML file, and then start writing Zone, here is an example (IPv6 is not required, all IPs should be filled in with external IPs, this article takes the country as an example, the order of the juxtaposed content does not matter):

    # @see: https://doc.powerdns.com/md/authoritative/backend-geoip/
    domains:
    - domain: example.com
      ttl: 300 # Default TTL duration
      records:
    ##### Default NS
        ns1.example.com:
          - a: # Your server's first IPv4 address
              content: 10.0.0.1
              ttl: 86400
          - aaaa: # Your server's first IPv6 address
              content: ::1
              ttl: 86400
        ns2.example.com: # Second IPv4 address of your server (if not, same as above)
          - a:
              content: 10.0.0.2
              ttl: 86400
          - aaaa: # Second IPv6 address of your server (if not, same as above)
              content: ::2
              ttl: 86400
    ##### Root domain
        example.com: # records under the root domain name
          - soa:
              content: ns1.example.com.admin.example.com.1 86400 3600 604800 10800
              ttl: 7200
          - ns:
              content: ns1.example.com.
              ttl: 86400
          - ns:
              content: ns2.example.com.
              ttl: 86400
          - mx:
              content: 100 mx1.example.com. # weight [space] hostname
              ttl: 7200
          - mx:
              content: 100 mx2.example.com.
              ttl: 7200
          - mx:
              content: 100 mx3.example.com.
              ttl: 7200
          - a: 103.41.133.70 # If you want to use the default TTL, you don't need to distinguish between the content and ttl fields
          - aaaa: 2001:470:fa6b::1
    ##### Servers list Your server list
        beijing-server.example.com: &beijing
          - a: 10.0.1.1
          - aaaa: ::1:1
        newyork-server.example.com: &newyork
          - a: 10.0.2.1
          - aaaa: ::2:1
        japan-server.example.com: &japan
          - a: 10.0.3.1
          - aaaa: ::3:1
        london-server.example.com: &uk
          - a: 10.0.4.1
          - aaaa: ::4:1
        france-server.example.com: &france
          - a: 10.0.5.1
          - aaaa: ::5:1
    ##### GEODNS partition resolution
        # @see: https://php.net/manual/en/function.geoip-continent-code-by-name.php
        # @see: https://en.wikipedia.org/wiki/ISO\_3166-1\_alpha-3
        # unknown also is default
        # %co.%cn.geo.example.com
        # default
        unknown.unknown.geo.example.com: *newyork # resolves to US by default
        # continent
        unknown.as.geo.example.com: *japan # Asia to Japan
        unknown.oc.geo.example.com: *japan # Oceania resolves to Japan
        unknown.eu.geo.example.com: *france # Europe resolves to France
        unknown.af.geo.example.com: *france # Africa to France
        # nation
        chn.as.geo.example.com: *beijing # China parsing Beijing
        gbr.eu.geo.example.com: *uk # UK resolves to UK
      services:
        #GEODNS
        www.example.com: [ '%co.%cn.geo.example.com', 'unknown.%cn.geo.example.com', 'unknown.unknown.geo.example.com']
    

    This configuration is equivalent to parsing www.example.com to the partition. Due to some problems in this parsing at present, GEODNS cannot be set under the root domain name and subdomain at the same time. I have submitted feedback on this bug. (https://github .com/PowerDNS/pdns/issues/4276). If you want to only set the parsing precision at the continent level, just write %cn.geo.example.com one less level. If you need to be accurate to the city, you can write one more level, but you need to add the GeoIP city database to the configuration file. However, the city version of the free city database is not accurate, and you also need to purchase a commercial database, which is an additional cost.

    Configure the Domain Name

    Go to your domain name registrar, enter the background to modify the settings, and add a subdomain name server record to the domain name, as shown in the figure:


    Since the NS to be set is under your own server, you must register your NS server IP address with the upper-level domain name (such as .com) on the domain name registrar, so that the upper-level domain name can resolve the IP of the NS and build your own DNS For example, there is a NS of its own under icann.org:

    $ dig icann.org ns +short
    a.iana-servers.net.
    b.iana-servers.net.
    c.iana-servers.net.
    ns.icann.org.
    

    Then look at its upper-level domain name org:

    $ dig org ns +short
    a2.org.afilias-nst.info.
    b0.org.afilias-nst.org.
    d0.org.afilias-nst.org.
    c0.org.afilias-nst.info.
    a0.org.afilias-nst.info.
    b2.org.afilias-nst.org.
    

    Find any server and query the authoritative record (I don’t need +short ):

    $ dig @a0.org.afilias-nst.info icann.org ns
    ;; QUESTION SECTION:
    ;icann.org.INNS
    ;; AUTHORITY SECTION:
    icann.org.86400INNSc.iana-servers.net.
    icann.org.86400INNSa.iana-servers.net.
    icann.org.86400INNSns.icann.org.
    icann.org.86400INNSb.iana-servers.net.
    ;; ADDITIONAL SECTION:
    ns.icann.org.86400INA199.4.138.53
    ns.icann.org.86400INAAAA2001:500:89::53
    

    It can be seen that the NS server in this org has already returned the records of ns.icann.org. This is why you need to fill in the IP address in the domain name registrar. However you’d better return the same NS and the same IP on the DNS server under your domain name as well. Finally, don’t forget to change the NS record of the domain name.

    Some Advanced Writing of YAML

    In the YAML I just used, I have actually used the advanced YAML writing method, that is, &variable sets variables, *variable uses variables, which is very similar to the LINK record under CloudXNS, for example, under CloudXNS you can write:

    www.example.com 600 IN A 10.0.0.1
    www.example.com 600 IN A 10.0.0.2
    www.example.com 600 IN AAAA ::1
    www.example.com 600 IN AAAA ::2
    sub.example.com 600 IN LINK www.example.com
    

    Then in your YAML record you can write:

    www.example.com: &www
      - a: 10.0.0.1
      - a: 10.0.0.2
      - aaaa: ::1
      - aaaa: ::2
    sub.example.com: *www
    

    This is a high-level way of writing YAML without any additional support.

    Add DNSSEC support

    For details, you can Reference Documentation, run the following command:

    $ mkdir /etc/powerdns/key
    $ pdnsutil secure-zone example.com
    $ pdnsutil show-zone example.com
    

    The result returned by the last command is the record you need to set at the domain name registrar. It is not recommended to set all of them. Just set ECDSAP256SHA256 - SHA256 digest. Finally, check the settings online Test address 1 Test address 2, there may be a few days of caching time. My inspection results

    Some Other Interesting Stuff

    You can write this in YAML, to make it easier for you to debug:

    "*.ip.example.com":
      - TXT:
          content: "IP%af: %ip, Continent: %cn, Country: %co, ASn: %as, Region: %re, Organisation: %na, City: %ci"
          ttl: 0
    

    These variables can be used as your GEODNS criteria, as well as checking your GEOIP database. Then, check the posture correctly:

    $ random=`head -200 /dev/urandom md5` ; dig ${random}.ip.example txt +short
    "IPv4: 42.83.200.23, Continent: as, Country: chn, ASn: unknown, Region: unknown, Organisation: unknown, City: unknown"
    

    The IP address is the DNS cache server address (if you enable EDNS Client Subnet and the cache server supports it, then it is your own IP, but if you use 8.8.8.8, you will see that the last digit of your IP is 0), if you If you specify to check from your own server locally, then return your own IP address directly. Since I only have the country database installed, everything is Unknown except for the continent and country.

    Advanced Use

    Establish Distributed DNS

    In general, it is a DNS resolution server of a Master and a Slave, but in this case, there may be problems with DNSSEC, so I set up two Master servers, automatically synchronize records, and set same DNSSEC Private Key , nothing seems to go wrong (after all, all records, including SOA, are exactly the same), my server’s current configuration

    $ dig @a.gtld-servers.net guozeyu.com
    ;; QUESTION SECTION:
    ;guozeyu.com.INA
    ;; AUTHORITY SECTION:
    guozeyu.com.172800INNSa.geo.ns.tloxygen.net.
    guozeyu.com.172800INNSc.geo.ns.tloxygen.net.
    ;; ADDITIONAL SECTION:
    a.geo.ns.tloxygen.net.172800INA198.251.90.65
    a.geo.ns.tloxygen.net.172800INAAAA2605:6400:10:6a9::2
    c.geo.ns.tloxygen.net.172800INA104.196.241.116
    c.geo.ns.tloxygen.net.172800INAAAA2605:6400:20:b5e::2
    

    Among them are two IPv4 and two IPv6, of which a.geo.ns.tloxygen.net. is an IP address using Anycast technology, which is provided by three servers behind it. c.geo.ns.tloxygen.net. belongs to the host of another service provider, so there is a backup after it hangs, which is more stable.

    Anycast or Unicast?

    A distributed DNS like mine is actually a combination of Unicast and Anycast. One problem is that connecting to one of them in one place will be faster, but the other will be slower. Only with a DNS cache server that supports asynchronous query or with GeoIP, it is possible to connect to the fastest DNS authoritative server, otherwise it is a random connection, and if a server hangs, then the corresponding IP of the server is obsolete. Anycast is an IP corresponding to multiple hosts, but I have no conditions to use it. This may cost more for individuals. Either you have an AS number and let the host provider give you access, or your host provider provides cross-regional access. Load Balancing IP. My VPS is in two different hosting companies, and I don’t have AS, so I can’t use Anycast. I think Anycast should be used for DNS services, because the IP corresponding to the DNS server cannot be GEODNS (because this is the root domain name that is resolved for you). After using Anycast, the fastest connection rate can basically be guaranteed, and a server has an IP address. Still usable. Additionally, DNS must forward both TCP and UDP port 53.

    Automatically Switch when Downtime

    How to realize automatic switchover when downtime? The process to achieve this is: Monitoring service finds downtime -> Sends a downtime request to the server -> The server processes the downtime, resolves to an alternate IP/pauses parsing monitoring service finds that the service is normal -> Sends a normal service request to the server -> The server processes the service normally, and the recovery analysis can create two YAML files, one is used by default, and the other is used when the server is down. When the monitoring service finds that the server is down, reload another YAML file, and then this is Downtime mode.

    --------------------------------------

    Self-built PowerDNS Advanced: GeoDNS, dnsdist, Lua Records

    This article will talk about setting up your own DNS authoritative server (serving your own domain name, this is not a public DNS cache server) using PowerDNS’s GeoIP Backend.

    By using PowerDNS, you can build a DNS server that supports partition resolution (fine to country, city, ASN, custom IP segment), EDNS-Client-Subnet, DNSSEC, IPv6 on your own server.

    This article is for domain name owners and webmasters, and is about authoritative DNS servers, not DNS caching servers. If you want to know more about DNS, please refer to Detailed Explanation of DNS Domain Name Resolution System - Basics and 'Introduction to DNSSEC, How Signatures Work'.(https://www.ze3kr.com/2018/03/dnssec/

    This article is an update to ‘self-built PowerDNS intelligent resolution server’. The advantages and disadvantages of self-built DNS, configuring DNSSEC, and distributed DNS services are described in the previous article, which will be omitted in this article. This article mainly updates the following content:

    1. This article applies to the latest PowerDNS 4.2.0
    2. Use the database in MaxMind GeoIP 2 mmdb format
    3. Describe how to set partition resolution for the root domain name
    4. Use dnsdist to limit IP access rate and defend against DOS attacks.

    Install PowerDNS Authoritative Server and dnsdist

    Considering the different default versions of operating system software sources, it is recommended to go to PowerDNS repositories reconfigure the software sources for PowerDNS Authoritative Server (please Add 4.2 or above). You can also configure dnsdist’s repositories (please add version 1.2 or above).

    After adding the repositories, update the software list and install pdns-server and pdns-backend-geoip. Under Debian/Ubuntu:

    sudo apt-get install pdns-server pdns-backend-geoip
    

    It should be noted that the systemd-resolved service may be included by default after Ubuntu 18.04 LTS. This service occupies port 53 of the loopback address, which conflicts with the port (0.0.0.0:53) required by PowerDNS. . You can: 1. Disable this service, 2. Modify PowerDNS’s local-address and [local-ipv6](https: //doc.powerdns.com/md/authoritative/settings/#local-ipv6) Configure to listen to external network IP addresses only, 3. Modify [local-port](https://doc.powerdns.com/md/authoritative/ settings/#local-port) is a non-53 port and forwarded using dnsdist (see below for details).

    If you want to configure the user-side IP access rate, install dnsdist:

    sudo apt-get install dnsdist
    

    Disable systemd-resolved

    If you choose to disable systemd-resolved, you can execute the following code:

    sudo systemctl disable systemd-resolved.service
    sudo systemctl stop systemd-resolved
    

    Install geoipupdate and download GeoIP2

    To implement partition resolution, we need the GeoIP database. The latest version of PowerDNS GeoIP Backend (4.2.0) already supports the mmdb format of GeoIP2, and also supports the dat format. The boss’s database only supports dat format. Since MaxMind has discontinued maintaining a free dat format database, it is highly recommended to use PowerDNS version 4.2 and above and use mmdb format instead IP database**.

    First create a configuration file, create /etc/GeoIP.conf with the following content (including IPv4 and IPv6 country, city, and ASN data):

    ProductIds GeoLite2-Country GeoLite2-City GeoLite2-ASN
    DatabaseDirectory /usr/share/GeoIP
    

    It is recommended to install geoipupdate, which can be installed in Ubuntu as follows:

    sudo add-apt-repository ppa:maxmind/ppa
    sudo apt update
    sudo apt install geoipupdate
    

    Then download/update GeoIP2:

    sudo geoipupdate -v
    

    All done!

    It is also recommended to configure Crontab to periodically execute the above command to update the database file (and reload the PowerDNS service) to update the GeoIP database.

    Configure PowerDNS

    The configuration file of PowerDNS (hereinafter referred to as pdns) is located in /etc/powerdns. First delete the original demo configuration of PowerDNS, and then create a folder to store the DNSSEC key file:

    sudo rm /etc/powerdns/pdns.d/*
    sudo mkdir /etc/powerdns/keys
    

    Then create the file, create /etc/powerdns/pdns.d/geoip.conf with the following content:

    launch=geoip
    geoip-database-files=/usr/share/GeoIP/GeoLite2-Country.mmdb /usr/share/GeoIP/GeoLite2-City.mmdb /usr/share/GeoIP/GeoLite2-ASN.mmdb
    geoip-zones-file=/etc/powerdns/zones.yaml
    geoip-dnssec-keydir=/etc/powerdns/key
    

    In the geoip-database option, you can set up one or more GeoIP databases as needed.

    Configure DNS records

    You can create the file /etc/powerdns/zones.yaml to configure DNS records. For the specific format, see Zonefile format.

    It should be noted that if mmdb is used, %re is the two-digit regional abbreviation for ISO3166. If using dat, it is the region code for GeoIP.

    Since PowerDNS GeoIP Backend only supports partition resolution by domain name configuration, and does not support partition resolution by record configuration, so to configure root domain name partition resolution, you can refer to the following configuration (YAML format, the same below):

    domains:
    - domain: example.com
      ttl: 300
      records:
        unknown.cn.example.com:
          - soa: &soa ns1.example.com hostmaster.example.com 2014090125 7200 3600 1209600 3600
          - ns: &ns1
               content: ns1.example.com
               ttl: 600
          - ns: &ns2 ns2.example.com
          - mx: &mx 10 mx.example.com
          - a: 10.1.1.1
        bj.cn.example.com:
          - soa: *soa
          - ns: *ns1
          -ns: *ns2
          - mx: *mx
          - a: 10.1.2.1
        unknown.unknown.example.com:
          - soa: *soa
          - ns: *ns1
          -ns: *ns2
          - mx: *mx
          - a: 10.1.3.1
        ns1.example.com:
          - a: 10.0.1.1
          - aaaa: ::1
        ns2.example.com:
          - a: 10.0.2.1
      services:
        example.com: [ '%ci.%cc.service.geo.example.com', 'unknown.%cc.service.geo.example.com', 'unknown.unknown.service.geo.example.com']
    

    As you can see, in order to configure sub-regional resolution of the domain name, we need to configure all types of records for each region. The root domain name usually has many record types, so it is relatively cumbersome to configure. The above YAML writing uses variables, which can reduce the repeated records of configuration. (&variable sets variables, *variable uses variables)

    debug

    You can debug by configuring logging as follows:

    debug.tlo.xyz:
      - a: "%ip4"
      - aaaa: "%ip6"
      - txt: "co: %co; cc: %cc; cn: %cn; af: %af; re: %re; na: %na; as: %as; ci: %ci; ip: %ip"
    

    Tested on the client through a command similar to the following (replace 10.11.12.13 with the IP address the service is listening on), and the following results are obtained:

    $ dig @10.11.12.13 debug.example.com
      
    debug.example.com. 3600 IN TXT "co: us; cc: us; cn: na; af: v4; re: ca; na: quadranet enterprises llc; as: 8100; ci: los angeles; ip: 10.11.12.13 "
    debug.example.com.3600 IN A 10.11.12.13
    

    This way you can see the specific value of each variable.

    Lua records

    In PowerDNS 4.2, Lua logging feature. The main function of its Lua record is that it can be configured to automatically switch records when downtime.

    Since Lua records can use the Lua programming language to execute arbitrary code, which is relatively dangerous, PowerDNS disables this function by default and needs to be enabled in the configuration file:

    enable-lua-records=yes
    

    Configure the following records, which will return dynamically available A records. If the ports of both IPs are available (here is port 443), an IP address will be returned randomly, if one is unavailable, only the address of the available IP will be returned, otherwise both IPs will be returned at the same time:

    sub.example.com:
      - lua: A "ifportup(443, {'192.0.2.1', '192.0.2.2'})"
    

    Configure the following records to automatically check the status of the specified URL. By default, the first group of IP addresses will be returned. If the first group of IP addresses is unavailable, the second group will be returned:

    sub.example.com:
      - lua: A "ifurlup('https://sub.example.com/', {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}})"
    

    Lua records can be used with GeoIP functionality and can coexist with other types of records. In addition, the status check is not synchronized with the request, but periodically checks whether it is available in the background, so using the status check will not increase the delay of DNS requests.

    configure dnsdist

    By now, your DNS server should be working. Configuring dnsdist is described below.

    dnsdist is equivalent to adding a layer of proxy on top of pdns, which can be configured to limit the access rate and play an anti-DOS role. Under normal circumstances, after the installation of dnsdist is completed, its service will start automatically.

    In this example, change the main program listener of pdns to 127.0.0.1:8053. Create or modify the file /etc/dnsdist/dnsdist.conf with the following content:

    newServer{address="127.0.0.1:8053",useClientSubnet=true}
    setLocal("10.0.1.1")
    setACL({'0.0.0.0/0', '::/0'})
    setECSSourcePrefixV4(32)
    setECSSourcePrefixV6(128)
    addAction(MaxQSIPRule(10, 32, 56), TCAction())
    addAction(MaxQSIPRule(20, 32, 56), DropAction())
    addAction(MaxQSIPRule(40, 24, 48), TCAction())
    addAction(MaxQSIPRule(80, 24, 48), DropAction())
    addAction(MaxQSIPRule(160, 16, 40), TCAction())
    addAction(MaxQSIPRule(320, 16, 40), DropAction())
    

    The newServer statement sets the server proxied by dnsdist, which is the IP address and port number on which pdns listens. setLocal sets the listening ip address of dnsdist. setACL sets the allowed IP addresses, here all IPv6 and IPv4 access is allowed. setECSSourcePrefixV4 and setECSSourcePrefixV6 set the number of bits of the IP address transmitted by the EDNS Client Subnet Client function. Here, 32 bits are set for IPv4, and 128 bits are set for IPv6, that is, the full length of the IP address is reserved. A smaller value than this can also be set in actual production.

    The last few lines addAction and MaxQPSIPRule define the access rate limit. Where MaxQSIPRule has three parameters. The first parameter is qps, which is queries per second, the number of requests per second. The second parameter is the CIDR value for IPv4, which defaults to 32, and the third parameter is the CIDR value for IPv6, which defaults to 64. TCAction represents asking the client to use a TCP request, and DropAction represents rejecting the request. When an ordinary client receives a request from the DNS server to use TCP, it will use TCP to make a DNS request, which does not affect the use of ordinary users. DOS generally does not attack the TCP DNS service.

    For example, the following statement means:

    addAction(MaxQSIPRule(40, 24, 48), TCAction())
    

    Limits the qps of /24 IPv4 addresses (256) and /48 IPv6 addresses (2^80) to 40, if it exceeds, the client is required to use TCP requests.

    In addition to TCAction and DropAction, DelayAction (an integer parameter representing the number of milliseconds to delay) and NoRecurseAction (specifically to limit requests marked with recursion ((RD))) can also be used.

    Therefore, using dnsdist with pdns can make the DNS service have a certain anti-DOS ability.


    from https://www.guozeyu.com/2016/08/self-host-dns/