一.介绍
之前看兽兽在V2上介绍了gdnsd的文章,马上点了一波收藏,因为CentOS没有现成的包,所以一直放在那懒得折腾。最近遇到CloudXNS这件事之后开始寻思着拿出来折腾下,在折腾了好几天PowerDNS后终于可以腾出手来搞这货了。
这个还是很有特色的,因为它有个插件系统,功能还是挺强大的,因为实现了自带的状态监控(http以及tcp),并且能够通过多个插件配合实现宕机切换,很有意思,还能通过外部命令来进行自定义的检测。此外,和PowerDNS不同的是这个由于使用了libmaxminddb库,支持GeoIP2格式数据库。
二.安装
比起PowerDNS不如的是这个连个spec都不给,我去网上翻来翻去,结合Github历史Commit中的spec撸了个出来,试了下没报错,感动,至于init脚本,其实不用也行,因为gdnsd自带控制,不过为了方便自启我还是找了个,别人写的,试了下还行就懒得自己动手了,已经打包到rpm文件中——>传送门
官方的依赖有ragel,而且只支持6.x版本(貌似是因为7.0出来的比较晚或者说官方更新的不勤,最后更新还是16年的了),这就带来了一个问题,CentOS6没这个包,CentOS7又只有7.x的,于是我只能顺便打个ragel的包了,然后因为这个依赖colm,于是……还好主要就这俩,其他的rpmforge以及epel源里都有,当然,为了更好的使用我把libmaxminddb也打包了个最新版本。
总而言之,CentOS6的应该是能直接用我的包了,7的同学可以自己研究下_(:з」∠)_如果我哪天换7了也许会做一份……如果想自己编译的同学请参考官方安装指导——>传送门
另外为了方便请下载release版本,直接git的会比较麻烦,因为需要autoreconf然后对automake autoconf以及libtool都要求较高的版本,可能源里的不能满足要求。
CentOS6 快捷通道
yum install http://down.senra.me/Senra-Build/colm/colm-0.13.0.4-2.el6.x86_64.rpm -y yum install http://down.senra.me/Senra-Build/ragel/ragel-6.10-1.el6.x86_64.rpm -y yum install http://down.senra.me/Senra-Build/libmaxminddb/libmaxminddb-1.2.0-4.el6.x86_64.rpm -y yum install http://down.senra.me/Senra-Build/gdnsd/gdnsd-2.2.4-1.el6.x86_64.rpm -y
在这个过程中可能安装其他依赖,如果出问题请添加rpmforge以及epel源。
这部分参考了一些东西,列举一下
三.配置
rpm打包的时候我就把需要的各个配置目录以及运行用户全写进去了,所以不用额外处理,唯一需要在意的是如果要使用geoip功能请创建/etc/gdnsd/geoip 目录并把数据库丢这个文件夹里,下面演示的时候也会提到,这部分流程参考了兽兽的教程——>传送门
不过说在前头,这玩意我还没玩明白,很多玩法请参照man以及GitHub上的wiki——>传送门
简易GeoDNS配置,参照烧饼博客
cat >/etc/gdnsd/config<<'EOF' options => { listen => any ;监听所有interface,如果指定ip的话可以带上端口 dns_port => 53 ;对于没有指定端口的ip就监听53端口 chaos_response => "SenraDNS" ;返回信息 } service_types => { example_monitor => { ;一个http检测插件 plugin => http_status ok_codes => [200, 301, 302, 403, 404] ;认为这些返回码代表网站正常,可以自己选择 vhost => example.org ;指定检测时使用的Host,因为只能检测ip,不带上Host会串网站 url_path => / ;检测的url路径 } } plugins => { geoip => { ;geoip插件 maps => { china_map => { geoip_db => GeoLiteCity.dat ;指定数据库 datacenters => [default-dc, cn-dc] ;类似meta插件指定的地址标签,按照官方说明geoip几乎包括了meta插件的全部代码,是它的超集,所以搞不懂可以去看看meta插件说明 map => { AS => {CN => [cn-dc, default-dc]} ;指定大陆为AS(亚洲),国家为CN(中国)的返回cn-dc对应记录,不然就返回后一个default-dc,有多个大陆或者国家会全部匹配过去 } } } resources => { example_org => { map => china_map ;使用的map映射 service_types => example_monitor ;使用的检测服务 dcmap => { cn-dc => { addrs_v4 => 192.0.2.4 addrs_v6 => 2001:DB8::4 }, default-dc => { addrs_v4 => 192.0.2.5 addrs_v6 => 2001:DB8::5 }, } } } } } EOF cat >/etc/gdnsd/zones/example.com<<'EOF' $TTL 86400 @ IN SOA ns1.example.com. hostmaster.example.com. ( 1 ; serial 7200 ; refresh 900 ; retry 1209600 ; expire 10800 ; ncache ) @ NS ns1.example.com. @ NS ns2.example.com. ns1 A 192.0.2.2 ns2 A 192.0.2.3 ns1 AAAA 2001:DB8::2 ns2 AAAA 2001:DB8::3 EOF cat >/etc/gdnsd/zones/example.org<<'EOF' $TTL 3600 @ IN SOA ns1.example.com. hostmaster.example.com. ( 1 ; serial 7200 ; refresh 900 ; retry 1209600 ; expire 10800 ; ncache ) @ NS ns1.example.com. @ NS ns2.example.com. @ DYNA geoip!example_org ;使用配置中的geoip插件来实现动态A(DYA)记录 www CNAME example.org. EOF mkdir /etc/gdnsd/geoip cd /etc/gdnsd/geoip wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz && gzip -df GeoLiteCity.dat.gz #检测配置是否正确 service gdnsd checkconf #检测gdnsd状态 service gdnsd status
插件介绍
#记录类 GdnsdPluginSimplefo 用于切换主备记录,可配合状态检测实现宕机切换,仅支持A(AAAA)记录 GdnsdPluginMultifo 类似上面的,但是这是多IP轮询状态下切换IP组,仅支持A(AAAA)记录 GdnsdPluginWeighted 带权重的负载均衡式,支持A(AAAA)记录以及CNAME记录 GdnsdPluginMetafo 这个是给记录或者记录组加标签,然后可以在其他插件中调用,支持A(AAAA)记录以及CNAME记录 GdnsdPluginGeoip 使用MaxMind的GeoIP或者GeoIP2格式数据库来进行基于地理位置的负载均衡GSLB,当然也可以用于实现GeoDNS(其实一个意思),仅支持A(AAAA)记录 #检测类 GdnsdPluginHttpStatus 可以通过http方式检测网站的状态码,如果在设置的正常状态码列表中即为正常,反之触发宕机切换,可指定端口 GdnsdPluginTcpConnect 类似上面的,但是是通过TCP检测端口是否为开放状态,可指定端口 GdnsdPluginExtmon 通过调用shell命令来进行检测,判断状态依靠返回码 GdnsdPluginExtfile 通过读取文件中的内容来判断状态,文件内容可以为其他监控生成数据,但是要依据格式 #特殊类 GdnsdPluginStatic 直接返回固定的解析结果,支持A(AAAA)记录以及CNAME记录,基本上只用于测试 GdnsdPluginReflect 用于在线调试的插件,可以根据配置返回请求解析的IP以及请求信息中的edns的IP GdnsdPluginNull 额,这个……真的是null,ipv4返回0.0.0.0,ipv6返回::,CNAME返回invalid,别问我是拿来干嘛的,我也不知道
四.同步
这部分其实的话……跟PowerDNS差不多,rsync的可以参考烧饼博客的最后一部分,btsync和syncthing的看我博客历史文章吧,左边搜索一下就有,至于文件同步后重载配置,gdnsd也有和pdns_control reload类似的命令,是gdnsd reload-zones,使用了我的rpm包的建议前面加个service来通过init脚本重载
如果你的内核版本够高,比如是4.x的那么gdnsd有内置的inotify,会自动检测配置文件改动,如果是自带的2.63内核,那么请参照我PowerDNS的文章丢个zone_watcher脚本上去吧,改改zone文件位置就行,当然这里是文件夹类型的,建议如下,加上-r参数是递归检测文件夹内文件
echo "nohup zone_watcher 2>&1 >>/tmp/watcher.log &" >>/etc/rc.local cat >/usr/bin/zone_watcher<<'EOF' #!/bin/sh cleanlog=`echo -n "" > /tmp/gdnsd-zone.log` zonefile="/etc/gdnsd" while inotifywait -qr -e modify,move_self $zonefile >/dev/null; do echo -e "`date "+%Y-%m-%d %H:%M:%S"` Zone Changed, Reload: [ `sleep 2 & pdns_control reload || echo -n "Failed"` ]" >>/tmp/pdns-zone.log done EOF chmod +x /usr/bin/zone_watcher nohup zone_watcher 2>&1 >>/tmp/watcher.log &
这样应该就差不多了,我还得继续研究下这蛋疼的配置
文章评论
我现在使用的方案是自建PowerDNS(MySQL后端)并使用第三方Slave自动同步做备份
然后有GeoDNS需求的域名做个cname到托管在XNS的域名去
@极雪 mysql后端每个节点都要跑数据库好烦_(:з」∠)_不过这确实是个好办法,自己配geodns配置要写的东西有点多了
@Senra DNS本来就是Master+Slave架构的,只需要一个Master节点跑MySQL即可,其他节点全部做Slave模式,更新记录之后会自动同步