鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 管理员笔记 > bind > >

智能DNS那些事(基于bind9 view的主从配置)

来源:互联网 作者:佚名 时间:2015-01-10 20:00
今天尝试了一下bind9 view智能DNS 主从配置. 一.智能DNS简介 智能DNS是域名频道在业界首创的智能解析服务。能自动判断访问者的IP地址并解析出对应的IP地址,使网通用户会访问到网通服务器,电信用户会访问到电信服务器。智能DNS就是根据用户的来路,自动智

今天尝试了一下bind9 view智能DNS 主从配置.

 
一.智能DNS简介
智能DNS是域名频道在业界首创的智能解析服务。能自动判断访问者的IP地址并解析出对应的IP地址,使网通用户会访问到网通服务器,电信用户会访问到电信服务器。智能DNS就是根据用户的来路,自动智能化判断来路IP返回给用户,而不需要用户进行选择。解决南北互联问题
二.软件及环境
Red hat 5.4x64 Bin9 主192.168.10.45 辅 192.168.10.44
 
三.安装配置
1.       bind的安装
下载bind
可直接从官网下载最新bind http://www.isc.org/software/bind
其中--libdir=/usr/lib64 可以根据自己系统来设定,32位使用--libdir=/usr/lib
 
编译安装(主从相同)
./configure --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --with-libtool --localstatedir=/var --enable-threads --with-openssl=no --enable-epoll
 
make –j 24
make install
 
 
2.       基础配置文件生成
生成rndc.conf
rndc-confgen > /etc/rndc.conf
 
生成named.conf
cat /etc/rndc.conf |tail |sed /^# //g > /etc/named.conf
 
域名文件目录
mkdir /var/named/chinanet –p
mkdir /var/named/cnc -p
useradd named
 
生成根域文件
dig -t NS . >/var/named/named.root
 
ip库文件
         开始找以前同事要的,后来发现网上可以找到 http://liubaishui.com/下载其它的bind view IP库 (netlist.inc)
 
 
主DNS配置及简要说明(建议仔细阅读,配置时如果不需要说明,可以过滤掉以”;”开始的行)
view会根据定义顺序在定义的IP列表查找,将相应结果返回请求者。这次测试分为三部分,网通、电信、其它、如果请求者的IP不能匹配到,那么将会被“其它”匹配。
 
cat /etc/named.conf
options {
directory "/var/named";
;这里可以添加其它控制参数,比如IP限制,可否递归查询等。请根据自己的生产需要添加
};
 
; rndc-key 用于控制DNS
key "rndc-key" {
         algorithm hmac-md5;
         secret "Mq+WZABoE+a/FFwgFYh3oQ==";
};
 
;以下这三个key 用于主从同步。如果不设置会出现只会同步一个域。因为view已经可以匹配到结果。而且同步回来的数据可能会是错误的,这取决于从DNS同步时IP。本文中使用内网IP,IP列表中不会有内网IP,所以会同步other域名的数据。
;key的生成方法:使用 rndc-confgen命令。使用下面的命令即可。只输出key部分。将其名称做下修改即可。有多少个view域就生成多少个。主从DNS使用的key必须相同。
; rndc-confgen |grep "# key" -A3|sed "s/^# //g"
key "cnc" {
        algorithm hmac-md5;
        secret "wPaGrqLp0XtAepn8Rc0U3w==";
};
 
key "chinanet" {
        algorithm hmac-md5;
        secret "i+uKnzR3JfSheMVLNWUH5Q==";
};
 
 
key "other" {
        algorithm hmac-md5;
        secret "3o9OOMjzusp+M82okFcWyA==";
};
 
controls {
         inet 127.0.0.1 port 953
                   allow { 127.0.0.1; } keys { "rndc-key"; };
};
;acl.conf即为下载回来的ip库。将其命名为acl.conf。其中cnc和chinanet为大写,我手动修改成了小写。如果写随意,记得其中acl的定义的名称就OK。如果拿不到ip库文件,可以邮件给我.learywolf@163.com内容示例如下。(下面的acl定义 在acl.conf中定义,这里只是示意,不要写在named.conf中)
;    acl "cnc" {
;    1.24.0.0/13;
;    1.56.0.0/13;
;    1.188.0.0/14;
;        ……………..
;    14.204.0.0/15;
;    27.8.0.0/13;
;    };
;    acl "chinanet" {
;    1.0.1.0/24;
;        ……….
;    1.0.2.0/23;
;    };
 
include "/etc/acl.conf";
 
; view 部分 三部分中会顺序匹配,我的配置顺序,电信→网通→其它
 
view "chinanet" {
; match-clients 定义了来源的IP。如果请求IP在chinanet 的acl中,那调用此view配置。其中添加的key为了实现主从同步
 match-clients { key "chinanet" ; chinanet; };
;server指定从dns的IP及所用key 以区分不同 view域。同理从dns指定主。
 server 192.168.10.44 { keys "chinanet";};
;指定根域文件 .
 zone "." IN {
         type hint;
         file "named.root";
         };
;加载chinanet.conf,其内容为常规dns配置。示例如下.注意三个view域要有三个不同的zone文件。如果不需要view 可以直接定义view控制文件中调用相同的zone文件。简单的说就是 cnc.con chinanet.conf other.conf中调用相应zone配置。其它配置不再赘述。可以查阅官方文档。
;    zone "leary.com" IN {
;            type master;
;            file "chinanet/leary.com.dns";
;    };
 include "/etc/chinanet.conf";
 notify yes;
 also-notify { 192.168.10.44; };
 allow-transfer { 192.168.10.44; };
 };
 
view "cnc" {
 match-clients { key "cnc" ;cnc; };
 server 192.168.10.44 { keys "cnc";};
 zone "." IN {
         type hint;
         file "named.root";
         };
 include "/etc/cnc.conf";
 notify yes;
 also-notify { 192.168.10.44; };
 allow-transfer { 192.168.10.44; };
 };
 
view "other" {
 match-clients { key "other" ; any; };
 server 192.168.10.44 { keys "other";};
 zone "." IN {
         type hint;
         file "named.root";
         };
 include "/etc/other.conf";
 notify yes;
 also-notify { 192.168.10.44; };
 allow-transfer { 192.168.10.44; };
 };
;end
 
 
3.       view域配置文件
/etc/cnc.conf
/etc/chinanet.conf
/etc/other.conf
分别配置其内容,需要注意:
 
zone "leary.com" IN {
        type master;
        file "cnc/leary.com.dns";
};
1) type类型,主或者从
2) zone文件位置。基础目录为/var/named. 其中对应域名解析到的IP为别定义在不同的域文件中
3) cnc 的zone放在/var/named/cnc/下,chinanet 放在/var/named/chinanet/下,other放在/var/named/下
 
 
4.       zone 文件
根据需要配置域文件。
cat /var/named/leary.com.dns
 
$TTL    86400
@ IN SOA ns.leary.com.       root.leary.com. (
                                        6             ; serial_num
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum
               IN NS           ns.leary.com.
 
@               IN A            10.1.4.165
ns               IN A            10.1.4.164
www            IN A            10.1.4.164
 
 
cat /var/named/cnc/leary.com.dns
 
$TTL    86400
@ IN SOA ns.leary.com.       root.leary.com. (
                                        6             ; serial_num
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum
               IN NS           ns.leary.com.
 
@               IN A            10.1.2.165
ns             IN A            10.1.2.164
www            IN A            10.1.2.164
 
cat /var/named/chinanet/leary.com.dns
 
$TTL    86400
@ IN SOA ns.leary.com.       root.leary.com. (
                                        6             ; serial_num
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum
               IN NS           ns.leary.com.
 
@               IN A            10.1.3.165
ns             IN A            10.1.3.164
www            IN A            10.1.3.164
 
 
5.       从DNS与主的配置区别
1) named.conf 中server的配置。 server 192.168.10.45 { keys "chinanet";};
2) view配置文件。以cnc.conf为例
zone "leary.com" IN {
        type slave;
        file "slaves/cnc/leary.com.dns";
         masters { 192.168.10.45; };
};
type 类似型为 slave
file 指定的文件位置,当然也可以按主DNS那样配置,我这里只是为了区分。
3) key 定义一定要和主一样
4) 从DNS的zone文件不用配置。可以直接从主同步
 
6.       权限修改
chown -R named:named /var/named
chown -R named /var/run/named
 
四.启动脚本及命令
1.       启动脚本。基于rhel 其它系统需要另行修改.放在/etc/init.d/named
#!/bin/bash
#
# named           This shell script takes care of starting and stopping
#                 named (BIND DNS server).
#
# chkconfig: - 13 87
# description: named (BIND) is a Domain Name Server (DNS) \
# that is used to resolve host names to IP addresses.
# probe: true
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network
 
[ -r /etc/sysconfig/named ] && . /etc/sysconfig/named
 
export KRB5_KTNAME=${KEYTAB_FILE:-/etc/named.keytab}
 
# Don't kill named during clean-up
NAMED_SHUTDOWN_TIMEOUT=${NAMED_SHUTDOWN_TIMEOUT:-100}
 
if [ -n "$ROOTDIR" ]; then
   ROOTDIR=`echo $ROOTDIR | sed 's#//*#/#g;s#/$##'`;
   rdl=`/usr/bin/readlink $ROOTDIR`;
   if [ -n "$rdl" ]; then
      ROOTDIR="$rdl";
   fi;
fi
 
RETVAL=0
named='named'
if [[ "$ENABLE_SDB" = [yY1]* ]] && [ -x /usr/sbin/named_sdb ]; then
    named='named_sdb';
fi;
prog=$named
 
nmdcOption()
{ let i=0;
 for a in $*;
 do ((++i));
     if [ $a = -c ]; then
          ((++i));
          eval 'echo $'$i;
     elif [[ $a = -c* ]]; then
          echo ${a#-c};
     fi;
 done;
}
 
named_c_option=`nmdcOption $OPTIONS`;
named_conf=${named_c_option:-/etc/named.conf};
 
dbusEnabled=0;
for a in $OPTIONS; do
    if [ $a = "-D" ]; then
         dbusEnabled=1;
    fi;
done
 
if [ $dbusEnabled -eq 0 ] && [ -z "$DISABLE_NAMED_DBUS" ] ; then
    NetworkManagerEnabled=0
    for l in 0 1 2 3 4 5 6; do
         if /sbin/chkconfig --level=$l NetworkManager >/dev/null 2>&1; then
             NetworkManagerEnabled=1;
         fi;
    done
    if [ $NetworkManagerEnabled -eq 1 ]; then
         OPTIONS="$OPTIONS -D";
    fi;
    dbusEnabled=1;
fi
 
start() {
 
         [ -x /usr/sbin/$named ] || exit 5
 
         if [ ! -r ${ROOTDIR}${named_conf} ] ; then
            if [ -z "$named_c_option" ] && [ -r ${ROOTDIR}/etc/named.caching-nameserver.conf ]; then
                named_conf='/etc/named.caching-nameserver.conf';
                OPTIONS="$OPTIONS -c ${named_conf}";
            else
                echo Locating $ROOTDIR/${named_conf} failed:
                failure
                echo;
                exit 6;
            fi;
         fi;
 
        # Start daemons.
        echo -n $"Starting $named: "
         if [ -n "`/sbin/pidof -o %PPID $named`" ]; then
                   echo -n $"$named: already running"
                   failure
                   echo
                   return 1
         fi
         ckcf_options='-z'; # enable named-checkzone for each zone (9.3.1+) !
         if [ -n "${ROOTDIR}" -a "x${ROOTDIR}" != "x/" ]; then
                   OPTIONS="${OPTIONS} -t ${ROOTDIR}"
                   ckcf_options="$ckcf_options -t ${ROOTDIR}";
                   if [ -s /etc/localtime ]; then
                       cp -fp /etc/localtime ${ROOTDIR}/etc/localtime
                   fi;
                   if [ ! -d ${ROOTDIR}/proc ]; then
                       mkdir -p ${ROOTDIR}/proc
                   fi
                   if ! egrep -q '^/proc[[:space:]]+'${ROOTDIR}'/proc' /proc/mounts; then
                       mount --bind -n /proc ${ROOTDIR}/proc >/dev/null 2>&1
                   fi
                   if [ $dbusEnabled -eq 1 ]; then
                       if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${ROOTDIR}'/var/run/dbus' /proc/mounts; then
                            mkdir -p ${ROOTDIR}/var/run/dbus
                            if [ ! -d /var/run/dbus ] ; then
                                mkdir -p /var/run/dbus ;
                            fi;
                            mount --bind -n /var/run/dbus ${ROOTDIR}/var/run/dbus > /dev/null 2>&1;
                       fi;                  
                   fi;              
         fi
 
         CHECK_ZONE_WRITE_VAR=0
         if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
                   write_master_zones=`/usr/sbin/getsebool named_write_master_zones |awk '{ print $3; }'`
                   if [ "$write_master_zones" = "on" ]; then
                            /bin/chown -f --from=root:named named:named $ROOTDIR/var/named
                   else
                            CHECK_ZONE_WRITE_VAR=1
                   fi;
         else
                   CHECK_ZONE_WRITE_VAR=1
         fi;
 
         if [ "$CHECK_ZONE_WRITE_VAR" -eq 1 ]; then
                   if echo "$ENABLE_ZONE_WRITE" | grep -q 'yes\|YES\|y\|Y'; then
                            /bin/chown -f --from=root:named named:named $ROOTDIR/var/named
                   else
                            /bin/chown -f --from=named:named root:named $ROOTDIR/var/named
                   fi;
         fi;
 
        conf_ok=0;
         if [ -x /usr/sbin/named-checkconf ] && [ -x /usr/sbin/named-checkzone ] && /usr/sbin/named-checkconf $ckcf_options ${named_conf} >/dev/null 2>&1; then
           conf_ok=1;
        else
            RETVAL=$?;
         fi
         if [ $conf_ok -eq 1 ]; then            
            daemon /usr/sbin/$named -u named ${OPTIONS};
            RETVAL=$?;
            if [ $RETVAL -eq 0 ]; then
                rm -f /var/run/named.pid
                rm -f /var/run/named_sdb.pid 2>/dev/null
                ln -s $ROOTDIR/var/run/named/named.pid /var/run/named.pid;
                if [ "$named" = "named_sdb" ]; then
                      ln -s $ROOTDIR/var/run/named/named.pid /var/run/named_sdb.pid;
                fi;
            fi;
            if [ -n "`/sbin/pidof -o %PPID $named`" ]; then
                # Verify that named actually started (JM 2006-10-04)
                if [ ! -e $ROOTDIR/var/run/named/named.pid ]; then
                    # If there is not a file containing the PID of the now running named daemon then create it (JM 2006-10-04)
                    echo `/sbin/pidof -o %PPID $named` > $ROOTDIR/var/run/named/named.pid;
                    if [ "$named" = "named_sdb" ]; then
                        echo `/sbin/pidof -o %PPID $named` > $ROOTDIR/var/run/named/named_sdb.pid;
                    fi;
                fi;
            fi;
         else
            named_err="`/usr/sbin/named-checkconf $ckcf_options $named_conf 2>&1`";      
            echo
            echo $"Error in named configuration"':';
            echo "$named_err";
            failure
            echo
            if [ -x /usr/bin/logger ]; then
                echo "$named_err" | /usr/bin/logger -pdaemon.error -tnamed
           fi;
           return 7;
        fi;
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/named
        echo
         return $RETVAL
}
stop() {
        # Stop daemons.
        echo -n $"Stopping $named: "
         /usr/sbin/rndc stop >/dev/null 2>&1
         RETVAL=$?
         [ "$RETVAL" -eq 0 ] || killproc "$named" -TERM >/dev/null 2>&1
 
         timeout=0
         RETVAL=0
         while /sbin/pidof -o %PPID "$named" >/dev/null; do
                   if [ $timeout -ge $NAMED_SHUTDOWN_TIMEOUT ]; then
                            RETVAL=1
                            break
                   else
                            sleep 2 && echo -n "."
                            timeout=$((timeout+2))
                   fi;
         done
         if [ $RETVAL -eq 0 ]; then
             rm -f /var/lock/subsys/named
             rm -f /var/run/named.pid
             rm -f /var/run/named_sdb.pid 2>/dev/null        
         fi;
        if [ -n "${ROOTDIR}" -a "x${ROOTDIR}" != "x/" ]; then
            if egrep -q '^/proc[[:space:]]+'${ROOTDIR}'/proc' /proc/mounts; then
               umount ${ROOTDIR}/proc >/dev/null 2>&1
            fi
            if [ $dbusEnabled -eq 1 ]; then
               if egrep -q '^/[^[:space:]]+[[:space:]]+'${ROOTDIR}'/var/run/dbus' /proc/mounts; then
                  umount ${ROOTDIR}/var/run/dbus > /dev/null 2>&1
               fi;
            fi;
        fi;
         if [ $RETVAL -eq 0 ]; then
             success
         else
             failure
        fi;
         echo
         return $RETVAL
}
rhstatus() {
         /usr/sbin/rndc status
         status /usr/sbin/$named
         return $?
}       
restart() {
         stop
# wait a couple of seconds for the named to finish closing down
         sleep 2
         start
}       
reload() {
        echo -n $"Reloading $named: "
         p=`/sbin/pidof -o %PPID $named`  
         RETVAL=$?
         if [ "$RETVAL" -eq 0 ]; then
             /usr/sbin/rndc reload >/dev/null 2>&1 || /bin/kill -HUP $p;
             RETVAL=$?
        fi
         [ "$RETVAL" -eq 0 ] && success $"$named reload" || failure $"$named reload"
        echo
         return $RETVAL
}
probe() {
         # named knows how to reload intelligently; we don't want linuxconf
         # to offer to restart every time
         /usr/sbin/rndc reload >/dev/null 2>&1 || echo start
         return $?
}
checkconfig() {
        ckcf_options='-z'; # enable named-checkzone for each zone (9.3.1+) !
         if [ -n "${ROOTDIR}" -a "x${ROOTDIR}" != "x/" ]; then
                   OPTIONS="${OPTIONS} -t ${ROOTDIR}"
                   ckcf_options="$ckcf_options -t ${ROOTDIR}"; 
         fi;
         if [ -x /usr/sbin/named-checkconf ] && [ -x /usr/sbin/named-checkzone ] && /usr/sbin/named-checkconf $ckcf_options ${named_conf} | cat ; then
             return 0;
         else
             return 1;
         fi
}
 
# See how we were called.
case "$1" in
         start)
                   start
                   ;;
         stop)
                   stop
                   ;;
         status)
                   rhstatus
                   ;;
         restart)
                   restart
                   ;;
         condrestart)
                   [ -e /var/lock/subsys/named ] && restart;
                   ;;
         reload)
                   reload
                   ;;
         probe)
                   probe
                   ;;
        checkconfig|configtest|check|test)
                 checkconfig
                   ;;
         *)
                 echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|configtest|probe}"
                   exit 2
esac
 
exit $?
 
chown +x /etc/init.d/named
chkconfig --add named
chkconfig named on
 
 
2.       named-checkconf 检查dns配置正确性
3.       rndc reconfig 重加载dns配置
4.       named-checkzone leary.com /var/named/leary.com.dns 重要zone配置文件
5.       rndc reload leary.com in cnc 重加载cnc 对应的zone文件配置
6.       rndc reload leary.com in chinanet 重加载chinanet 对应的zone文件配置
7.       rndc reload leary.com in other 重加载other 对就的zone文件配置
 
 
至此,可以启动dns了。
/etc/init.d/named configtest
/etc/init.d/named start
 
日志在/var/log/message,如遇问题,根据其中报错排查
 
已知问题:
会有报错如下
managed-keys-zone ./IN/chinanet: loading from master file 0eb205490a59454b6f6feb085efc6b0dab64a63f855a77e2d200c59ed055acd0.mkeys failed: file not found
touch /var/named/managed-keys.bind 依旧会报,目前没找到解决办法。但测试不影响使用。
 
测试方法:
         由于基于内网,可以分别修改acl.conf,添加192.168.0.0/16;在对应的acl中,用其它内网机器 dig 结果,正常可以得到不同的解析结果。我这里设置的,cnc为10.1.2 网段,chinanet 10.1.3网段 other 10.1.4网段。
网友评论
<