目睹DNS怪现状 本地对DNS的设定故障分析

来源:互联网 发布:剑网3人物捏脸数据 编辑:程序博客网 时间:2024/04/28 18:20
  DNS(Domain Name System)在tcp/ip网络中,一个用户通过指定一个名字就可与其他用户进行通信,这个名称的规定和解析系统就叫域名系统。我们常用DNS代指域名解析服务(Domain Name Service),它最基本的功能就是将我们在IE地址栏中输入的URL域名(如:www.yesky.com )解析成网络上唯一的Internet地址即IP(如:218.201.41.19),这个工作由网络上的DNS服务器来完成。我们每天上网最频繁的操作恐怕就属发出DNS请求来访问网站了,而我遇到的两个怪现象都跟本地系统对DNS的相应设定有关。

  怪现状之一:在一以开启NAT路由的ADSL MODEM为网关设备的局域网中,一台主机在访问一个平时非常稳定的大站点时,出现了“该页无法显示”的状况,刷新多次也未能正常,而同一时刻在别的主机上却登录正常。过了几分钟,这台故障主机又莫名其妙的好了,访问此站点时一切正常了。

  分析:这种情况,由于其他的网络操作都正常,故障也不时常发生,一般用户很可能会认为自己的系统、IE浏览器和防火墙设置哪里出现了小冲突。其实这个故障的现象是由于本地系统的DNS缓存服务造成的。

  在win2000以上的MS系统中,系统会自动的将从DNS服务器上的查询结果保存在本地的DNS缓存中(每次启用DNS缓存时,Hosts文件中记录也会被载入缓存中),那么下次再有重复的查询请求,系统会优先查询本地缓存,如果已有对照的条目则不再向DNS服务器发起请求,缓存中无记录时才查询DNS服务器。本来设定此DNS缓存的目的是为了能减少DNS服务器的负荷,不用为同一个域名解析多次,也同时能加快客户主机上的访问速度。在DNS缓存中记录条目每隔一段时间将被更新一次,长时间不用的条目将被丢弃,这个时间间隔称为生存时间(TTL)。默认情况下,得到肯定响应的条目TTL为86,400 秒(1 天),否定响应的TTL win2000下是300秒(5分钟),在winXP和2003中 是 900 秒(15 分钟)。正是由于这个否定响应的TTL时间存在,所以才造成了故障主机在得到一次否定的DNS解析之后一段时间内无法再到DNS服务器上查询,只有等TTL时间过后,这条否定的记录被清除,才能恢复。

  遇到这种情况,我们能采取的最简单手段是刷新DNS,也就是删除 DNS 解析器缓存中的条目。点击“开始”-“运行”-输入cmd并点击“确定”,在命令提示符窗口中键入:ipconfig /flushdns,然后按 Enter 键。你将会收到“Successfully flushed the DNS Resolver Cache.”的显示,这时你的DNS缓存已被重置,主机发起的查询请求将再次发向DNS服务器。

  注:查看本地DNS缓存记录的命令为:ipconfig /displaydns。你将会看到包括本地Hosts文件记录和已访问过的站点在内的所有DNS记录。如图1所示:



图 1

  如果记录太多显示不全,还可以用如下命令将其保存成文本文件:

  ipconfig /displaydns >log.txt

  这个log.txt文档将生成在输入此命令的路径文件夹下。

  我们还可以通过调整注册表中TTL设定的键值来改善此种故障的状况。关于DNS缓存机制设定的键值都在如下路径中:

  HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Dnscache/Parameters

  点击“开始”-运行-键入regedit并确定,展开注册表到上面的路径中,在右边窗口可以看到如下图2中所示的键值:



图 2 windows2000中的DNS缓存设定键值

  其中MaxCacheEntryTtlLimit为DNS缓存条目TTL最大值,在XP和2003系统中此项名称为MaxCacheTtl。肯定响应条目的TTL,将由在DNS解析器收到的查询响应中指定的秒数和此项数值两者中最小值决定。如果将此项键值设为1秒,则DNS 缓存看起来已被禁用。图中的NegativeCacheTime为否定响应条目的TTL,XP和2003中此项名称为MaxNegativeCacheTtl。可以将此项键值改小或直接改为0,则不缓存否定的响应。而NetFailureCacheTime子项为常规网络缓存失败的控制时间,默认30秒。若系统重复发送多次DNS请求,而完全得不到任何DNS服务器的响应,系统会认为网络连接失效,在默认30秒的时间中将不会再向外发送任何DNS查询请求,此项也可减小或置0。

  另外,在XP中还使用了“子网优先级划分”机制。如果查询的域名从 DNS 服务器收到多个 IP 地址映射,并且记录中包含客户主机直连网段范围的IP地址,那么系统DNS解析器会优先放置此记录在缓存中。也就说在实际访问中,客户端将优先采用此IP作为肯定响应的DNS解析,这样会强制客户机连接到比较靠近它们的网络资源,从而减少了子网间的网络通信量。如果我们不想让系统这样做,可以通过在此路径的注册表项中添加一个值为 0(REG_DWORD 数据类型)的 PrioritizeRecordData 注册表条目来禁用“子网优先级划分”功能。

  当然,我们还可以通过在命令提示符中键入命令“net stop dnscache”和“net start dnscache”来暂时停止和重新开启DNS缓存服务。而想要永久停止此服务,需要到“我的电脑”图标上右键单机-“管理”-展开“服务和应用程序”-“服务”(如图03),在右面窗口中找到“DNS Client”服务项上右键单击-“属性”,然后在“启动类型”中选择“已禁用”即可。在WinXP等系统中此项服务名称还可能会显示为“DNS Cache”。要注意的是,禁止掉DNS缓存将使每次查询都发送到指定的DNS服务器,不利于访问速度。



图 3



图 4

  解决:当此主机再次遇到同样故障时,用刷新DNS缓存命令,果然快速解决了问题,肯定了是由DNS解析造成的问题。经过调整注册表键值也确实改善了故障持续的时间,但具体分析到此种故障几乎都集中在这台主机,同一时刻别的主机则没发生类似的情况,而且ISP的DNS服务器一般都是很稳定的,所以最后怀疑是主机的“本地连接”属性-“Internet连接(TCP/IP)”属性中“DNS服务器地址”设定有问题。经查看,其他主机都是直接设定的当地ISP给定的DNS服务器地址,而此故障主机的DNS设的是网关IP,也就是指向了那台启用了路由的ADSL MODEM,这种情况下ADSL MODEM充当DNS Proxy即DNS代理或叫DNS转发的角色(开启路由后,一般默认支持DNS转发,有些MODEM则需要手动启用此功能)。它将客户机发送的DNS请求转发到它所知的DNS服务器上去,而很可能是由于这台ADSL MODEM的软件性能不稳定,致使DNS转发时偶尔出错,造成了客户主机系统认为DNS解析被否定或失败。既然明白了故障起因,那就好办了。将此主机的DNS设定改为ISP给定的公网本地DNS服务器地址,果然以后不再出现同样的故障了,至此这一怪现状被彻底解决了。

  怪现状之二:朋友的局域网中原有一台Windows 2000 DNS服务器,自从将其升级为Windows Server 2003以后,他就不能访问一些网站了,但是升级过程中没出现任何的错误。

  分析:按照经验,这很可能是由于root Cache文件丢失或损坏造成的。这种情况可以使用 DNS 管理单元手动添加根目录提示、将硬盘上的 Cache.dns 文件替换为备份 Cache.dns 文件或替换为 windows Server 2003 CD 中的原始版本 Cache.dns 文件来解决。恢复方法如下:

  第一步:使用 DNS 管理单元更新根目录提示

  在非域控制器上:

  1. 单击“开始”,指向“管理工具”-“DNS”。 
  2. 在控制台树中,右键单击“服务器名”-属性”。(“服务器名”是指服务器的名称)
  3. 单击“根目录提示”选项卡,然后单击“添加”。
  4. 指定要添加的根服务器的完全限定域名称 (FQDN) 和 IP 地址,然后单击“确定”。

  在域控制器上:

  1. 点击“开始”-“运行”。在“打开”框中,键入 cmd,然后 “确定”,打开命令提示符窗口。
  2. 停止 DNS 服务。请在命令提示符处,键入 net stop dns,然后按 Enter 键。
  3. 将 Cache.dns 文件从 %SystemRoot%/System32/Dns/Samples 文件夹复制到 %SystemRoot%/System32/Dns 文件夹。在命令提示符处键入下面的行,然后回车即可:
  copy %systemroot%/System32/Dns/Samples/Cache.dns %systemroot%/System32/Dns
  如果系统提示您改写现有文件,请键入 y,然后按 Enter 键。(这里的 %SystemRoot%指本地系统所在文件夹根目录,如C:/windows)
  4. 点击“开始”,指向“管理工具”,然后单击“Active Directory 用户和计算机”。
  5. 在“查看”菜单上,单击“高级功能”。展开“系统”,展开“Microsoft DNS”,右键单击“Root DNS Servers”,然后单击“删除”。在提示确定删除时,单击“是”。 退出 Active Directory 目录服务用户和计算机 MMC 管理单元。
  6. 启动 DNS 服务。在命令提示符处键入 net start dns,然后按 Enter 键。
  7. 点击“开始”,指向“管理工具”,然后单击“DNS”。 
  8. 在控制台树中,右键单击“服务器名”,然后单击“属性”。 单击“根目录提示”选项卡,并确认根服务器是否显示在“名称服务器”列表中。
  9. 单击“开始”,指向“管理工具”,然后单击“Active Directory 用户和计算机”。
  10. 展开“系统”,展开“Microsoft DNS”,然后确认已重新创建了“Root DNS Servers”容器,并且该容器是否包含根服务器列表。

  第二步:复制Windows Server 2003 CD 中的 Cache.dns 文件覆盖损坏文件

  1. 放入Win2003 CD。点击“开始”,然后单击“运行”。键入 cmd,然后单击“确定”。
  2. 在命令提示符窗口中,键入下面的命令,在每一行之后按 Enter 键:

  光驱盘符(如E):
  cd i386
  expand cache.dn_ %systemroot%/System32/Dns/Cache.dns

  3.退出命令提示符。

  注:如果是从备份的Cache.dns文件恢复。那么需要先用net stop dns停止DNS服务,并用ren cache.dns cache.old将当前cache.dns文件改名,然后Copy备份文件到DNS目录。最后用net start dns将DNS服务重新启动。

  但是,经过了Cache文件的恢复之后,问题依旧没能得到解决。而且最奇怪的是,这种情况下仍能Ping通这些网站,至此问题陷入了僵局。最后,经过多方面的资料查询,了解到原来Windows2003中为DNS嵌入了新的扩展结构(Extension Mechanisms),默认情况下这个EDNS是启动的,它允许通过使用大于512KB的UDP包来改善性能。而很多防火墙基于安全的考虑,并不允许这么大的UDP包,会直接拒绝或丢弃它们。这就造成了网络和DNS服务一切正常的情况下无法访问一些网站的怪现状。

  解决:还是那句话,既然明白了故障起因,那就好办了。首先,可以查询防火墙供应商是否为这个问题发布了修正补丁,如果有直接升级就解决了。如果没有,那么可以暂时禁用此EDNS,等待补丁的发布。要禁用EDNS,先要安装Win2003 CD的支持工具中的命令行工具“dnscmd.exe”。然后,打开命令提示符窗口输入:dnscmd /config /enableednsprobes 0,按Enter键即可停用EDNS。当防火墙得到了升级修正之后,重新启用EDNS时,输入:dnscmd /config /enableednsprobes 1,按Enter键即可。至此,这一怪现状得到了完满解决。

  注:关于EDNS的更多详细信息,可以参看IETF的RFC 2671文档(http://www.ietf.org/rfc/rfc2671.txt?number=2671)和微软的官方文档(http://www.microsoft.com/resources/documentation/WindowsServ/2003/standard/proddocs/en-us/Default.asp?url=/resources/documentation/windowsserv/2003/standard/proddocs/en-us/sag_dns_imp_ednssupport.asp)。

原创粉丝点击