MySQL+BIND-dlz 实现智能DNS

配置环境

系统:centos 6.8
Mysql: 5.7
BIND: 9.11.0 

CentOS6编译环境安装

yum groupinstall "Development Tools"
yum install openssl-devel

mysql 安装

这里直接使用官方yum源安装
1. 找对应系统版本的rpm包,https://dev.mysql.com/downloads/repo/yum/
2. sudo yum localinstall mysql57-community-release-el6-{version-number}.noarch.rpm
3. 查看开启的mysql是哪个版本的yum repolist enabled | grep "mysql.*-community.*"
4. 官方默认5.7直接安装 sudo yum install mysql-community-server mysql-community-devel
5. 启动 sudo service mysqld start
6. 查看状态 sudo service mysqld status
7. 找到临时密码 sudo grep 'temporary password' /var/log/mysqld.log
8. 登录并修改密码 mysql -uroot -p  
   ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';
其他需求查看官网教程:https://dev.mysql.com/doc/refman/5.7/en/linux-installation-yum-repo.html

Bind编译安装dlz插件

下载: https://www.isc.org/downloads/

1. 添加用户,和编译安装bind 
# tar xvf bind-9.11.0-P1.tar.gz
# cd bind-9.11.0-P1
# groupadd -r named
# useradd -s /sbin/nologin -M -r -g named named
# ./configure --with-dlz-mysql --enable-largefile --enable-threads=yes --prefix=/usr/local/bind --with-openssl
# make -j 4
# make install 
注: 这里的--enable-threds一般建议为no,dlz开启mysql多线程会崩溃,我为了测试所以编译时开了多线程,结果不行.
再注:后面有开启多线程的方法,所以推荐开启多线程。
2. 这里编译引用libmysqlclient.so可能会报错,我这里该库文件所在位置为/usr/lib64/mysql/libmysqlclient.so 需要在/usr/lib/下做个软链接
#ln -s /usr/lib64/mysql/libmysqlclient.so /usr/lib/libmysqlclient.so
3. 配置bind 环境变量
# chown -R named:named /usr/local/bind 
# echo "export PATH=${PATH}:/usr/local/bind/sbin/:/usr/local/bind/bin/" >> /etc/profile
# source /etc/profile
4. 配置rndc  配置named.conf
# cd /usr/local/bind/etc/
# rndc-confgen -r /dev/urandom >rndc.conf
# 添加其他配置
#  options {
        directory "/var/named/";
        recursion yes;
        listen-on port 53    { any; };
        dump-file "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        allow-query { any; };
        blackhole { none; };
 };
# mkdir /var/named/
# wget -O /var/named/named.ca  http://www.internic.net/domain/named.root
# chown -R named:named /var/named/
5. 启动named,查看根递归解析域名是否成功
#named -u named -n 1 -c /usr/local/bind/etc/named.conf
#dig www.baidu.com @127.0.0.1
如果这一步成功的话,一个基本的dns就搭建成功了。

配置dlz数据库查询

1. 创建单独的数据库
# mysql -uroot -p
# > create database bind;
2. 建表
#> CREATE TABLE IF NOT EXISTS `dns_records` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `zone` varchar(255) NOT NULL,
  `host` varchar(255) NOT NULL DEFAULT '@',
  `type` enum('A','MX','CNAME','NS','SOA','PTR','TXT','AAAA','SVR','URL') NOT NULL,
  `data` varchar(255) DEFAULT NULL,
  `ttl` int(11) NOT NULL DEFAULT '3600',
  `mx_priority` int(11) DEFAULT NULL,
  `view`  enum('any', 'Telecom', 'Unicom', 'CMCC', 'ours') NOT NULL  DEFAULT "any" ,
  `priority` tinyint UNSIGNED NOT NULL DEFAULT '255',
  `refresh` int(11) NOT NULL DEFAULT '28800',
  `retry` int(11) NOT NULL DEFAULT '14400',
  `expire` int(11) NOT NULL DEFAULT '86400',
  `minimum` int(11) NOT NULL DEFAULT '86400',
  `serial` bigint(20) NOT NULL DEFAULT '2015050917',
  `resp_person` varchar(64) NOT NULL DEFAULT 'ddns.net',
  `primary_ns` varchar(64) NOT NULL DEFAULT 'ns.ddns.net.',
  PRIMARY KEY (`id`),
  KEY `type` (`type`),
  KEY `host` (`host`),
  KEY `zone` (`zone`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
view:是区分不同网络区域的字段.
Priority:是区分不同优先级的字段.
3. 创建单独用户,并授权
# grant all privileges on bind.* to named@'%' identified by "named_passwd";
# flush privileges;
4. 创建view, 在named.conf中加入
#view "ours_domain" {
        match-clients           {127.0.0.1; };
        allow-query-cache           {any; };
        allow-recursion          {any; };
        allow-transfer          {none; };
 
        dlz "Mysql zone" {
               database        "mysql
               {host=localhost dbname=bind ssl=false port=3306 user=named pass=named}
               {select zone from dns_records where zone='$zone$'}
               {select ttl, type, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"') when lower(type) = 'soa' then concat_ws(' ', data, resp_person, serial, refresh, retry, expire, minimum) else data end from dns_records where zone = '$zone$' and host = '$record$'}"; 
        };
        zone "."  IN {
            type hint;
            file "named.ca";
        };
 
};
5. 插入数据
> insert into named.dns_records (zone, host, type, data, ttl) VALUES ('test.info', 'www', 'A', '1.1.1.1', '60');
> insert into named.dns_records (zone, host, type, data, ttl) VALUES ('test.info', 'mail', 'CNAME', 'www', '60');
> insert into named.dns_records (zone, host, type, data, ttl) VALUES ('test.info', '@', 'NS', 'ns', '60');
> insert into named.dns_records (zone, host, type, data, ttl) VALUES ('test.info', 'ns', 'A', '127.0.0.1', '60');
6.测试结果
# dig  @127.0.0.1
# dig mail.test.info @127.0.0.1
# dig -t NS test.info @127.0.0.1 
# dig -t ANY test.info @127.0.0.1

启动脚本

#!/bin/bash
# named a network name service.
# chkconfig: 345 87 75
# description: a name server

[ -r /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions

Builddir=/usr/local/bind
PidFile=/usr/local/bind/var/run/named/named.pid
LockFile=/var/lock/subsys/named
Sbindir=${Builddir}/sbin
Configfile=${Builddir}/etc/named.conf
CheckConf=${Builddir}/sbin/named-checkconf
named=named

if [ ! -f ${Configfile} ]
then
    echo "Can't find named.conf "
    exit 1
fi

if [ ! -d /var/run/named/ ]
then
    echo "could not open directory '/var/run/named/': Permission denied "
    exit 1
elif [ ! -w /var/run/named/ ]
    then
        echo "could not open directory '/var/run/named/': Permission denied "
        exit 1
fi


if [ ! -r ${Configfile} ]
then
    echo "Error: ${Configfile} is not readfile!"
    exit 1
else
    $CheckConf
    if [ $? != 0 ]
    then
        echo -e "Please check config file in \033[31m${Configfile} \033[0m!"
        exit 2
    fi
fi

start() {
    [ -x ${Builddir}/sbin/$named ] ||   exit 4
    if [ -f $LockFile ]; then
        echo -n "$named is already running..."
        echo_failure
        echo
        exit 5
    fi

    echo -n "Starting $named: "
    daemon --pidfile "$PidFile" ${Sbindir}/$named -u named -n 1 -c ${Configfile}
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        touch $LockFile
        return 0
    else
        rm -f $LockFile $PidFile
        return 1
    fi
}

stop() {
    if [ ! -f $LockFile ];then
        echo "$named is not started."
        echo_failure
    fi

    echo -n "Stopping $named: "
    killproc $named
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && rm -f $LockFile
    return 0
}

restart() {
    stop
    sleep 1
    start
}

reload() {
    echo -n "Reloading $named: "
    killproc $named -HUP
    RETVAL=$?
    echo
    return $RETVAL
}


status() {
    if pidof $named > /dev/null && [ -f $PidFile ]; then
        echo "$named is running..."
    else
        echo "$named is stopped..."
    fi
}

case $1 in
start)
    start ;;
stop)
    stop ;;
restart)
    restart ;;
reload)
    reload ;;
status)
    status ;;
*)
    echo "Usage:named {start|stop|status|reload|restart}"
    exit 2;;
esac

关于dlz默认开启多线程,Mysql崩溃问题

默认编译开启多线程支持后,每次启动后,查询一次,dlz对mysql的接口就会崩溃。
其实官方已经解决了这个问题,https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=commit;h=5ba1d3dcc5739a1f77ec2875b276b163a42ef1e8

首先在源码包下面找到bind-9.11.0-P1/contrib/dlz/modules/mysql 目录
里面有dlz_mysql_dynamic.c 源码执行make 编译一下,可能会报错,还是之前mysql库文件那个,如果之前设置过应该没问题。
在contrib/dlz/modules/mysql/testing 下面有给出的配置文件和数据库文件,按照READEME导入测试即可。
其中最重要的是加一句 database "dlopen ../dlz_mysql_dynamic.so
这个.so就是刚才编译出来的库文件,把它放在你的配置文件目录下载,加载之后就可以了。以前的配置可以不变,即可支持多线程。
终于不崩溃了。其实数据库也可以使用postgresql,这个亲测dlz支持多线程,也不崩溃。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容