一.原因

自从月初CloudXNS突然翻脸,以及一个星期了,虽然我在最短的时间内知道了这个消息并在V2顺利骗了一波铜币,然后花了一个晚上迁移自己的一堆域名,成功将这个事件的影响降到了最低。但是,针对这种情况还是需要做一些预防,所以把之前攒的自建DNS的相关资料拿出来好好研究了一下,并在这几天中实验了其中一种,基于PowerDNS的GeoDNS方案,发现效果还行,于是打算分享一下,也顺便做个记录。(之后打算研究下兽兽安利过的gdns,不过这玩意好像在Centos上比较蛋疼)

二.安装

由于Centos6平台求稳,所以各种包的版本都比较落后,因此在PowerDNS的官方源中没有支持GeoIP的版本,这特么就很尴尬了,在Github发issue求助被告知因为yaml-cpp版本不够所以只能自己编译后,我就开始了长达两天的修(编)仙(译)过程。

其实吧,一开始没发现官方的Github里有打包脚本,于是只能自己拆Centos6和Centos7的src.rpm包来拼一份spec出来,在折腾半天后发现各种不对劲,于是重新去找,结果在官方的Github里发现了build-scripts/build-auth-rpm这个脚本……蛋疼,好吧,拿来修修改改,加个pdns-backend-geoip进去,然后开始了编译打包大业。接着就碰到了一个简直日狗的问题,成功编译,成功打包,成功安装,然后……查询不出设置的txt记录,提示如下

这就很绝望,因为查询a记录啥都正常,于是怀疑是不是编译过程中有啥依赖有问题,折腾了一天,最后发现……yaml格式的配置文件中txt记录部分少了俩空格……这,我的内心是崩溃的,大哥,你格式不对提醒下啊,别报这种八竿子打不到一起的错误啊。好吧,总算是成功了,所以用Centos6的各位就不用蛋疼了,用我的rpm包就行。

至于Centos7以及其他系统的各位,请参照官方文档从官方repo或者系统自带的仓库安装——>传送门

Centos6请参照如下,第一个yaml-cpp也是我编译的最新版本,官方的太老了,不支持,另外还会安装GeoIP这个包,请确保添加了epel或者city-fan源

之后就可以开始配置了(默认没有开机启动,请使用chkconfig pdns on来设置)

三.配置

配置的话主要有三个,pdns配置、zone配置、dnssec配置(可选)

①. pdns.conf 这个默认在/etc/pdns/pdns.conf 中,可能其他系统有所不同,找不到请使用如下命令

当然也可能找到pdns.conf-dist这个文件,这是默认配置样本,因为是GeoIP版本,所以大部分配置其实都没用,可以按照我的修改下

其中如下两行,是使用alias(也叫aname)记录的前提条件,官方文档里有说明——>传送门

这个记录和CloudXNS的Link记录以及CloudFlare的CNAME Flattening记录一样都是为了解决主域名无法CNAME而生的,确实是挺好用的。

另外第一行是为了将pdns的日志分离开,如果和你其他软件的日志的冲突,也可以改成其他数字(0-7),这个需要配合如下命令

另外,请修改geoip-database-files,我这边的不是默认路径,而且额外加入了Maxmind的付费库以便提高精准度,默认路径在/usr/share/GeoIP文件夹,当然我还是建议做软连接到和zone.yaml以及key一个文件夹,方便下面的同步(如果默认GeoIP文件夹空的话,请运行geoipupdate命令更新)

下面添加一个zone.yaml方便参考使用

yaml的写法我个人还是不太熟的,所以如果你熟的话请尽管浪,我这边的IP用的是某机房全球各地的IP,地区多,拿来测试效果极好,配置完成后请启动PowerDNS (还是得把下面的dnssec配置好,起码创建好,不然缺文件不好启动),另外请务必参照yaml写法,不然别想跑起来,可以使用某个js-yaml的网页来校对是否写错——>传送门

PS.配置文件说明请查看PowerDNS文档——>传送门

参数部分大概是这样

大陆缩写不说了,国家缩写是ISO 3166-1 alpha-3,你也可以在pygeoip的const里面找到,城市这个蛋疼,请查看maxmind的region_codes.csv,这玩意你搜一下就有

至于DNSSEC,直接创建一下

然后把返回结果填到你的域名商的DNSSEC设置那儿就行,挑着填,不用都写,建议sha256那个就够了

本部分参考:

  1. 自建 PowerDNS 智能解析服务器
  2. GeoDNS with the PowerDNS GeoIP back-end

四.同步

要知道,为了保证速度以及可靠性,我们至少有两个NS节点,这也是一个域名NS的最少要求。所以,多个节点同步就是一个问题了,由于PowerDNS的GeoIP版本不存在Master以及Slave的区分,所以我们需要额外的方法来实现同步。我推荐btsync (也叫sync home或者resilio sync) 或者 syncthing 以及rsync。

我之前打折的时候买了俩btsync的key,所以这儿就用它了,安装我博客有文章,我这边不说其他的,直接写命令了 ——>传送门

然后你访问http://IP:8888/ 就能看到web界面了,简单设置密码以及节点名字啥的,然后在你本机上以及其他节点上都装好,添加一个文件夹,我这边路径就是/data/pdns了,(其实,你也可以在自己电脑上装一个,这样你直接本地修改就能静默同步到节点上,很是方便)

各个节点设置完成,尝试修改文件,确认是否会自动同步。

最后一个问题,由于PowerDNS不能自动检测zone文件变动,所以需要手动重载,如果你使用rsync的话有post script这个设置,可以在同步后执行如下命令实现重载配置

如果你用syncthing,可以使用它的api功能写个agent监听同步事件,但是btsync的api我本以为是直接用的,后来发现还额外收费,贵的可怕,放弃,换个思路。

使用inotify来直接对文件的事件监听然后触发操作,试了下发现效果意外的不错

然后就能在后台监视了,发现修改后会延迟2秒然后重载

到这儿一切都OK了,我这测试效果还行,虽然部分区域分配的ip还是有些问题,大概是因为ip库依旧不够精准以及检测节点使用的DNS向上查询可能被透传了的关心,不过也已经基本够用了。

自建DNS主要是灵活性够高,当然如果不想折腾还是建议选择现成的,毕竟自建一是维护麻烦,二是如果想要效果好成本也是挺大的,特别是DNS建议使用anycast的节点来确保在线率以及查询速度。


Senraの小窝原创文章,转载请注明来自:自建DNS系列——PowerDNS GeoIP版(多节点,分区解析)