域名系统DNS(Domain Name System)实现的是将ip和主机名的互相转换,dns是一个应用层协议,使用C/S架构,使用的udp和tcp的53端口。BIND(Bekerley Internet Name Domain)是dns的实现,由ISC维护。
互联网初期使用mac地址来通信,随着tcp/ip的成熟,改使用ip地址进行通信,当加入的主机越来越多时,ip地址很难记忆,所以引入了主机名称,主机通信就可以通过名称来实现。
实际上计算机通信仍然使用的ip和mac进行通信,只是使用了dns将主机名和ip进行了解析
本地名称解析配置文件保存了主机名和对应ip地址的关系,在Linux中,这个在文件在/etc/hosts。
随着大量主机接入互联网后,在本地维护这样的数据库,已经是很困难了,于是IANA建立了一台ftp服务器,任何主机需要使用地址和名称解析时,向它请求,访问成功后,写入一个公共的host文件中,IANA也会将向他申请的主机名和对应ip写入host文件中,然后需要的主机将文件拷贝到自己的主机。
当本地hosts条目过多时,查询的效率就非常低了。于是就本地不在维护host,而改用iana提供的服务器,让服务器直接进行解析,然后返回目标的ip的地址。在服务器上将host文件哈希化保存在内存中,这样查询速度也加快了。
当主机增加到百万级别时,一台服务器就无法应对,于是这台服务器对外提供服务,监听在某个套接字,当用户需要名称解析请求时,服务器根据数据库解析到结果后,将结果发回请求主机。另外dns进行了分层,将一个大数据库分成了若干个小数据库,dns也就形成了一个倒置的树形结构,dns的根使用.表示,整个树形结构叫做dns的namespace。这些树形结构层层向下,叫做子域划分。
直接位于根域之下有7个著名顶级域名(top-level domain),也叫一级域名(tld),这7个顶级域名是:com, edu, mil, gov, net, org, int。
早期顶级域名分为三类,有组织域、国家域、反向域。
dns的表示是自底向上的,以点号分隔的,如www.cisco.com.。
dns的查询类型有递归查询和迭代查询,递归查询只需要发出一次请求,就会得到最终结果,这样根域服务器会非常繁忙,而迭代查询,要发出多次请求,才会得到结果,根只回答迭代查询。实际上一台主机并非直接和dns根域通信,而是和指定dns服务器通信,由dns服务器来向根查询并返回结果,客户端到dns服务器使用的是递归查询,dns服务器使用的迭代查询。客户端执行的dns服务器一定是允许给本地主机做递归查询的。
FQDN是full qualified domain name的缩写,将FQDN转换为ip地址叫做正向解析,将ip解析为FQDN,叫反向解析。
早期的dns只能实现将FQDN解析为ip,后来也可以进行反向解析,但是正反向解析使用的技术不同,不能存放于同一个数据库文件中,正反向解析时两个不同的名称空间,是两颗不同的解析树。
在一个域中,为了完成正反向解析需要两个数据库文件,这两个数据库文件标识了不同的物理空间,这个物理空间叫区域,在dns中,域(domain)是逻辑概念,区域(zone)是物理概念区域自身有名字。
域名注册需要找当地的注册代理商,也可以找国外的代理商如过godaddy,注册代理商会给注册的域名提供dns服务器,也可以自建dns服务器,但是需要向上级域请求授权。除了有提供注册的代理商,还有一些提供商不提供注册,只提供dns服务器。
在dns解析库文件中,使用资源记录(Resource Record)来存储各个条目,资源记录也简写成RR。资源记录有不同的类型,用于标记主机在域内的角色
dns解析库文件是一个文本文件,并且只能包含资源记录和宏定义,SOA必须是区域数据库的第一条记录。
资源记录类型有:
-
SOA:Start of Authority,起始授权记录
-
NS:Name Server,标明当前区域的域名服务器
-
MX:Mail eXchanger,邮件交换器
-
A:internet address,用于实现将FQDN解析为ip地址
-
PTR:pointer,将ip反向解析为FQDN
-
AAAA:将FQDN解析为ipv6地址
-
CNAME:Canonical Name,别名记录
资源机记录的格式:
NAME [ttl客户端缓存时间] IN RRType VALUE
ttl可从全局继承,@表示当前区域的名字,同一个名字可以通过多条记录定义多个不同的值,此时dns服务器会以轮询方式相应,同一值也可能有多个不同的名字,通过多个不同的名字指向同一个值实现,仅表示通过多个不同的名字来找到主机。
例如:www 600 IN A 1.1.1.1
www.jsp.com. 600 IN A 1.1.1.1
SOA类型:只能有一条
name:区域名称,如jsp.com.,通常可以简写为@
value:第一部分是当前区域的主dns服务器的FQDN,也可以使用当前区域的名字。第二部分是当前区域的管理员的邮箱地址,但地址中的@不能使用@,而要改成.。第三部分是(主从服务器协调属性的定义以及否定答案的统一TTL值)
如:@ 600 IN SOA ns.jsp.com. 管理员的邮箱地址admin.jsp.com. (
serial number;序列号,不能超过10位,通常使用日期时间版本,如2017052001
refresh time;刷新时间,每隔多久到主服务器检查一次
retry time;重试时间,小于refresh time
expire time;过期时间
nagative answer ttl;否定答案的ttl
)
NS类型:一个区域可以有多条NS记录
name:当前区域的名字
value:当前区域的dns服务器的FQDN。可以使用相对名称
一个区域可以有多条NS记录,相邻的两个资源记录的name相同时,后续的可省略;
对于NS记录而言,任何一个ns记录后面的value(服务器名字FQDN),都应该在后续至少有一个A记录
如@ 600 IN NS ns
A类型:只能定义在正向区域数据库文件中
name:FQDN,某主机的完整名字
value:主机名对应的ip地址
如 www.cisco.com. IN A 1.1.1.1
为了避免写错名称时,发送错误答案,可以通过泛用解析进行解析至某特定地址,如*.cisco.com. IN A 1.1.1.2
多个IP地址使用相同的FQDN,是一种最简单的负载均衡,一个主机可以有多个名字,也可以使用别名机制。
AAAA类型:
name:FQDN,某主机的完整名字
value:主机名对应的ipv6地址
MX类型:可以有多个,需要标注优先级
name:当前区域的名称,用于标识smtp服务器
value:当前区域的某邮件服务器(smtp服务器)的主机名。
一个区域内,mx记录可以有多个,但每个记录的value之前应该有一个数字0-99,表示此服务器的优先级,数字越小,优先级越高。
如 cisco.com. IN MX 10 mail1.cisco.com.
cisco.com. IN MX 20 mail2.cisco.com.
因为发送邮件标识的是一个域名,所以在要有一个邮件交换器转为一个主机。
对于MX记录而言,任何一个MX记录后面的value(服务器名称),都应该在后续至少有一个A记录。
CNAME类型:
name:FQDN
value:FQDN
如:ftp IN CAME WWW 表示ftp是www的别名
PTR:只能定义在反向区域数据库文件中,反向区域名称为逆向网络地址加.in-addr.arpa.后缀
name:逆向的主机ip地址,如主机地址是172.16.100.7的name是7.100,完全格式是7.100.16.172.in-addr.arpa.
value:FQDN
如 4.3.2.1-in-addr.arpa. 600 IN PTR www.cisco.com.
DNS服务器有四种不同的类型:主DNS服务器、辅助DNS服务器、缓存DNS服务器和转发器
主dns服务器是维护解析域内解析库的服务器,解析库由管理员维护。辅助dns服务器从主dns服务器或其他的辅助dns服务器请求传送"复制"一份解析库的过程叫区域传递,区域传递有全量传送(AXFR)和增量传送(IXFR)两种方式。辅助服务器每隔一段时间向主服务器请求更新,这个时间叫刷新时间,如果主服务器没有应答,会再次以更短的时间间隔向主服务器请求,这个时间叫做重试时间,当多次无法和主服务器请求更新后,在一定时间后,辅助服务器放弃从dns服务器功能,这个时间叫做过期时长。时间间隔的设定在SOA中
主从服务器是同时工作的,在主从同步时,早期使用序列号来保证主从dns服务器的内容保持一致,序列号是解析库的版本号,发生同步的前提时主服务器解析库内容发生变化。
在同步中还有通知机制,可以快速进行同步,避免了从服务器始终落后于主服务器。
一次完整的查询请求过程:
client首先查找hosts文件,没有结果的话,到下一步,dns server。在dns server中,首先查找local cache,仍然没有的话,使用系统配置的第一dns server,第一dns server查找自己的server cache,没有的话,第一dns server做迭代查询,解析结果有两种,一种是肯定答案,还有就是否定答案。请求的条目不存在等原因导致无法返回结果,这种结果就是否定答案。否定答案也有缓存,不过有时间限制。
权威答案和非权威答案,只有域dns服务器返回的结果是权威答案。
dns的实现有bind、PowerDNS、dnsmasq等,bind由isc维护,目前大部分使用的是bind9
bind的程序包名叫做bind,提供dns服务,程序名叫named。需要安装的包主要有:bind、bind-libs、bind-utlis。
在centos6中,bind的服务脚本在/etc/rc.d/init.d/named,主配置文件在/etc/named.conf和/etc/named.rfc1912.zones,以及辅助性配置文件/etc/rndc.key。运行的named程序用户和组都是named
DNS域名解析的配置文件在 /etc/resolv.conf,由networkmanager生成,定义了dns服务器的ip地址、本地域名、和域名的搜索列表。
其中rndc代表reomte name domain controller,是一个远程管理工具,默认与bind安装在同一主机,其只能通过127.0.0.1来连接named进程,提供辅助性的管理功能,工作在tcp 953端口。
解析库文件在/var/named/ZONE_NAME.ZONE,一台物理服务器,可同时为多个区域提供解析,另外必须要有根区域文件named.ca,一般来讲应该有多个实现localhost和本地回环地址的解析库。
任何服务程序如果希望能够通过网络被其他主机访问,至少应该监听在一个能与外部主机通信的ip地址上。
缓存名称服务器的配置,监听外部地址即可,建议测试时关闭dnssec。
(一)配置主DNS服务器
配置dns服务要定义主配置文件(/etc/named.conf)用来定义区域和区域数据文件/var/named
主配置文件至少要定义三个区域:
- 根域(提供的文件在/var/named/named.ca)
- localhost(提供的文件在/var/named/named.localhost)
- 127.0.0.1(提供的文件在/var/named/named.loopback)
在主配置文件中,使用include包含了/etc/named.rfc1912.zones
和/etc/named.root.key
两个文件,其中/etc/named.rfc1912.zones,就定义了这些区域。
区域定义是指本机能够为哪些zone进行解析,就要定义哪些zone
主配置文件的字段:
- option{}:全局选项
- zone “ZONE NAME” IN {}:定义区域
- logging{}:定义日志系统
zone的区域类型:
- hint:根
- master:主
- slave:辅助
- forward:转发
手动写一个主配置文件
options {
directory "/var/named";
};
zone "." IN {
type hint;
file "named.ca";
};
zone "localhost." IN {
type master;
file "named.localhost";
};
zone "1.0.0.127.in-addr.arpa." IN {
type master;
file "named.loopback";
};
zone "jsp.com." IN {
type master;
file "jsp.com.zone";
};
修改文件的属主和属组:chown root:named /etc/named.config
修改文件的执行权限:chmod 640 /etc/named.config
检查语法错误:service named configtest
,也可以使用named-checkconf手动检测主配置文件
在/var/named目录中,创建自定义区域的文件
$TTL 43200
@ IN SOA dns.jsp.com. admin.jsp.com (
2017052010
2H
10M
7D
1D)
@ IN NS dns
@ IN MX 10 mail
mail IN A 192.168.1.100
dns IN A 192.168.1.101
www IN A 192.168.1.102
pop IN CNAME mail
ftp IN CNAME www
~
同样需要修改文件的属主和属组以及文件的权限,检查语法使用service named configtest
,手动检查文件使用named-checkzone “区域名称” 区域名称文件。如named-checkzone "jsp.com" /var/named/jsp.com.zone
重启服务后service named restart
,也可以使用service named reload
重读配置文件,相当于killall -1 named
检查dns是否生效dig -t A www.jps.com @192.168.1.101
[root@localhost named]# dig -t A www.jsp.com @192.168.1.101
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.2 <<>> -t A www.jsp.com @192.168.1.101
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16098
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;www.jsp.com. IN A
;; ANSWER SECTION:
www.jsp.com. 43200 IN A 192.168.1.102
;; AUTHORITY SECTION:
jsp.com. 43200 IN NS dns.jsp.com.
;; ADDITIONAL SECTION:
dns.jsp.com. 43200 IN A 192.168.1.101
;; Query time: 12 msec
;; SERVER: 192.168.1.101#53(192.168.1.101)
;; WHEN: Wed May 17 05:02:38 2017
;; MSG SIZE rcvd: 79
dig用于测试dns系统,因此不会查询hosts文件进行解析,dig [-t TYPE] name [@SERVER] [query options]
查询选项:
+[no] trace:跟踪解析过程
+[no] recurse:进行递归解析
也可以使用host命令进行测试:也是由bind-utility提供,host [-t TYPE(资源记录类型)] name [SERVER(通过指定服务器查询)]
nslookup更多情况下使用交互模式的命令
- server DNS_SERVER_IP:指明使用哪个dns server进行查询,等同dig的@server
- set q=RR_TYPE:指明查询的资源记录类型
- NAME要查询的名称
(二)配置缓存dns服务器
当使用rpm包安装了bind时,默认配置只监听在127.0.0.1的53端口,就表示只监听本机的请求和响应,其他来自外部的主机则不监听也不会响应,所以想要给其他主机提供解析服务就必须要监听在能与其他主机通信的地址上,需要将默认的配置文件中的监听的端口和ip地址修改为可以与其他主机通信的地址和端口,并且把allow-query字段改为any,表示允许任何主机进行查询,也可以设定固定的白名单,注释掉后也表示默认为any,把option其他字段注释掉,这样就可以作为一个缓存名称服务器了。
当一个主机向缓存服务器发出递归查询时,缓存dns服务器进行迭代查询,返回一个权威答案,当再次有主机请求相同的查询时,直接返回缓存在本地的结果,这个结果叫参考答案。
在配置文件中创建一个反向区域
zone "1.168.192.in-addr.arpa." IN {
type master;
file "192.168.1.zone";
};
创建区域文件
$TTL 43200
@ IN SOA dns.jsp.com. admin.jsp.com (
2017052010
2H
10M
7D
1D)
@ IN NS dns.jsp.com.
101 IN PTR dns.jsp.com.
102 IN PTR www.jsp.com.
100 IN PTR mail.jsp.com.
用dig模拟完全区域传送:dig -t axfr 区域名称 @server,主服务器的bind版本可以低于辅助服务器的bind版本
向区域中添加从服务器,前提是从服务器也要在上级获得授权,关键的一步是要在区域数据文件中为辅助服务器添加一条NS记录和对应的A或PTR记录。
辅助服务器区域:
zone “jsp.com” IN {
type slave;
masters {主服务器的ip地址;};
file “slave/jsp.com.zone”; #named进程的属主是named,而/var目录的属主是root,但在/var/slaves目录,属主是named,这样就可以保存和编辑文件
allow-transfer{ none; }; #区域传送安全控制,允许可以传送的客户端,主服务器配置辅助服务器的ip地址,辅助服务器如果不打算作为其他服务器的主服务器,应该设定拒绝向其他服务器传送,使用none。
};
rndc(remote name domain controller)是远程管理bind的工具,rndc使用一对密钥,一半密钥放在rndc中,通常保存在rndc的配置文件中,一半保存在服务端bind的主配置文件中。
rndc的配置文件在/etc/rndc.conf,在rhel系,还要读取一个密钥文件/etc/rndc.key。
rndc reload:
rndc reload zone:
rndc retransfer zone:
rndc reconfig:重读配置文件,并加载新增的区域
rndc querylog:关闭或开启查询日志
rndc stop:停止进程
rndc flush:清空服务器端缓存
rndc flushname name:只清空指定名称相关的缓存
rndc trace:打开debug,调试模式,debug有级别的概念,每执行一次提升一个等级
rndc trace LEVEL:指定debug的级别
如果rndc无法正常工作,可尝试使用rndc-confgen生成/etc/rndc.conf配置文件,并将配置文件中的后半部分复制到BIND的主配置文件中按指示启用即可
一个域的名称服务器除了直接管理一部分主机,还可以将某些主机的管理授权给子域,子域也有名称服务器,这就是子域授权。
在父域的配置文件中要添加授权的子区域名称以及子区域的名称服务器、子区域的名称服务器的ip地址。
在区域文件中,资源记录是NS,并且name既不是缺省也不是@或者当前的域名,那么这就是一个子域,value是子域dns服务器的FQDN。同样的也需要一条对应的A记录。
在父域中,虽然有子域的ns记录,但不以父域的响应为最终结果,这条记录完成的是授权功能,最终响应的是子域的dns服务器,这一条记录仅仅是完成父域和子域的连接,这样的条目叫做胶水记录(glue record)。
在父域里的主机可以请求到子域的ip地址,父域的dns服务器会转发给子域的dns服务器,因为在资源记录中有子域的资源记录
在子域里请求一个父域中直接管理的主机ip地址,此时子域会向根域进行查询,这样明显是不合理的,所以可以配置一个转发服务器,交给父域解析。
解析某主机不负责的区域内的名称时,不转发给根,而是转给指定的主机,这就叫做区域转发,也叫转发域
允许使用转发的前提:本机要在对方允许递归的主机列表中
转发某特定区域:
zone "zone_name" IN {
type forward;
forwarders { DNS_SERVER; };
forward only(仅转发,无响应就结束) | first(先转发后找根)
}
转发非本机负责解析的所有区域:
options{
forward only|frist
forwarders { 目标ip; }
}
allow-transfer {}:定义允许发送区域传送的主机,通常都需要启用
alow-query{}:定义允许查询的主机,通常仅用于服务器是缓存名称服务器时,只开放查询功能给本地客户端
allow-recursion{可以使用网段};允许递归的白名单
allow-update{ none; }:允许动态更新数据文件的主机白名单
这些既可以在options也可以在zone中使用
BIND支持使用访问控制列表ACL,访问控制列表只有定义后才能使用,通常acl要定义在named.conf的最上方。
acl ACL_NAME{
172.16.0.0/16
192.168.0.0/24
127.0.0.0/8
};
BIND有四个内置的acl
- any:任何主机
- none:无一主机
- local:本机
- localnet:本机所在的网络
一个BIND可定义多个view,每个view可以定义一个或多个zone,在多个view可以定义相同的zone,每一个view用来匹配一组客户端,多个view可能需要对同一个区域进行解析,但使用不同的区域解析库文件,使同一个域名解析为不同的地址。
view的格式:
view VIEW_NAME {
match-clients { };
... ...
}
启用view后,所有的zone只能定义在view中,仅有必要在匹配到允许递归请求的客户端所在view中定义根区域,客户端请求到达时,是自上而下检查每一个view所服务的客户端列表。