首页 > 代码库 > DNS的视图功能以及日志系统
DNS的视图功能以及日志系统
实验环境:RHEL5.8 32Bit
DNS的视图功能以及日志系统详解
DNS的主配置文件中的allow-recursion参数用来定义能够和DNS服务器进行递归的客户端来源,allow-query参数用来定义允许到DNS服务器上面发起查询请求的客户端,allow-transfer参数用来定义允许和DNS服务器进行区域传送的客户端,区域传送主要有两种方式,axfr和ixfr,使用dig命令也可以模拟实现区域传送:
如果我们的DNS服务器允许进行递归、发起查询请求以及进行区域传送的客户端比较多的话,而且这些客户端如果都不在同一个网段的话,那么我们管理起来会变得非常麻烦,于是我们可以在DNS的主配置文件中使用类似的脚本中变量和函数的方法来对所有这些客户端进行集中管理,只不过在DNS的主配置文件中,这种机制叫做acl。
·acl(访问控制列表)
acl专门用于定义将所有我们DNS允许递归、查询以及区域传送的客户端的ip地址进行统一管理,定义方法如下:
acl ACL_NAME {
将所有客户端的ip地址全部定义在花括号的内部
192.168.0.0/24;
127.0.0.1/8;
};
而后我们如果要将这些客户端作为我们的某些参数的值的话,直接调用acl的名称即可,例如:
接下来我们在定义参数的值的时候就可以直接调用acl的名称:
之后如果我们需要修改允许的客户端ip地址的话,直接在定义的acl中实现统一修改即可,这样管理起来就会非常的方便,DNS的主配置文件里面有两个内置的列表,分别如下:
1,none -> 表示进制所有客户端主机
2,any -> 表示允许所有客户端主机
acl列表必须先定义后使用,因此一般而言对于主配置文件来讲,acl是被定义在文件的最上面的,甚至是全局选项之上,之后所有的参数值都可以通过直接调用acl的名称来进行添加,acl的名称如果有空格的话,得使用双引号将acl的名称引起来:
我们最后修改完主配置文件之后,不要忘记检查配置文件语法和重启DNS服务,接着查看日志看看是否有错误信息:
在互联网上,往往会有很多这样的应用场景,当然这种应用场景也是中国的现状所决定的,中国有两大网络运营商,将中国的网络分成了两个网络,目前来讲我国的网络运营商主要是电信(telecom)和联通(unicom),电信和联通接入互联网的接口是两个不同的接口,从而将电信和联通分为了两个各自独立的网络,它们二者彼此之间的网络没有结合起来,但是会在某一个机房里有一个总接口,将这两个网络连接起来,并且总带宽可能只有大约100G,这就造成了电信网络和联通网络之间的数据传输变得非常的慢,这还会引起一个问题,比如说我们在联通网里建立了一个网站,那么来自于电信网的用户访问起来速度就会很慢,但是来自联通网的用户的访问速度有可能会很快,即网内速度快,网间速度慢,这就是为什么有的时候我们在下载一个东西的时候,提供下载服务的网站会让我们选择下载线路,有电信下载线路、联通下载线路等等,是为了让我们根据我们所处的网络来选择下载线路从而提高下载的速度,有人曾经做过统计,用户打开一个网站等待网站响应的最大耐心是3秒钟,超过5秒的话,网站的用户流失率会达到百分之六十,那么可想而知我们在联通网中建立的网站,来自电信网的用户要访问我们的站点的时候,总是需要挤那100G的带宽时的用户体验会有多么糟糕,但是我们国内的某些大型网站如淘宝、百度等等,这些网站我们不论在什么地方访问的时候速度都不是很慢,这是因为这些公司很有可能在联通网和电信网中都部署有自己的网站,并且两个网络内的网站的页面内容都是一样的,但是这样又会引起一个新的问题,如果将来我们根据公司业务的需要更新了联通网络内的网站的内容,那么电信网络中的网站内容也必须得到更新,一般都是通过部署在两个网络内的服务器进行同步更新的,但是同步更新的话又会涉及到网间的数据传输,这个传输的速度又会非常的慢,其实现在的公司服务器的机房大部分都是双线接入的,电信和联通网络各接一根,所以我们可以在一个双线接入的机房里面部署我们的服务器,给服务器器配置两个ip地址,一个电信网络的ip地址,一个联通网络的ip地址,或者是配置一个ip地址,只要我们的机房和服务器能够实现双线接入并且使用一个ip地址就能够接入两个不同的网络即可,这是一种解决上述问题的方案,但是有时候还会有一种极端的情况,比如说像淘宝这样的站点,一旦搞一个活动,在全国范围内就会有大量的用户蜂拥而至,那么仅仅依靠淘宝网内部的服务器肯定是顶不住这样的压力,因此为了解决这样的问题,淘宝一般会将全国分为几个区域而且先不考虑这些用户是来自哪个网络的,因为我们的机房通通都是双线接入的机房,所以不同考虑用户来自于哪个网络,并且在每一个区域都部署一组服务器,某一个区域的交易就可以在该区域的服务器上面完成,将来如果期望统计全国一共有多少笔交易的话,可以在最后进行汇总,只不过发生的交易只需要在距离用户最近的服务器上面完成即可,而且每个用户都可以直接访问距离它最近的那台服务器,我们可以根据用户的客户端的地址来判断用户来自于哪个网络,之后再给用户返回距离他最近的服务器的地址,这种能够根据用户的ip地址来判断用户的来源并且给用户返回一个我们实现定义好的ip地址的机制我们把它称为智能DNS。
·智能DNS
智能DNS其实就是在DNS的服务器内部作视图。
·视图
假设我们的DNS服务器负责解析一个域名lkxedu.com.,我们可以将所有的客户端来源分为两类,一类来自于电信网,一类来自于联通网,现在我们期望来自联通网的用户到我们的DNS服务器上面查找我们的域名的时候给它返回我们位于联通网机房的服务器地址,来自电信网的用不到我们的DNS服务器上面查找我们的域名的时候给它返回我们位于电信网机房的服务器地址,该如何实现呢?简单来讲就是将我们的区域文件切割成两半,然后根据客户端的来源进行判断,如果客户端来自于电信网,我们就去查找电信网区域文件,如果客户端来自于联通网,我们就去查找联通网对应的区域文件,分别使用这样两个区域文件来应对来自不同的网络内的用户的请求,由此我们就可以将我们的域名的解析结果一分为二,这种结果我们也可以称之为脑裂(split brain),脑裂就是使得一个整体从中间切割开来的一种机制,但是也不一定分割成两个部分,我们可以根据业务需要将DNS服务器的区域文件切割为若干部分,比如对于全国来讲,我们可以按照地域对全国进行分区,比如说浙江联通、浙江电信、上海联通以及上海电信等等,这些区域都可以在我们的DNS服务器内部拥有自己的区域文件,那么对于一个可以将全国分为好几十个区域的庞大组织来说,一定有能力在每一个划分的区域内都部署上自己的服务器,这样一来对于每一个区域的用户来说都可以实现直接访问距离自己最近的并且是同一个网络内的服务器,这就是为什么我们无论身处何地,去访问淘宝这样的网站的时候速度都会非常的快,但是它们在全国各地部署的服务器不一定是原服务器,一般都是缓存服务器,目前来说,用户使用的最多的就是Web,而缓存服务器就可以给我们提供Web对象缓存,而原服务器都在公司内部的机房部署着,当某个区域的用户访问我们的公司的站点的时候,一般会先访问距离它最近的缓存服务器,而如果缓存服务器中没有该用户所要请求的内容的时候,缓存服务器就会向原服务器发起请求,之后将请求的内容缓存至本地,同时在返回给用户一份,同理当该区域的第二个用户再访问同样的内容的时候,缓存服务器就会直接将缓存的内容返会给用户,所以当我们一般第一次访问一个Web页面的时候,速度可能会很慢,但是一旦运行一段时间后,原服务器中的大部分内容都会全部缓存在缓存服务器中,所以之后的访问速度都会非常的快,而且当我们需要修改网站的内容的时候,直接在原服务器中修改再推送给缓存服务器即可,这种类型的网络有一些特性,它首先可以判断客户端的来源,并返回距离用户最近的缓存服务器得地址,并且这种网络本身能够从原服务器中获取数据并缓存至缓存服务器中,这种网络就称为CDN。
·CDN(Content Delivery Network:内容分发网络)
CDN的原始服务器可以将数据全部推送至距离用户最近的缓存服务器当中,目前Web页面中的内容大部分都是动态类型的,但是页面中的图片大都是静态的,而且缓存服务器能够缓存的内容都是静态的,动态内容得从原始服务器当中直接获取,但是动态内容的绝大部分也可以经过策略设定后静态化,并且缓存至用户本地,因此CDN的一个比较重要的前提就是能够准确的判断客户端的来源,而且还得根据客户端的来源给用户返回一个距离用户最近的缓存服务器的ip地址,因此只能DNS对于现在网络来说是一个比较重要的功能,但并非是必须的,因为CDN自身就拥有内容分发路由的功能。
·如何实现智能DNS的功能
假设我们现在拥有两个网络192.168.0.0/24和127.0.0.0/8,我们假设这两个网络全部属于电信网,而其余网段的网络全部属于联通网,我们现在就来看看来自不同网络的用户,到我们的DNS服务器上请求解析同一个域名的时候,我们的DNS服务器是否可以实现根据客户端的来源而给客户端返回不同的解析结果。
首先我们得准备三台主机,一台就是我们的DNS服务器,另外两台当做客户端,一台属于192.168.0.0/24网段即电信网,另一台属于其他网段即联通网,我们可以将客户端的DNS服务停掉,因为我们只是用它们来进行测试,要想实现智能DNS的功能,我们得在DNS服务器的主配置文件中配置视图(view)功能,DNS使用视图的方法非常简单,每一个视图在定义的时候我们只需要给它一个名称即可,视图的定义格式如下:
view VIEW_NAME {
除了directory参数,全局选项中可以定义的所有参数在视图中都可以定义,一旦我 们定义了视图,那么我们主配置文件中的所有zone都得定义在视图中,但是根区域 只需要定义在需要递归的视图中,但是我们作为一个DNS服务器只需要给自己域内的 的客户端递归就可以了,而没有必要给其他客户端递归,因此只要是不属于我们域 内的客户端主机我们都不用给它们递归,由此我们可以在主配置文件里面定义三个 视图,一个是我们内网的视图,一个是电信网的视图,最后一个就是联通网的视 图,而来自于电信网和联通网的用户我们都没有必要给它们递归,只要不递归就不 需要在视图内提供根域的解析,但是一般来讲我们是应该提供根域的解析的,只需 要随意在一个视图内提供根域解析即可。
};
首先将我们的DNS的主配置文件备份一份:
然后开始编辑,全局选项不用修改,而只是将所有的zone全部定义在view当中:
以上两个区域文件是两个完全不同的区域文件,那么接下来我们该如何在view中实现判断客户端来源的功能呢?只需要在每一个view当中添加一个关键性指令match-clients即可,如下:
接下来我们去建立对应的区域文件,首先是telecom的区域文件:
然后接下来是unicom的区域文件:
不要忘记检查区域文件的语法错误,还有MX记录得添加优先级,最后还得修改区域文件的属主属组和权限,当然了还要重启DNS服务。
接下来使用客户端进行测试:
1,首先使用telecom客户端进行测试
2,接下来使用unicom客户端进行测试
由于我这里只有192.168.0.0/24这么一个网段,故无法模拟来自联通网络客户端进行测试的场景。
3,使用Windows系统来模拟电信用户访问我们站点的场景,Window物理机和我们的Linux虚拟机是处于同一个网段的
以上就是我们实现如何将同一个域名解析为不同的结果的过程,这就是view实现的功能。
我们之前提到过同一台DNS服务器可以同时解析多个域,假设我们现在拥有两个域,一个叫做lkxedu.com.,一个叫做a.net.,并且a.net.域我们不区分客户端来源,无论来自哪里的客户端我们解析的结果都是一样的,该如何实现呢?
还是编辑DNS的主配置文件:
在我们刚刚定义的两个view当中同时都加上一个a.net.域的zone即可:
接下来建立a.net.域的区域文件:
最后使用dig命令进行测试即可:
DNS服务器在启动起来之后它会将数据直接载入内存,所以DNS的所有解析过程都是在内存中完成的,而不是在区域文件中查找的,所以我们每次在修改完DNS的数据文件的时候,重启服务的时候数据文件都是要被重新载入内存的,但是如果我们的数据文件比较大的话,这个载入内存的过程就会耗费很长的时间,因此后来人们发明了一种比较特殊的方法,将DNS主配置文件的zone不直接定义在主配置文件中,而是放到数据库中去,之后在我们的DNS服务启动的时候,它会自动将数据库中的内容全部抽取出来并载入到内存中去,而我们临时添加的内容,它也会临时到数据库中抽取并载入到内存中,这样做的好处是我们可以随时修改DNS的数据文件,而且修改也会随时生效,而且不用去读取数据文件,但是这样做还有一个坏处,坏处就是我们每一次的读取都会去读取数据库中的内容,在数据库中查找数据的速度要比在文件中查找数据的速度慢得多,虽然可以使得管理变得方便了,但是查找数据的速度却变得慢了很多,但是对于很多公用DNS服务器来讲,这还是比较常用的做法。
目前在互联网上有一个非常著名的项目叫做dnspod。
·dnspod
dnspod是中国非常著名的免费的智能DNS服务提供商,也就是说将来我们注册一个域名之后,可以将我们的DNS指向dnspod的服务器,然后在dnspod的服务器上面建立我们的区域文件,就能够实现智能解析,不但能够分网还可以分省,还有一个叫做dns.la。
·www.dns.la
这也是一个智能DNS的服务提供商,是马哥做的,马哥说它在国内排名第二。
·dlz
dlz就是一种能够将DNS的所有数据放入MySQL数据库中进行管理的机制,还有另外一种将DNS的数据放入数据库中的机制,在bind的rpm包中有一个叫做bind-sdb的软件包,这种机制就是用该软件包来实现的,默认情况下DNS的配置和数据信息都是保存在它的配置文件中的,但是bind-sdb这个软件包就可以实现将这些信息全部保存到数据库去。
·如何开启DNS的日志功能
比如说有哪些客户端到我们的DNS服务器上面查询过信息,我们就可以使用DNS的日志功能将这些客户端的行为记录下来,再比如说哪些客户端到我们的DNS服务器上面进行过区域传送,也可以使用DNS的日志功能记录下来,但是在真正的生产环境中,我们并不建议开启DNS的日志功能,因为处于互联网这个环境中,我们的DNS服务器每秒钟收到的查询请求可能会非常多,如果将每一个这样的请求都记录成为日志的话,可能会导致服务器的性能变得非常的慢,因为这个过程会产生大量的磁盘I/O去写日志信息,所以可能会导致原本性能很好的服务器的性能变得越来越差,接下来我们介绍一种很简单的开启DNS日志功能的方法:
直接编辑DNS的主配置文件并且在全局选项中添加一个querylog参数并赋值yes
接下来使用dig命令在客户端中进行测试即可:
然后我们在服务器中查看有无相关日志信息产生:
但是上图中记录的只是一次查询时产生的日志,我们的DNS服务器在互联网上很有可能会被大量发起查询请求,这样在我们的日志文件中就有可能会产生N条日志信息,这样管理起来会非常的麻烦,因此我们的DNS给我提供了一个非常有弹性的日志系统,它能够使得我们自定义去记录哪些日志,不记录哪些日志,这样一个日志系统需要定义两个子系统,一个叫做channel,另一个叫做category。
·category
category用来表示DNS的日志源,客户端发往我们主机的请求有很多种类型,比如说查询请求、区域传送的请求、服务器出错以及以及服务器的开启关闭等等类型的动作都会产生日志,这些不同的动作就叫做不同的日志源,所以category还有类别的意思,因此category可以理解为bind的子系统,它指的是产生日志的日志源,并且这些日志源可以由我们自己去定义,category虽然指的是日志源,但是bind的日志源一共就只有15个,除了这15个之外,我们不可以自己去发明DNS的日志源,也就意味着能够自定义category的意思是,我们可以定义一个或多个日志源并将它们综合在category里面的意思,DNS日志源的种类如下:
default -> 表示默认的channel(表示存放日志信息的文件的路径),即为所有的日志源定义channel
general -> 表示普通日志信息
queries -> 表示DNS查询操作产生的日志信息
xfer-in -> 表示作为从服务器来讲,从其它主机传送进来数据时产生的日志信息
xfer-out -> 表示作为主服务器来讲,传送数据到其它主机时产生的日志信息
config -> 表示配置文件中产生的问题产生的日志信息
network -> 表示和网络相关的日志信息
notify -> 表示和通知相关的日志信息
security -> 表示拒绝查询请求时产生的日志信息
·channel
channel用来将DNS的日志信息记录在什么地方,即channel用来定义DNS的日志目标即DNS日志的记录位置,因此我们一旦定义了一个日志源之后,就得给该日志源关联一个记录位置,一个category可以被定向到多个channel中,但是一个channel只能属于一个category,一般来讲我们记录日志的方式主要有两种,一种方式叫做syslog,另一种方式叫做file,file表示我们可以自定义记录日志的位置,如果我们使用syslog来记录日志的话,syslog是有日志级别概念的,它一共有7个日志级别:
1,debug
2,info
3,notice
4,warn
5,error
6,critical
7,emerge
一般来讲日志级别越高,记录的信息就越少,但是日志的级别越高,信息的严重程度就会越高,如果我们使用file来记录日志的话,也可以来自定义日志级别,file的日志级别和syslog的日志级别相同,主要有以下几种:
critical、error、warning、notice、info以及debug,但是file会有一个独特的日志级别叫做dynamic(动态级别),dynamic和debug级别都是DNS日志所独有的,DNS的debug日志级别和syslog的debug日志级别是不一样的,DNS的debug日志级别是分等级的(debug1、debug2、debug3等等,debug等级不同,该级别下所记录的日志信息的详细程度就不同,一般debug等级的数字越大,记录的信息就越详细),如果不定义的话,file所记录的日志级别默认是info级别。
·如何定义一个channel
定义一个channel很简单,使用channel关键字即可,格式如下:
channel CHANNEL_NAME { 日志方式;日志级别; };
如果要将日志记录到文件当中还可以自己定义额外的保存信息,例如:
print-severity表示每记录一条日志信息的时候,将当前日志信息的日志级别也记录下来
print-category表示记录由哪一个category记录的该条日志信息
print-time表示记录什么时间产生的该条日志,但是如果我们是使用syslog来记录日志的话,syslog自身就会记录时间,所以如果是使用syslog来记录日志的话,就不用再添加print-time
·DNS日志的定义格式
首先得使用logging关键字将所有的内容用花括号括起来:
logging {
#首先使用channel定义一个日志通道
channel my_file(channel名称) {
file(日志方式) "log_msgs(日志文件名)" version 3 size 10k;#表示日志滚动之后保存三个版本
severity(表示日志级别) dynamic;
};
channel my_syslog {
syslog local0(表示将日志信息记录在local0里面,但是syslog的配置文件中没有定义local0的日志信息是记录在什么地方的,所以我们还得自行定义);
severity info;#表示记录info以及info级别之上的所有日志信息
};
#接下来定义category
category xfer-in { my_file; };#表示xfer-in类型的日志信息以file的方式保存在my_file文件当中
category update { my_syslog; };#表示update类型的日志信息以syslog的方式保存在my_syslog文件中
};
以上就是如何定义DNS日志系统的格式。
·手动定义我们的DNS日志系统
假设我们期望在/var/named建立一个名为bind_query.log的文件,专门用于记录DNS查询请求产生的日志信息该怎么办?
编辑DNS的主配置文件:
并在全局选项下面定义logging,/var/log目录可能无法产生DNS的日志文件,因为运行DNS服务的进程是named进程,而named进程的属主和属组分别都是named,/var/log目录的属主属组和权限如下:
由上图知,named进程无法在该目录中写入任何文件,所以我们只有在该目录下再创建一个named目录,并将该目录的属主属组修改为named,然后将该目录专门用作named进程写入DNS日志文件的目录:
定义方式如下:
14 logging { 15 channel query_log { 16 file "/var/log/named/bind_query.log" versions 3 10M; 17 severity dynamic; 18 print-category yes; 19 print-time yes; #表示记录日志的时间 20 print-severity yes; #表示记录日志级别 21 }; 22 category queries { query_log; }; #表示queries类型的DNS日志信息全部记录到query_log这个channel中 23 };
接着在客户端使用dig命令进行测试,测试结果如下:
每重启一次DNS服务,日志文件就会发生一次滚动。
·如何手动定义我们的DNS服务器去记录和xfer-out相关的日志信息
直接在刚刚定义的channel下面再定义一个channel,然后在刚刚那个category下面再定义一个category即可:
然后在客户端使用dig命令进行模拟的区域传送即可:
一般来讲DNS涉及和查询以及安全相关的日志功能最好不好开启,因为这两种日志源所产生的的日志信息太多了,而和更新相关的日志记录功能最好开启。
·DNS服务器性能测试
有一个软件可以专门用来测试我们DNS服务器的性能,但是这个软件DNS服务器并没有提供给我们,不过我们可以自己下下来然后编译安装,这个软件叫做dnstop,dnstop可以用来监控DNS服务器每秒钟能够接受多少个并且是对哪个域名发起的查询请求,除此之外bind的源码包中还有一个命令叫做queryperf,该命令也可以用来做DNS服务器的性能测试。
·queryperf
这个命令可以对我们的DNS服务器做压力测试,即查看我们的DNS服务器每秒钟能够解析多少次域名请求,首先我们得下载一个bind的源码包,然后解压该源码包,解压之后,进入解压后的源码目录中去,在该目录中有一个contrib(该目录中的源程序都是别人贡献出来的)目录,进入该目录,该目录中就有queryperf目录,还有dlz目录,所以在bind97以后,dlz的功能就已经自带了,只不过我们使用的rpm包,在编译的时候没有将该功能编译进来而已,如果我们要使用的话,直接编译dlz即可,就可以实现dlz到MySQL中去查询数据的功能了,还有sdb,同样的,要使用的话直接编译安装即可,进入queryperf目录,直接在该目录中使用./configure命令,接下来在使用make命令就可以了,如果没有安装make工具的话,还得首先使用yum install -y gcc make命令去安装make工具,make成功之后,我们就可以使用queryperf命令,但是在使用之前还得将它复制我们的/bin目录中去,接下来就可以使用了。
·queryperf命令的用法
使用queryperf -h命令可以查看该命令的用法:
-d选项表示指定数据文件,要想使用-d选项,得首先自己创建一个数据文件,假设我们在自己的家目录下创建了一个test文件当做我们的数据文件,数据文件的格式如下:
接下来就可以使用-d选项指定数据文件,-s选项指定要测试的服务器来测试服务器的性能,还可以在queries类型的日志文件中查看产生的日志信息:
如果我们觉得产生的日志信息太少不足以测试出来我们服务器的性能的话,可能是因为我们的数据文件中的条目太少了,所以我们可以在我们的服务器中多添加一些条目,我们可以直接在数据文件中使用末行模式的命令:1,$y,然后粘贴,之后在进行测试:
经过测试,我们发现速度变得很快了,接着我们查看日志信息就会发现产生了很多日志:
由上图可知,产生了快10万行日志,接下来我们可以在客户端上面进行测试,这样可以更接近实际环境,将test文件和queryperf命令scp到客户端主机上面一份即可:
接下来开始测试:
使用top命令可以查看CPU的占用率,如果我们有多个CPU核心的话,CPU的占用率有可能会超过100%。
queryperf的-p选项表示指定端口,该选项也可以省略,-q选项表示查询多少次,一般来说该命令使用这几个选项就可以了,我们还有一个可以测试DNS服务器性能的工具,它就是dnstop。
本文出自 “菜鸟的技术文档” 博客,请务必保留此出处http://zhubo.blog.51cto.com/11395641/1893954
DNS的视图功能以及日志系统