我的Hosts文件之前都可以正常使用的,但是最近不知何故突然失效了。
如图,给大家做个演示测试:
可见hosts文件路径是对的,而且只有一行映射,确保没有其他的干扰项。

使用ipconfig /flushdns清理DNS缓存,而且其实我还停止了DNS Client服务的。然后继续ping,依然返回的是真实DNS解析的地址。

如图,可见system的权限也是有分配的。下面那个我自己的账户和Admin组的账户的权限也是完全控制的。
情况就是这样,不知为何最近突然失效了。我可能是遇到什么劫持了么?
上网找了一通,解决办法都没有用,不知究竟是什么原因呢?
我是分割线,解决办法在14楼我自己的回复里,因为不能标记自己的回复为解答,所以贴上来了
您好!
其实我这些天一直在试图找到一个办法,来检测windows是否成功读取到了hosts文件。因为现在的情况,非常像windows本身漠视了hosts文件的存在(但是我的确没有弄错路径)。所以如果能有个办法来检测到windows是否成功读取了hosts文件就好了。
我在想,windows是否会缓存hosts文件,这样的话,内存中应该有个hosts文件的副本,那可能有某种途径能读取这片内存空间,看看内容是否和实际hosts文件的内容对应即可判断是否成功读取了。
如果windows不缓存hosts文件,而是直接每次请求一次DNS解释就打开一次hosts文件检测是否有对应映射的话,那应该也可以有个办法检测到windows是否有触动hosts文件,是否触动成功等。比如是否会产生一些消息记录?
苦于没有找到相应的检测办法,所以不知您是否有一些高见?
非常感谢这些天来 王小石 和 John Wu 的倾力帮助,给了很多很有帮助的提示!
现在问题已经被我自己解决掉了,公布如下:
根据引用中我的猜想,我使用了消息记录器来跟踪与hosts文件有关的系统消息。为了对比,我同时在windows 8.1和虚拟机中运行的windows XP下操作,以便作为对比。
首先我发现其实所有有网络通信功能的程序都会去检测HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\
这个键下面是否存在UseHostsFile值是否存在,数据是多少。但是我发现无论XP还是8.1都没有该值,但是根据之前的实验可知是XP可以正常读取hosts文件的,所以可以断定这个是无关项。(不过根据这个判断,原来Dnscache服务(也就是在服务中显示名称为DNS Client的服务,用于缓存DNS解析的结果)是可以手动强制不读取hosts文件的,修改这个键值即可)
然后我发现一个怪异的现象,每次我手动修改hosts文件后,在8.1下会显示出一个名为svchost.exe的进程试图访问hosts文件但是结果为Acces Denied。在XP下,也有同样名称的进程试图访问hosts文件但是结果却是Success的。
根据消息记录器提供的进程的PID,追踪到其承载的服务中有一个共同的服务就是DNS Client。于是可以断定肯定是上述提到的DNS Client服务出现问题了。因为出现访问文件被拒,肯定是帐户问题,于是我习惯性地打开DNS Client的属性页,转到登录选项卡,发现其使用的帐户不是默认本地系统帐户,而是名为“Network Service”的内置安全主体。
到此一切都明了了,归根到底还是权限问题。DNS Client服务使用的帐户不是system,而是Network Service。虽然我给system帐户赋予了完全的访问控制,但是根据我开篇的截图可以发现,我里面缺少了Network Service的安全主体。而现在我们可以断定system帐户和Network Service安全主体是没有关联的,所以才导致了DNS Client服务启动后无法正常读取hosts文件,而导致hosts文件无效。
解决办法就是:编辑etc文件夹的访问权限,添加Network Service安全主体并赋予至少允许读取的权限,然后重新启动DNS Client服务即可。目前我的hosts已经一切正常。
题外话:在使用消息记录器做实验的时候,发现一点值得提及的:
当没有关闭DNS Client服务时,每次更新hosts文件后,只会有svchost.exe进程去读取hosts文件。但是当关闭DNS Client服务后,所有有网络通信功能的进程都会独立去读取这个hosts文件。
而且,在没有关闭DNS Client服务时,已知仅有svchost.exe进程去读取hosts文件,但也仅仅读取一次hosts,在直至下一次修改hosts文件前,svchosts.exe都没有反复第二次读取hosts文件,无论期间其他的程序创建了多少次网络访问的请求。但是当关闭服务后,所有有网络通信功能的进程每一次访问网络时都会独立去读取hsots文件,不管hosts文件是否有更新。
所以我猜想出hosts的工作原理:
首先我们知道,所有具有网络通信功能的进程都需要包含网络通信模块DLL。其实在这个DLL编写之初,并无考虑到DNS Client服务的存在。所以其实关闭DNS Client服务后的表现是原始的处理过程:每个进程独立管理自己的网络连接,处理自己的网络地址解析(windows网络通信模块的确一开始也是这样制定的)。而自己处理自己的网络地址解析,当然有一个步骤就是首先解析hosts文件了,所以每个有网络通信功能的进程都会独立去访问hosts文件并解析它。而且这时候并无缓存机制,每次读取解析完毕立即释放,待下次网络地址解析请求发生时再一次读取hosts文件,即使期间hosts并没有更新。
而DNS Client服务是后来才出现的,目的是解决DNS解析的混乱吧。不管其出现是为了什么,反正其就把网络地址解析这个功能独揽过去了。这个时候开始,每个有网络访问功能的进程包含的网络通信模块在处理网络地址解析的时候,都会首先去看系统中是否启动了DNS Client服务,如果有启动,那就把请求交由它来完成。所以对于hosts更新的维护,仅仅需要在DNS Client服务中进行就可以了,无需每个进程都去读取hosts文件。所以就有了上面提到的流程:每次更新hsots文件后,仅仅有svchosts.exe进程去读取hosts文件,而其他进程在访问网络的时候,不再产生hosts文件的读取记录。而且,svchost.exe进程并没有每来一个网络地址解析请求就更新一次hosts文件,相反,它等到hosts下一次更新的时候才再次读取,这期间其一直使用自己读入的缓存。
所以可以看到,DNS Client服务的确是有好处的,其统一了对网络地址解析的访问,让网络请求有序化。而我猜统一的访问是为了加入缓存机制铺路的。这是因为,如果是“独立自治”又采取缓存机制的话,那每个进程都要独立监视hosts文件,显然不是明智的做法。加入了缓存机制后,使得对hosts文件的访问大大减少,不用每次访问网络都需要读取一遍hosts文件,而是使用缓存好的数据,这样可以提高系统的处理速度。