Xupeng's blog

圆外之大,心向往之

Snow leopard 的诡异 DNS 问题

用 Mac 一年来遇到最诡异的问题,就是 Snow leopard 的 DNS 问题了,最常遇到的状况是,dig/nslookup/host 都能够正确解析域名,但 ping 却不能解析任何域名,其他的一票软件如 ssh、浏览器等也因为解析不了域名而不能正常工作。

发生这种状况时,我一般会看看 mDNSResponder 是否异常,曾多次遇到 mDNSResponder CPU 占用 100%,这种情况下 kill 掉 mDNSResponder,等它自动重启之后,DNS 解析问题通常就会恢复正常。但也不尽如此,我越来越多次有类似的 DNS 解析问题时,重启 mDNSResponder 进程并不凑效,log 中也未能发现对我有意义的线索。

今天又遇到了这样的问题,与以前一样,dig/nslookup/host 能够正确解析所有域名,ping 和其他软件则不能,和之前略有不同的是,这次的状况是 VPN 内网的域名不能解析,而其他的外网域名可以正常解析,于是花了点时间做了些探索,同时也找到了一篇详尽解释Snow leopard DNS解析问题的文章

简单说来,dig/nslookup/host 对 /etc/resolv.conf 中的 DNS server 直接进行查询,因此只要 DNS server 本身工作正常,这三个程序都可以正常解析。而系统的其他部分则不同,在 Mac OS X 10.6 Snow leopard 中,由 mDNSResponder 负责所有的 DNS 解析,包括单播 DNS(传统的域名解析)和多播 DNS(Bonjour),mDNSResponder 并不使用 /etc/resolv.conf 中的 DNS,实际使用的 DNS 是使用 scutil 来设置的,并可以使用 scutil –dns 来查看当前使用的 DNS server 和顺序,而在 resolv.conf 中看到的 DNS,只是 mDNSResponder 列出来的 primary DNS resolvers。

以 xxx.douban.com 这个子域为例,假设内部 DNS 地址为 1.2.3.4,对于我遇到的内部域名不能正确解析的情况,可以使用 resolver(man 5 resolver) 来解决,方法是:

1
2
sudo mkdir -p /etc/resolver
echo "nameserver 1.2.3.4" > /etc/resolver/xxx.douban.com

意指使用 1.2.3.4 作为 xxx.douban.com 这个域的域名服务器。

resolver 的这个功能同时也给我带来了极大的便利,我以前指定用特定的服务器来解析某域时,通常是在本地跑一个 dnscache 实例,在 dnscache 中做类似配置,现在直接使用 resolver 即可,比如我可以在 openvpn 服务器端推送到 8.8.8.8 的路由记录,使得到 8.8.8.8 的链路经由 VPN 加密,然后在本地配置指定比如 twitter.com 使用 8.8.8.8 来解析,就可以解决国内劫持 twitter.com 域名的问题了。

Comments