首页 > Linux系统管理 > 基于Bind+DLZ智能DNS的安装配置
2015
07-31

基于Bind+DLZ智能DNS的安装配置

1. 简介
  智能DNS(Bind-view):
智能DNS 原理很简单:在用户解析一个域名的时候的,判断一下用户使用的IP,然后跟DNS服务器内部的IP表匹配一下,看看用户是电信还是网通用户,然后给用户返回对应的IP地址。
        目前的域名服务运营商不提供智能DNS服务,所以必须自行架设DNS服务或者使用网上免费的智能DNS服务,如DNSPOD。
 
2. DLZ与传统的BIND区别
DLZ(Dynamically Loadable Zones)与传统的BIND9不同,BIND的不足之处:
* BIND从文本文件中获取数据,这样容易因为编辑错误出现问题。
* BIND需要将数据加载到内存中,如果域或者记录较多,会消耗大量的内存。
* BIND启动时解析Zone文件,对于一个记录较多的DNS来说,会耽误更多的时间。
* 如果近修改一条记录,那么要重新加载或者重启BIND 才能生效,那么需要时间,可能会影响客户端查询。
而Bind-dlz 即将帮你解决这些问题, 对Zone文件操作也更方便了,直接对数据库操作,可以很方便扩充及开发管理程序。
 
3. 服务器列表
ID 主机名 IP 角色 备注 
1 dns01 192.168.80.19 Master  
2 dns02 192.168.80.20 Slave  
 
4. BIND View规划
ID view 用途 文件 备注 
1 TEST 测试环境 test_acl.conf  
2 PRODUCT 生产环境 product_acl.conf  
3 ANY 其他   
 
* 还有一个隐藏的view是DF,这个域是默认的解析,除了TEST/PRODUCT之外的默认解析,默认解析都是和TEST的解析一致的 * 
 
5. DLZ安装
5.1. 安装MySQL
这里用的是percona-server,版本是5.6 
 
 安装依赖库和编译工具
 * yum install gcc gcc-c++ kernel-devel ncurses-devel bison cmake -y
 添加用户
 * useradd -s /sbin/nologin mysql
 解压压缩包
 * tar -zxvf  percona-server-5.6.21-69.0.tar.gz
 * cd percona-server-5.6.21-69.0
 * cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
       -DSYSCONFDIR=/usr/local/mysql/etc \
       -DMYSQL_DATADIR=/usr/local/mysql/data \
       -DMYSQL_USER=mysql \
       -DMYSQL_TCP_PORT=3306 \
       -DWITH_MYISAM_STORAGE_ENGINE=1 \
       -DWITH_INNOBASE_STORAGE_ENGINE=1 \
       -DWITH_MEMORY_STORAGE_ENGINE=1 \
       -DWITH_PARTITION_STORAGE_ENGINE=1 \
       -DEXTRA_CHARSETS=all \
       -DDEFAULT_CHARSET=utf8 \
       -DDEFAULT_COLLATION=utf8_general_ci \
       -DENABLED_LOCAL_INFILE=1 \
       -DWITH_READLINE=1
 * make && make install
 拷贝启动脚本,并设置开机启动
 * cp support-files/mysql.server /etc/init.d/mysqld
 * chmod +x  /etc/init.d/mysqld
 创建相关目录
 * mkdir -p /usr/local/mysql/etc
 * mkdir -p /usr/local/mysql/logs/
 移除系统默认的mysql配置文件
 * mv /etc/my.cnf  /etc/my.cnf.bak
 
5.2. 配置MySQL
以上步骤都没问题的情况,开始配置MySQL,配置文件内容如下 
 
[mysqld]
character_set_server=utf8
#Misc
user = mysql
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir =  /usr/local/mysql/data
ft_min_word_len=1
max_allowed_packet = 32M
 
#Performance
log-bin=mysql-bin
binlog_format="MIXED"
net_read_timeout = 60
wait_timeout = 100
interactive_timeout = 100
open_files_limit = 10240
back_log = 150
max_connections = 1000
max_connect_errors = 100000
external-locking = FALSE
performance_schema = 0
 
#buffers & cache
table_open_cache = 2048   #在mysql5.6不再支持table_cache
table_definition_cache = 2048
max_heap_table_size = 246M
sort_buffer_size = 2M
join_buffer_size = 2M
thread_cache_size = 256
 
#thread_concurrency = 8
query_cache_size = 32M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
thread_stack = 192K
read_buffer_size = 1M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
 
#logs
log-error=/usr/local/mysql/logs/mysql.err
log_warnings = 2
slow-query-log
slow-query-log-file=/use/local/mysql/logs/slow-log.log
long_query_time = 2
log-queries-not-using-indexes = 1
log-slow-admin-statements = 1
log-slow-slave-statements = 1
 
#binlog & replication
server-id = 2086 #如果需要做主从的话,此项必须要不同
binlog_format = ROW
binlog-row-image = minimal
binlog_cache_size = 4M
max_binlog_cache_size = 2G
max_binlog_size = 1G
expire_logs_days = 7
relay-log-purge = 1
sync_binlog = 0
skip-slave-start = 1
log-slave-updates  = 1
 
#Myisam engine
key_buffer_size = 32M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
lower_case_table_names = 1
skip-name-resolve
slave-skip-errors = 1032,1062
 
#Innodb engine
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 768M
innodb_data_file_path = ibdata1:1G:autoextend
innodb_file_per_table = 1
innodb_thread_concurrency = 0
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 256M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 75
innodb_lock_wait_timeout = 120
innodb_rollback_on_timeout
innodb_status_file = 1
innodb_io_capacity = 800
transaction_isolation = READ-COMMITTED
innodb_flush_method = O_DIRECT
innodb-support-xa = 0
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_file_format = Barracuda
 
skip-name-resolve
log_slave_updates = 1
#auto_increment_increment=2
#auto_increment_offset=1
 
[mysqldump]
quick
max_allowed_packet = 32M
 
5.3. 初始化MySQL
  * cd /usr/local/mysql
  * scripts/mysql_install_db --defaults-file=/usr/local/mysql/etc/my.cnf --user=mysql
Installing MySQL system tables...2014-11-14 15:58:26 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
OK
 
Filling help tables...2014-11-14 15:58:36 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
OK
 
To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system
 
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
 
  /usr/local/mysql/bin/mysqladmin -u root password 'new-password'
  /usr/local/mysql/bin/mysqladmin -u root -h 192.168.80.20 password 'new-password'
 
Alternatively you can run:
 
  /usr/local/mysql/bin/mysql_secure_installation
 
which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.
 
See the manual for more instructions.
 
You can start the MySQL daemon with:
 
  cd . ; /usr/local/mysql/bin/mysqld_safe &
 
You can test the MySQL daemon with mysql-test-run.pl
 
  cd mysql-test ; perl mysql-test-run.pl
 
Please report any problems at
 https://bugs.launchpad.net/percona-server/+filebug
 
The latest information about Percona Server is available on the web at
  http://www.percona.com/software/percona-server
 
Support Percona by buying support at
 http://www.percona.com/products/mysql-support
 
6. 主从同步
首先要确保两边的server-id不一样 
 
主库 
 mysql> show master status;
 +------------------+----------+--------------+------------------+-------------------+
 | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
 +------------------+----------+--------------+------------------+-------------------+
 | mysql-bin.000004 |      120 |              |                  |                   |
 +------------------+----------+--------------+------------------+-------------------+
 1 row in set (0.00 sec)
 
 mysql> grant replication slave on *.* to 'cpmysql'@'192.168.80.%' identified by 'cpmysql';
 Query OK, 0 rows affected (0.00 sec)
 
 
 
从库 
 mysql> stop slave;
 Query OK, 0 rows affected, 1 warning (0.00 sec)
 
 mysql> change master to master_host='192.168.80.19',master_user='cpmysql',master_password='cpmysql', master_log_file='mysql-bin.000004',master_log_pos=120;
 Query OK, 0 rows affected, 2 warnings (0.02 sec)
 
 mysql> start slave;
 Query OK, 0 rows affected (0.00 sec)
 
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.19
                  Master_User: cpmysql
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 544
               Relay_Log_File: dns02-relay-bin.000002
                Relay_Log_Pos: 707
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 544
              Relay_Log_Space: 880
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1986
                  Master_UUID: 9811abed-6b32-11e4-8336-d6cdc0dea021
             Master_Info_File: /usr/local/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)
 
ERROR: 
No query specified
 
 
7. 安装bind
版本bind-9.8.0-P1 
 
  * tar -zxvf bind-9.8.0-P1.tar.gz
  * cd bind-9.8.0-P1
  * ./configure --with-dlz-mysql=/usr/local/mysql --enable-threads=no --prefix=/usr/local/bind 
  * make && make install
 
 
* 如果出现/usr/bin/ld: cannot find -lmysqlclient的错误,说明没有找到mysql客户端的lib库 * 
 
*做个软连接就可以解决 ln -s /usr/local/mysql/lib/libperconaserverclient.so.18.1.0 /usr/lib64/libmysqlclient.so * 
8. 配置bind
8.1. 初始化
 * cd /usr/local/bind && sbin/rndc-confgen > etc/rndc.conf
 * cd etc && tail -10 rndc.conf | head -9 | sed s/#\ //g > named.conf
 * dig >named.root
 
 创建数据库
 mysql> create database dns_records;
 Query OK, 1 row affected (0.00 sec)
 
 mysql> use dns_records;
 Database changed
 mysql> CREATE TABLE `dns_records` (
 ->         `id` int(10) unsigned NOT NULL auto_increment,
 ->         `zone` varchar(255) NOT NULL,
 ->         `host` varchar(255) NOT NULL default '@',
 ->         `type` enum('MX','CNAME','NS','SOA','A','PTR') NOT NULL,
 ->         `data` varchar(255) default NULL,
 ->         `ttl` int(11) NOT NULL default '600',
 ->         `view` char(20) default 'DF',
 ->         `mx_priority` int(11) default NULL,
 ->         `refresh` int(11) NOT NULL default '3600',
 ->         `retry` int(11) NOT NULL default '3600',
 ->         `expire` int(11) NOT NULL default '86400',
 ->         `minimum` int(11) NOT NULL default '3600',
 ->         `serial` bigint(20) NOT NULL default '2014111300',
 ->         `resp_person` varchar(64) NOT NULL default 'root.yokaapp.com.',
 ->         `primary_ns` varchar(64) NOT NULL default 'ns1.yokaapp.com.',
 ->         `data_count` int(11) NOT NULL default '0',
 ->         PRIMARY KEY (`id`),
 ->         KEY `type` (`type`),
 ->         KEY `host` (`host`),
 ->         KEY `zone` (`zone`)
 -> ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 Query OK, 0 rows affected (0.04 sec)
 
 mysql> grant all privileges on dns_records.* to 'named'@'192.168.80.%' identified by 'named';
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> flush privileges;
 Query OK, 0 rows affected (0.00 sec)
 
 
8.2. 配置
localhost.zone 
 ttl 86400
 @ IN SOA localhost. root.localhost. (
 1997022700 ; Serial
 28800 ; Refresh
 14400 ; Retry
 3600000 ; Expire
 86400 ) ; Minimum
 IN NS localhost.
 1 IN PTR localhost.
 
 
ACL文件(/usr/local/bind/etc) 
 在named.conf加入以下
 include "/usr/local/bind/etc/product_acl.txt"; #生产环境ACL
 include "/usr/local/bind/etc/test_acl.txt";  #测试环境ACL
 include "/usr/local/bind/etc/view.conf";
 
 
 product_acl.txt内如如下:
 acl "PRODUCT" {
 192.168.80.9;
 };
 
 test_acl.txt内如如下:
 acl "TEST" {
 192.168.80.18;
 };
 
 
view文件 
 
#test-view
view "test_view" {
match-clients           { key cnc;dns-ip-list;TEST; };
allow-query-cache       { any; };
allow-recursion         { any; };
allow-transfer          { none; };
recursion               yes;
 
dlz "Mysql zone" {
database "mysql
{host=192.168.80.19 dbname=dns_records ssl=false port=3306 user=named pass=named }
{select zone from dns_records where zone = '$zone$' and view='TEST' 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 as mydata from dns_records where zone = '$zone$' and host = '$record$' and view = 'TEST'}
{}
{select  ttl, type, host, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"') else data end as mydata, resp_person, serial, refresh, retry, expire, minimum from dns_records where zone = '$zone$' and view='TEST'}
{select zone from xfr_table where zone = '$zone$' and client = '$client$' and view='TEST' limit 1}
{update data_count set count = count + 1 where zone ='$zone$' and view='TEST'}";
};
 
zone "." IN {
type hint;
file "named.root";
};
};
 
#product-view
view "product_view" {
match-clients           { key telecom;dns-ip-list;PRODUCT; };
allow-query-cache       { any; };
allow-recursion         { any; };
allow-transfer          { none; };
recursion               yes;
 
dlz "Mysql zone" {
database "mysql
{host=192.168.80.19 dbname=dns_records ssl=false port=3306 user=named pass=named }
{select zone from dns_records where zone = '$zone$' and view = 'PRODUCT' 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 as mydata from dns_records where zone = '$zone$' and host = '$record$' and view = 'PRODUCT'}
{}
{select  ttl, type, host, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"') else data end as mydata, resp_person, serial, refresh, retry, expire, minimum from dns_records where zone = '$zone$' and view = 'PRODUCT'}
{select zone from xfr_table where zone = '$zone$' and client = '$client$' and view='PRODUCT' limit 1}
{update data_count set count = count + 1 where zone ='$zone$' and view = 'PRODUCT'}";
};
 
       zone "." IN {
                type hint;
                file "named.root";
        };
};
 
#any_view
view "any_view" {
match-clients           { key any;dns-ip-list;ANY; };
allow-query-cache       { any; };
allow-recursion         { any; };
allow-transfer          { none; };
recursion               yes;
 
dlz "Mysql zone" {
database "mysql
{host=192.168.80.19 dbname=dns_records ssl=false port=3306 user=named pass=named }
{select zone from dns_records where zone = '$zone$' and view='DF' 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 as mydata from dns_records where zone = '$zone$' and host = '$record$' and  view = 'DF'}
{}
{select  ttl, type, host, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"') else data end as mydata, resp_person, serial, refresh, retry, expire, minimum from dns_records where zone = '$zone$' and view='ANY'}
{select zone from xfr_table where zone = '$zone$' and client = '$client$' and view='DF' limit 1}
{update data_count set count = count + 1 where zone ='$zone$'}";
};
 
      zone "." IN {
                type hint;
                file "named.root";
        };
};
 
 
配置DNSTSIG 
产生加密金钥 
  /usr/local/bind/sbin/dnssec-keygen -a hmac-md5 -b 128 -n HOST test
  /usr/local/bind/sbin/dnssec-keygen -a hmac-md5 -b 128 -n HOST product
  /usr/local/bind/sbin/dnssec-keygen -a hmac-md5 -b 128 -n HOST any
 
 
将产生的密钥写入named.conf中 
 key "test" {
        algorithm hmac-md5;
        secret "HLGLTZECc7gGosbiu3h+0A==";
};
 
key "product" {
        algorithm hmac-md5;
        secret "bFddMVr7Gab9fMCj5z+LZQ==";
};
 
key "any" {
        algorithm hmac-md5;
        secret "6j5gVyzrfrn8+NZCmz9/Hg==";
};
 
 
 
named.conf最终配置 
  options {
        version "1.1.1";
        listen-on port 53 {any;};
        directory "/usr/local/bind/etc/";
        pid-file "/usr/local/bind/var/run/named.pid";
        allow-query { any; };
        Dump-file "/usr/local/bind/var/log/binddump.db";
        Statistics-file "/usr/local/bind/var/log/named_stats";
        zone-statistics yes;
        memstatistics-file "/usr/local/bind/var/log/mem_stats";
        serial-query-rate 100;
        recursion yes;
        forwarders {
           218.4.4.4;
           8.8.8.8;
        };
 
};
 
key "test" {
        algorithm hmac-md5;
        secret "HLGLTZECc7gGosbiu3h+0A==";
};
 
key "product" {
        algorithm hmac-md5;
        secret "bFddMVr7Gab9fMCj5z+LZQ==";
};
 
key "any" {
        algorithm hmac-md5;
        secret "6j5gVyzrfrn8+NZCmz9/Hg==";
};
 
key "rndc-key" {
        algorithm hmac-md5;
        secret "8mKOsOXgpIh6nflaCsQfmA==";
};
 
controls {
        inet 127.0.0.1 port 953
                allow { 127.0.0.1; } keys { "rndc-key"; };
};
 
acl "dns-ip-list"{
        192.168.80.19;
        192.168.80.20;
};
 
logging {
        channel warning {
                file "/usr/local/bind/var/log/dns_warning" versions 10 size 10m;
                severity warning;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        channel general_dns {
                file "/usr/local/bind/var/log/dns_log" versions 10 size 10m;
                severity info;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        category default {
                warning;
        };
        category queries {
                general_dns;
        };
};
 
include "/usr/local/bind/etc/product_acl.txt";
include "/usr/local/bind/etc/test_acl.txt";
include "/usr/local/bind/etc/view.conf";
 
8.3. 启动脚本
#!/bin/sh -e
#chkconfig: 2345 80 90
#description:auto_run
#
# Symlink target for initscripts that have been converted to Upstart.
 
set -e
 
case "$1" in
start)
 if [ -x /usr/local/bind/sbin/named ]; then
 /usr/local/bind/sbin/named -c /usr/local/bind/etc/named.conf -uroot && echo "Bind Server Started"
 fi
;;
stop)
 kill -9  `cat /usr/local/bind/var/run/named.pid` && echo "Bind Server Stopped"
;;
restart)
 echo "Restart Bind Server ......"
 $0 stop && $0 start
;;
reload)
 /usr/local/bind/sbin/rndc reload
;;
status)
 /usr/local/bind/sbin/rndc status
;;
*)
echo "$0 start|stop|restart|reload|status"
esac
 
插入记录
 
INSERT INTO dns_records (zone, host, type, data, ttl, view) VALUES ('abc.com', 'www', 'A', '192.168.2.1', 3600, 'CNC');^M
INSERT INTO dns_records (zone, host, type, data, ttl, view) VALUES ('abc.com', 'mail', 'A', '192.168.2.1', 3600, 'CNC');^M
INSERT INTO dns_records (zone, host, type, data, ttl, view, mx_priority) VALUES ('abc.com', '@', 'MX', 'mail.abc.com.', 3600, 'CNC', '10');^M
INSERT INTO dns_records (zone, host, type, data, ttl, view) VALUES ('abc.com', 'w2', 'CNAME', 'www', 3600, 'CNC');
最后编辑:
作者:saunix
大型互联网公司linux系统运维攻城狮,专门担当消防员

留下一个回复