热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《DNS与BIND(第5版)》——10.3DNSNOTIFY(区域变更通知)

本节书摘来自异步社区《DNS与BIND(第5版)》一书中的第10章,第10.3节,作者:【美】JosephDavies更多章

本节书摘来自异步社区《DNS与BIND(第5版)》一书中的第10章,第10.3节,作者: 【美】Joseph Davies 更多章节内容可以访问云栖社区“异步社区”公众号查看。

10.3 DNS NOTIFY(区域变更通知)

习惯上,BIND中的slave通过轮询(polling)机制来决定何时需要进行区域传输。轮询间隔时间又被称为更新间隔时间(refresh interval)。而区域SOA记录中的其他参数,则可以用来配置轮询机制的其他参数。

但是使用这种轮询机制,在slave检测到并且从其master名称服务器传回新的区域数据,需要等待一段更新间隔时间。对使用动态更新的环境而言,这种延迟所带来的后果是灾难性的。当区域信息变更时,如果primary名称服务器能够主动通知slave服务器,岂不更好?毕竟,primary名称服务器能感知数据发生了改变:有人重载(reload)了数据,或其收到并处理了一条动态更新。因此,primary可以在处理完重载或更新之后立即发送通知,而不必等待更新间隔时间的到来1。

RFC 1996提出了一种机制,允许primary名称服务器通知slave,区域数据已经变更。BIND 8和9已实现了这一功能,并称之为DNS NOTIFY。

DNS NOTIFY的工作原理如下:当primary名称服务器注意到区域的序号已经改变时,便会给该区域所有slave服务器发送一条特殊的通告。primary名称服务器通过检索区域NS记录,排除出现在区域SOA记录MNAME字段中的名称服务器和本地主机域名,从而确定区域中所有的slave服务器。

名称服务器会在何时发送变更通知?重启primary名称服务器,会导致其通知所有slave当前全部区域的序号,因为primary无从得知其区域数据文件在启动之前是否被编辑过。以新的序号重载一个或多个区域,会导致名称服务器通知区域的slave。并且动态更新会使区域的序号增大,这也会导致名称服务器发送变更通知。

这个特殊的NOTIFY通告,可以通过检查DNS包头中的opcode来加以识别。一般查询要求的opcode多为QUERY。而NOTIFY消息,包括通告与应答,具有一个特殊的opcode,即NOTIFY。除此之外,NOTIFY消息看起来和对区域SOA记录所做查询的响应很像:因为两者都包含序号被改变的区域SOA记录,并且authoritative answer(权威应答,简称aa)位也被置位了。

当slave从它的master名称服务器收到区域的NOTIFY通告时,它会发送NOTIFY响应。该响应用来告知master,它已经收到NOTIFY通告,于是master就会停止向它发送该区域的NOTIFY通告。随后,就像该区域的更新间隔时间到期一样,slave会执行以下动作:向master名称服务器查询其声明有变动的区域SOA记录。如果发现序号更大,则slave就会执行区域数据传输。

为什么slave不直接相信master发送的区域变更消息呢?因为攻击者可能通过伪造NOTIFY通告来欺骗slave,目的在于制造许多不必要的区域数据传输,导致master瘫痪,从而实现对master名称服务器的拒绝服务攻击。

如果slave实际完成了区域数据传输,RFC 1996还提到:slave应该向该区域中的其他权威名称服务器发送自己的NOTIFY通告。这样做的原因是:只靠primary master可能无法通知到区域中所有的slave服务器,因为很可能某些slave无法直接和primary master通信(所以才会使用另一台slave作为它们的master)。虽然BIND 及其后续版本,以及所有BIND 9名称服务器都实现了该功能,但是BIND 8的早期版本并不支持该功能。对于旧版的BIND 8,除非有明确的配置,否则slave不会发送NOTIFY消息。

下面来看它实际是如何工作的。在网络上,toystory.movie.edu是区域movie.edu的primary名称服务器,而wormhole.movie.edu和zardoz.movie.edu则是slave,如图10-1所示。


<a href&#61;https://yqfile.alicdn.com/7e533dcef25e5a482eb14a069bc2c299f1e3a7fc.png" >

当在toystory.movie.edu上编辑、重载或动态更新区域movie.edu时&#xff0c;toystory.movie.edu将给wormhole.movie.edu和zardoz.movie.edu发送NOTIFY通告。这两个slave都会向toystory.movie.edu发送应答&#xff0c;表示已经收到通知。它们接着检查区域movie.edu的序号是否增加&#xff0c;如果增加了&#xff0c;便会执行区域数据传输。如果wormhole.movie.edu和zardoz.movie.edu所运行的是BIND &#xff08;或其后续版本&#xff09;或者BIND 9的名称服务器&#xff0c;当传输完新的区域数据后&#xff0c;它们还会彼此发送NOTIFY通告&#xff0c;以便通知其他slave服务器区域数据已经改变。不过对区域movie.edu而言&#xff0c;wormhole.movie.edu并不是zardoz.movie.edu的master名称服务器&#xff0c;反之亦然&#xff0c;所以它们彼此都会忽略对方的NOTIFY通告。

BIND名称服务器会把与NOTIFY有关的信息记录在syslog中。下面是在重载区域movie.edu后&#xff0c;toystory.movie.edu的日志记录&#xff1a;


da4117ca49205125913be3ba40c414cc4bc5c176

其中&#xff0c;第一条信息表示toystory.movie.edu发送NOTIFY通告&#xff0c;用来通知两个slave&#xff08;2NS&#xff09;&#xff0c;区域movie.edu现在的序号是2000010958。另外两条信息表示这两个slave名称服务器已经确认收到了该通知。

BIND 9名称服务器仅会记录&#xff1a;


4b0e1e28d2e851eed9e9d31f0905043e7961c524

再来看一个更复杂的例子。在图10-2中&#xff0c;a是区域的primary master名称服务器&#xff0c;也是b的master服务器&#xff0c;而b是c的master服务器&#xff0c;并且b有两个网络接口。

在这个例子中&#xff0c;区域数据更新后&#xff0c;a会通知b和c。随后b会向a查询区域的序号是否增加&#xff0c;如果增加则启动区域数据传输。然而&#xff0c;c会忽略a的NOTIFY通告&#xff0c;因为a不是c所配置的master名称服务器&#xff08;b才是&#xff09;。如果b运行的是BIND &#xff08;及其后续版本&#xff09;或者BIND 9&#xff0c;或者明确配置成通知c&#xff0c;那么在b完成区域数据传输后&#xff0c;它还会给c发送NOTIFY通告&#xff0c;这会提醒c去检查b所持有的区域序号。如果c运行的也是BIND 8.2.3&#xff08;及其后续版本&#xff09;或者BIND 9&#xff0c;它也会在完成区域数据传输后&#xff0c;给b发送NOTIFY通告&#xff0c;当然&#xff0c;b会把它忽略掉。

同时请注意&#xff0c;如果c有可能会从b的另外一个网络接口收到NOTIFY通告&#xff0c;c就必须把b的两个网络接口的IP地址&#xff0c;都配置到其zone语句的masters子语句中&#xff0c;否则c会忽略来自另一个未知接口的NOTIFY通告。


<a href&#61;https://yqfile.alicdn.com/720d904b29fd267ea7edbd130053f14f5505770b.png" >

至于BIND 4版本的slave名称服务器&#xff0c;以及其他不支持NOTIFY功能的名称服务器&#xff0c;则会回应NOTIMP&#xff08;Not Implemented&#xff0c;不支持指定的操作&#xff09;的错误信息。请注意&#xff0c;Microsoft的DNS服务器支持DNS NOTIFY功能。

在BIND 8和9中&#xff0c;虽然DNS NOTIFY是默认开启的&#xff0c;但是可以用如下子语句从全局上完全关闭该功能&#xff1a;


<a href&#61;https://yqfile.alicdn.com/8e30b8e7829fcaaf55de1c20887c452e5418ef4e.png" >

你还可以针对特定的区域开启或关闭NOTIFY功能。例如&#xff0c;如果知道区域fx.movie.edu中所有的slave名称服务器都使用BIND 4版本&#xff0c;因此它们都不能识别NOTIFY通告&#xff0c;那么zone语句可以配置为&#xff1a;


ae90034e824f55b107e205eae406a10b1a17469a

这样就可以避免给fx.movie.edu中的slave发送无用的NOTIFY通告。针对特定区域的NOTIFY配置&#xff0c;将会覆盖针对全局的配置。可惜BIND 8和9都不允许针对特定的服务器关闭NOTIFY功能。

除了区域的NS记录中指定的服务器&#xff0c;BIND 8和9甚至允许将其他服务器增加到“NOTIFY列表”中。例如&#xff0c;可能存在一个或多个未注册的slave名称服务器&#xff08;本书第8章介绍过&#xff09;&#xff0c;不过又想让它们尽快取得区域数据更新。或者可能存在一个运行较旧版本的BIND 8名称服务器&#xff0c;它虽然是区域的slave&#xff0c;但同时又是另一个slave的master服务器&#xff0c;同样需要传送NOTIFY消息给该slave。

要将服务器加入NOTIFY列表&#xff0c;可在zone语句中使用also-notify子语句&#xff1a;


de77acdcbec15cb3392b9903494fb3227ccd001e

在BIND 及其后续版本的名称服务器中&#xff0c;还可以把also-notify作为options的子语句。当NOTIFY功能开启时&#xff0c;该处所做的配置将会应用到所有区域上&#xff08;只要它们没有配置自己的also-notify子语句&#xff09;。

从BIND 和9.1.0开始&#xff0c;配置notify子语句时可以同时指定explicit这个参数&#xff1b;这将禁止把NOTIFY消息转发给所有名称服务器&#xff0c;除非在also-notify列表中另有指定。例如&#xff0c;下面两条子语句将名称服务器配置为只给IP地址为192.249.249.20的slave发送NOTIFY消息&#xff1a;


<a href&#61;https://yqfile.alicdn.com/9bfe715f9be9c0330d8fc2efe4a4859916854a0d.png" >

还可以使用allow-notify子语句告诉名称服务器&#xff0c;可以接受来自区域中master以外的其他名称服务器发送的NOTIFY消息&#xff1a;


<a href&#61;https://yqfile.alicdn.com/766d5be66687d30596295fcee72b2f327a5c3955.png" >

如果作为options的子语句&#xff0c;则allow-notify的配置会影响所有slave区域。如果作为特定zone的子语句&#xff0c;则allow-notify的配置会覆盖掉该区域所有全局allow-notify配置。



推荐阅读
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有