Bind基于DLZ实现智能DNS配置教程详解

  本文章为各位介绍Bind基于DLZ实现智能DNS配置教程,如果有需要对于这个智能dns配置的朋友可以进来参考此教程.
 
  简介:在我看来基于Bind的只能DNS方案主要包括两个部分:Geolocation和Dynamic Record。国内的业界对智能DNS的定位也无非这两点,但是我所理解的智能DNS是建立在这两条基础上的智能调度系统,比如我有三个负载能力不同的数据中心,DNS可以根据数据中心的metrics(这里可能包括带宽,服务能力等)实现流量的调度,限于个人水平个人未在这个方向有所实践,这个话题留作以后讨论,所以本文只针对前两个问题。由于Bind本身的配置可运维性比较差,这就引出本文主要讨论的DLZ。
 
  原理:DLZ实际上就是扩展了Bind,将Zonefle的内容放到外部数据库里,然后给Bind配置查询语句从数据库里查询记录。当修改数据库里的记录信息的时候,无需重启Bind,下次客户请求时直接就能返回新的记录了。另外,DLZ本身不支持缓存,所以需要自己根据实际情况解决查询的问题。
 
  安装:
 
  注意:这里我以CentOS7上安装dlz-mysql模块为例。
 
  安装依赖:yum install mariadb-devel gcc wget patch make
 
  下载源码:
 
  Bind9.8之前的版本需要打patch,具体可参考DLZ官方文档,Bind9.8之后(包括9.8)的版本已经集成DLZ:
 
  wget ftp://ftp.isc.org/isc/bind9/9.10.1/bind-9.10.1.tar.gz
  tar xzf bind-9.10.1.tar.gz
  cd  bind-9.10.1
  配置:由于CentOS7目录结构上的变更,在编译dlz-mysql时会找不到库文件或者head文件,所以要做个软连接:
 
  ln -s /usr/lib/mysql /usr/lib64/mysql
  ./configure --prefix /opt/bind --with-dlz-filesystem --with-dlz-mysql
  编译:make
 
  安装:make install
 
  模型:
 
  注意:DLZ没有限制用户的数据模型,你可以根据业务逻辑定义模型,然后构造自己的查询语句即可,官方给出了建议的模型.
 
  建模:
 
  Field Type Null Key Default Extra
  zone text YES  NULL  
  host text YES  NULL  
  type text YES  NULL  
  data text     
  ttl int(11) YES  NULL  
  mx_priority text YES  NULL  
  refresh int(11) YES  NULL  
  retry int(11) YES  NULL  
  expire int(11) YES  NULL  
  minimum int(11) YES  NULL  
  serial bigint(20) YES  NULL  
  resp_person text YES  NULL  
  primary_ns text YES  NULL  
  zone 区域
  host 记录名
  type 记录类型
  data 记录值
  ttl 缓存时间
  mx_priority mx记录优先级
  refresh SOA记录的刷新时间
  retry SOA记录的重试时间
  expire SOA记录的过期时间
  minimum SOA记录的minimum
  serial SOA记录的序列号
  resp_person SOA记录的序列号
  primary_ns <尚不明确这个字段的意义>
  建库建表,新建数据库:
 
  create database demo;
 
  新建record表:
 
  CREATE TABLE IF NOT EXISTS records (
    id int(10) unsigned NOT NULL AUTO_INCREMENT,
    zone varchar(255) NOT NULL,
    host varchar(255) NOT NULL,
    type enum('A','MX','CNAME','NS','SOA','PTR','TXT','AAAA','SVR','URL') NOT NULL,
    data varchar(255) NOT NULL,
    ttl int(11) NOT NULL,
    mx_priority int(11) DEFAULT NULL,
    refresh int(11) DEFAULT NULL,
    retry int(11) DEFAULT NULL,
    expire int(11) DEFAULT NULL,
    minimum int(11) DEFAULT NULL,
    serial bigint(20) DEFAULT NULL,
    resp_person varchar(64) DEFAULT NULL,
    primary_ns varchar(64) DEFAULT NULL,
    PRIMARY KEY (id),  --phpfensi.com
    KEY type (type),
    KEY host (host),
    KEY zone (zone)
  ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
  新建acl表:
 
  CREATE TABLE IF NOT EXISTS acl (
    id int(10) unsigned NOT NULL AUTO_INCREMENT,
    zone varchar(255) NOT NULL,
    client varchar(255) NOT NULL,
    PRIMARY KEY (id),
    KEY client (client),
    KEY zone (zone)
  ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
  配置:GeoIP
 
  这块目前还没有那么灵活,基本上都是基于acl来实现的,虽然最新版的bind 9.10支持maxmind的api来做Geo,但还是改写配置文件的方式,下面是一个示例:
 
  acl "US" {
       3.0.0.0/8;
       4.0.0.0/25;
       4.0.0.128/26;
       4.0.0.192/28;
       4.0.0.208/29;
       4.0.0.216/30;
       4.0.0.220/31;
  };
  view "north_america" {
        match-clients { US; CA; MX; };
        recursion no;
        zone "foos.com" {
              type master;
              file "pri/foos-north-america.db";
        };
  };
  view "other" {
        match-clients { any; };
        recursion no;
        zone "foos.com" {
              type master;
              file "pri/foos-other.db";
        };
  };
  该示例引用自这里,但是我们可以通过DLZ实现GeoIP,二次开发一个自己的driver,然后在driver里根据client ip,结合自己的业务系统实现真正的Geo以及智能业务调度.
 
  Dynamic Record
 
  DLZ新定义了一个配置关键字dlz,完整的配置项参考官方文档,这里给出简要说明:
 
  dlz "Mysql zone" { //定义DLZ标识
     database "mysql //database为dlz这个block唯一可指定的关键字,mysql表示使用mysql driver
     {host=localhost dbname=dns_data ssl=tRue} //连接数据库的信息
     {select zone from dns_records where zone = '$zone$'} //用于findzone调用,查询zone
     {select ttl, type, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"')
          else data end from dns_records where zone = '$zone$' and host = '$record$'
          and not (type = 'SOA' or type = 'NS')} //用于lookup调用,查询record
     {select ttl, type, mx_priority, data, resp_person, serial, refresh, retry, expire, minimum
          from dns_records where zone = '$zone$' and (type = 'SOA' or type='NS')} //用于authority调用,查询SOA或者NS记录,注意这个配置是可选的,SOA和NS查询可以放到lookup调用里,具体见后文
     {select ttl, type, host, mx_priority, data, resp_person, serial, refresh, retry, expire,
          minimum from dns_records where zone = '$zone$' and not (type = 'SOA' or type = 'NS')} //用于allnode调用,和接下来的allowzonexfr一起来提供AXFR查询,可选的配置项
     {select zone from xfr_table where zone = '$zone$' and client = '$client$'} //用于allowzonexfr()调用,用于查询客户端是否可发起AXFR查询,可选的配置项
     {update data_count set count = count + 1 where zone ='$zone$'}";
  };
  注意:此配置为最新Bind版本的配置,如果是打patch的版本请将$换成%,以下的配置同样,这里也给出我的配置:
 
  logging {
      channel all {
          file "/opt/bind/log/named.log" versions 1;
          print-time yes;
          severity dynamic;
          print-category yes;
          print-severity yes;
      };
  category default { all; };
  category queries { all; };
  
  };
  
  options {
      directory "/opt/bind/var/";
      listen-on-v6 { none; };
      listen-on { any; };
      pid-file "/var/run/named.pid";
      recursion yes;
      allow-transfer {127.0.0.1;};
  };
  
  dlz "mysql-dlz" {
      database "mysql
      {host=localhost dbname=demo ssl=false port=3306 user=root pass=thinkin}
      {select zone from records where zone = '$zone$' limit 1}
      {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 records where zone = '$zone$' and host = '$record$'}
      {}
      {select ttl, type, host, mx_priority, data from records where zone = '$zone$' and not (type = 'SOA' or type = 'NS')}
      {select zone from acl where zone = '$zone$' and client = '$client$'}";
  };
  
  zone "." IN {
      type hint;
      file "named.root";
  };
  
  key "rndc-key" {
      algorithm hmac-md5;
          secret "OdEg+tCn/bMe+/2vbJgQvQ==";
  };
  
  controls {
          inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
  };
  注意:这里的配置开启了递归解析且支持本机发起的AXFR请求。
 
  根zonefile
 
  wget -SO /opt/bind/var/named.root http://www.internic.net/domain/named.root
 
  启动:/opt/bind/sbin/named -n1 -c /opt/bind/etc/named.conf -d9 -g
 
  测试,导入数据,导入records数据:
 
  INSERT INTO demo.records (zone, host, type, data, ttl) VALUES (&#phpfensi.com', 'www', 'A', '1.1.1.1', '60');
  INSERT INTO demo.records (zone, host, type, data, ttl) VALUES ('phpfensi.com', 'cloud', 'A', '2.2.2.2', '60');  
  INSERT INTO demo.records (zone, host, type, data, ttl) VALUES ('phpfensi.com', 'ns', 'A', '3.3.3.3', '60');
  INSERT INTO demo.records (zone, host, type, data, ttl) VALUES ('phpfensi.com', 'blog', 'CNAME', 'cloud.phpfensi.com.', '60');
  INSERT INTO demo.records (zone, host, type, data, ttl) VALUES ('phpfensi.com', '@', 'NS', 'ns.phpfensi.com.', '60');
  INSERT INTO demo.records (zone, host, type,  ttl, data,refresh, retry, expire, minimum, serial, resp_person) VALUES ('phpfensi.com', '@', 'SOA', '60', 'ns', '28800', '14400', '86400', '86400', '2012020809', 'admin');
  导入acl数据:
 
  INSERT INTO demo.acl (zone, client) VALUES ('phpfensi.com', '127.0.0.1');
 
  测试记录:
 
  dig @127.0.0.1 www.phpfensi.com a
  dig @127.0.0.1 blog.phpfensi.com a
  dig @127.0.0.1 blog.phpfensi.com cname
  dig @127.0.0.1 phpfensi.com ns
  dig @127.0.0.1 www.phpfensi.com axfr。
 

dawei

【声明】:站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。