点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!
1. DNS域名结构介绍
DNS域名又称DNS命名空间,它是以层次树状结构进行管理的,其顶层是根域,根域在整个DNS命名空间是唯一的,而根域下可以分为多个子域,每个子域又可以有多个子域。
一个完整的域名是由顶级域以及各子域的名称所组成,各部分之间用圆点,“.”来分割,其中最后一个点是顶级域,最后一个“.”左边部分称为二级域名,二级域左边称为三级域名,以此类推。
www.sina.com.cn
cn是一级域名,com是二级域名,sina是三级域名。
顶级域名
域名 代表含义
.com 表示商业机构 .cn 中国;
.net 表示网络服务机构 .hk 中国香港 ;
.org 表示非营利性组织 .tw 中国台湾;
.gov 表示政府机构 .us 美国 ;
.edu 表示教育机构 .jp 日本;
.mil 表示军事机构。
2. DNS工作原理
随着计算机网络的快速发展,网络中的计算机数量也是随之快速增长,以前依靠hosts文件来实现主机名和IP地址之间的通信已经无法满足现状,DNS的出现提供了一个完整的解决方案。
DNS服务采用C/S方式,域名和IP地址的维护工作全部在DNS服务端进行,用户无需再在本地手动维护hosts文件。
下面是通过DNS解析域名的工作过程:
案例:访问www.QQ.com的dns解析过程
客户端需要解析www.qq.com,客户端向本地DNS服务器发送解析请求。
本地DNS发现无法解析,转发给根域服务器。
根域服务器根据请求域名对应的顶级的com,返回com的服务器地址。
本地DNS服务器向com域dns服务器发出解析请求。
com域服务器返回qq.com域服务器的地址。
以此类推,本地DNS服务器向qq.com域dns服务器发出解析请求,直到在qq.com域dns服务器上面找到www.qq.com所对应的IP地址。
qq.com把查找到的域名对应IP地址信息返回给本地DNS服务器。
最终再由本地DNS服务器把结果返回给客户端计算机。
3. 工作模式和端口
TCP/53,UDP/53 用户客户端查询,递归查询;
TCP/953,UDP/953 DNS主从同步工作模式:C/S模式。
SOA:起始授权记录,Start of Authority Record 每个区的开始处都包含,SOA定义了域的全局参数,进行整个域的管理,一个区有且仅有一个SOA记录;
NS:Name Server 域名服务记录 指定该域名由那个DNS服务器来解析,每个区在区根处至少包含一条NS记录;
A:address记录,吧FQDN映射到IP地址,因为有此记录,所以DNS服务器能够解析FQDN域名对应的IP地址;
PTR:反A记录,指针PRT记录把IP映射到FQDN,用于反向查询,通过IP地址,找到域名;
CNAME:别名记录,记录创建特定FQDN的别名,用户可以使用CNAME记录来隐藏网络用户的实现细节6、MX:邮件交换记录,为DNS指定邮件交换服务器。
4. DNS转发
当本地DNS服务器(也是转发器)收到查询时,它会尝试使用它主持和缓存的主要和辅助区域解析该查询;
如果不能使用本地数据解析查询,此时它作为客户端,会将查询转发给外网DNS服务器;
本地DNS(转发器)收到客户端的请求后会等待一段很短的时间,等待来自外网DNS的应答;
对于外网DNS来说,它接收到的查询请求是递归查询,此时,它自己需要向外层层迭代找到最终答案返回给转发器(此时转发器作为DNS客户端)
转发器将外网DNS返回的查询结果送到客户端(非权威答案),完成解析过程。
注:转发的前提——接收转发请求的服务器(这里是外网DNS)必须能够为请求者(这里是本地DNS,也是转发器)做递归查询。
无条件转发:转发所有针对非本机负责解析的区域的请求
在主配置文件/etc/named.conf的全局选项中添加如下内容:
options { forwarders { ip; }; #指明转发器是谁 forward only|first; #only表示仅转发 ;first表示先进行转发,如果没查询到结果,那么它自己还会根据根提示向外迭代查询 };
条件转发:仅转发对特定区域的请求(即转发域)
在区域置文件/etc/named.rfc1912.zone中定义转发域:
zone "区域名称" IN { type forward; #区域的类型为转发 forwarders { ip; }; #指明转发器是谁 forward only|first; #only表示仅转发 ;first表示先进行转发,如果没查询到结果,那么它自己还会根据根提示向外迭代查询}。

1. 编译安装mysql
#安装依赖包:
yum -y install make gcc-c++ cmake bison-devel ncurses-devel
#下载mysql:
wget http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.35.tar.gz
tar xvf mysql-5.6.35.tar.gz
cd mysql-5.6.35
#编译安装:
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DSYSCONFDIR=/etc \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DMYSQL_UNIX_ADDR=/var/lib/mysql/mysql.sock \
-DMYSQL_TCP_PORT=3306 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci
#安装:
make && make install
#配置mysql。
#设置权限:
groupadd mysql
groupadd -g mysql mysql
chown -R mysql:mysql /usr/local/mysql
#初始化配置:
ln -s /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib64/libmysqlclient.so.18
cd /usr/local/mysql
scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --user=mysql
注意: 将/etc/my.cnf 改成其他名字,以防冲突。
#启动Mysql:
cp support-files/mysql.server /etc/init.d/mysql
chkconfig mysql on
service mysql start --启动MySQL
#配置system管理:
PATH=/usr/local/mysql/bin:$PATH
export PATH
source /etc/profile
mysql -uroot
mysql> set password = password('123456')
#设置远程访问:
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
#mysql 配置完成。
2. 编译安装bind
1)编译安装
#解压文件:
tar xf bind-9.11.0.tar.gz
cd bind-9.11.0
#bind 编译安装(bind-9.11.0.tar.gz):
./configure --prefix=/usr/local/bind/ --with-dlz-mysql=/usr/local/mysql --enable-threads=no --enable-largefile --disable-ipv6 --with-openssl=no
--enable-threads 多线程支持(官网解析是需要关闭); --enable-largefile 启用大文件支持; --disable-ipv6 关闭ipv6支持; --with-dlz-mysql意思是使用mysql存储域名解析,同时如果需要为安装python也可关闭python。
make && make install
2)生成bind配置文件
cd /usr/local/bind/etc/
/usr/local/bind/sbin/rndc-confgen > rndc.conf
cat rndc.conf >rndc.key
tail -10 rndc.conf | head -9 | sed s/#\ //g > named.conf
3)配置named.conf (master)文件
#验证安装:
key "rndc-key" {
algorithm hmac-md5;
secret "+m1KYq8j8laFDbRrNiD1aA==";
};
#DNS主从同步端口:
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { "rndc-key"; };
};
#全局配置:
options {
listen-on port 53 {any;}; #ipv4监听端口和ip地址
directory "/usr/local/bind/var";
pid-file "named.pid";
allow-query{any;}; #查询范围
allow-transfer { 10.0.0.51; }; #查询转发至从节点
also-notify { 10.0.0.51; };
forwarders{114.114.114.114;8.8.8.8;}; #转发至公网DNS(测试用)
};
#日志文件配置:
logging {
channel error_log {
file "/usr/local/bind/var/logs/error.log" versions 10 size 32m;
severity warning;
print-time yes;
print-severity yes;
print-category yes;
};
channel query_log {
file "/usr/local/bind/var/logs/query.log" versions 10 size 32m;
severity debug;
print-time yes;
print-severity yes;
print-category yes;
};
category default { error_log; };
category queries { query_log; };
};
#mysql数据库zone查询:
dlz "Mysql zone" {
database "mysql
{dbname=db_ops port=3306 host=127.0.0.1 user=root pass=123456 ssl=false}
{select zone from t_dns_records where zone = '$zone$' and status = 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 t_dns_records where zone = '$zone$' and host = '$record$' and status = 1}
{select ttl, type, host, mx_priority, case when lower(type)='txt' then
concat('\"', data, '\"') else data end, resp_person, serial, refresh, retry, expire,
minimum from t_dns_records where zone = '$zone$' and status = 1}
{select zone from t_dns_xfr_table where zone = '$zone$' and client = '$client$' and status = 1}";
};
4)named.conf(slave) 配置文件
key "rndc-key" {
algorithm hmac-md5;
secret "oNQJdm0CeHn8VYMu+40Jmw==";
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { "rndc-key"; };
};
options {
listen-on port 53 {any;};
directory "/usr/local/bind/var";
pid-file "named.pid";
allow-query{any;};
allow-transfer { 10.0.0.51; };
also-notify { 10.0.0.51; };
forwarders{114.114.114.114;8.8.8.8;};
};
logging {
channel error_log {
file "/usr/local/bind/var/logs/error.log" versions 10 size 32m;
severity warning;
print-time yes;
print-severity yes;
print-category yes;
};
channel query_log {
file "/usr/local/bind/var/logs/query.log" versions 10 size 32m;
severity debug;
print-time yes;
print-severity yes;
print-category yes;
};
category default { error_log; };
category queries { query_log; };
};
#zone信息同步:
zone "wsq.com" IN { #wsq.com的zone信息
type slave; #类型为从 同步
file "wsq.com.zone"; #存放文件
masterfile-format text; #同步过来的文本类型
masters{ 10.0.0.50; }; #从主节点同步
};
5)mysql 配置
#创建zone信息表格:
create table `t_dns_records` (
`id` bigint(20) not null auto_increment comment '主健',
`zone` varchar(255) not null default '' comment '域名',
`host` varchar(255) not null default '' comment '记录名称',
`type` varchar(255) not null default '' comment '记录类型',
`data` varchar(255) not null default '' comment '记录值',
`ttl` int(11) default null comment 'ttl(存活时间)',
`mx_priority` int(11) default null comment 'mx优先级',
`refresh` int(11) default null comment '刷新时间间隔',
`retry` int(11) default null comment '重试时间间隔',
`expire` int(11) default null comment '过期时间',
`minimum` int(11) default null comment '最小时间',
`serial` bigint(20) default null comment '序列号,每次更改配置都会在原来的基础上加1',
`resp_person` varchar(64) default null comment '责任人',
`primary_ns` varchar(64) default null comment '主域名',
`status` tinyint(4) default 1 comment '0:该记录无效, 1:该记录有效',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
primary key (`id`),
key `ix_zone` (`zone`),
key `ix_host` (`host`),
key `ix_dat` (`data`),
key `ix_type` (`type`),
key `ix_status` (`status`),
key `ix_created_at` (`created_at`),
key `ix_updated_at` (`updated_at`)
) engine=InnoDB default charset=utf8 comment='内网DNS记录';
#创建工作服务器表:
create table `t_dns_xfr_table` (
`id` bigint(20) not null auto_increment comment '主健',
`zone` varchar(255) not null default '' comment '域名',
`client` varchar(255) not null default '' comment 'BIND SLAVE 客户端',
`status` tinyint(4) default 1 comment '0:该记录无效, 1:该记录有效',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
primary key (`id`),
key `ix_created_at` (`created_at`),
key `ix_updated_at` (`updated_at`)
) engine=InnoDB default charset=utf8 comment='DNS传送信息';
#插入数据。
#插入正向解析数据:
INSERT INTO t_dns_records (zone, host, type, data, ttl) VALUES ('wsq.com', 'www', 'A', '10.0.0.50', '60');
INSERT INTO t_dns_records (zone, host, type, data, ttl) VALUES ('wsq.com', 'web', 'A', '10.0.0.51', '60');
INSERT INTO t_dns_records (zone, host, type, data, ttl) VALUES ('wsq.com', '@', 'NS', 'www.wsq.com.', '60');
INSERT INTO t_dns_records (zone, host, type, ttl, data,refresh, retry, expire, minimum, serial, resp_person) VALUES ('wsq.com', '@', 'SOA', '60', 'www.wsq.com.', '28800', '14400', '86400', '86400', '2012020809', 'admin');
#插入反向解析数据:
insert into t_dns_records
(zone,host,type,data,ttl,mx_priority,refresh,retry,expire,mi
nimum,serial,resp_person,primary_ns) values ('1.168.192in-
addr.arpa','@','SOA','node02.example.com',86400,NULL,3600,15
,86400,3600,2008082700,'node02.example.com','node02.example.
com'); #添加SOA(授权区域定义)记录
insert into t_dns_records
(zone,host,type,data)values('1.168.192.in-
addr.arpa','@','NS','node02.example.com.'); #添加NS(标记区域的
域名服务器以及授权子域)记录
insert into
t_dns_records(zone,host,type,data)values('1.168.192.in-
addr.arpa','250','PTR','node02.example.com.'),
('1.168.192.in-addr.arpa','111','PTR','x.example.com.'); #添
加PTR(与A记录相反,将ip转换成主机名,反向解析操作)记录
#插入用户数据:
insert into t_dns_xfr_table (zone, client) values("wsq.com", "10.0.0.50")
insert into t_dns_xfr_table (zone, client) values("wsq.com", "10.0.0.51")
6)debug 模式下运行 bind 服务
/usr/local/bind/sbin/named -g -d 1
#-g -d 1 是debug的参数 可以查看到后台的日志信息。
7)测试结果
首先查看从节点是否同步zone成功:

修改内网中某机器的配置文件/etc/resolv.conf (hosts文件自行修改)。

对zone之中所配置URL进行nslookup命令:

FAQ:
检查 t_dns_xfr_table 是否配置相应的zone 及 client, client是slave的ip, 只有配置,slave才能被授权同步;
检查 SOA 序列号(serial),每次更改配置都会在原来的基础上加1, 保证master比slave大;
检查 refresh 字段, 一般设置300s, 5分钟同步一次。
在数据库更新记录后, 在slave节点上执行 rndc refresh xxx.com(你需要同步的zone)。

本文作者:汪训琪(上海新炬中北团队)
本文来源:“IT那活儿”公众号





