使用国外DNS造成国内网站访问慢的解决方法

你是否是一个使用国外 DNS 的中国网民?你是否发现使用国外 DNS 之后访问某些国内网站奇慢无比?这不是 DNS 慢,而是电信到联通的线路太慢。如果你愿意小小地折腾一下,那么跟随本文,你可以解决这一问题。

一、为什么要用国外 DNS

由于众所周知的问题,国内 DNS 服务器解析国外网站会遭到 DNS 污染和投毒,使之解析到完全虚构的 IP 上,造成「开了 VPN 也没法访问 Twitter 或 Facebook」等问题。以下是一个例子:

wzyboy@vermilion:~$ dig twitter.com @8.8.8.8 +short

199.59.148.82

199.59.149.230

199.59.148.10

wzyboy@vermilion:~$ dig twitter.com @221.228.255.1 +short

93.46.8.89

Twitter 正确的 IP 地址应该是 199.59.148.0/24 里的那几个,但是如果用 221.228.255.1 这台中国电信的 DNS 服务器查询,查到的就是不知道什么鬼地址了,地理信息是在意大利,乱七八糟的。正是因为这样的 DNS 解析不正确的情况出现,不少人转而使用了国外的 DNS 服务器,如老牌的 OpenDNS 以及这几年新崛起的好记又好用的 Google Pulic DNS 即 8.8.8.8 和 8.8.4.4。使用它们进行查询,再配合以 VPN 或者浏览器的远程 DNS 解析,便可避免 DNS 污染的情况出现,从而解析出正确的地址。

此外,拒绝使用电信的 DNS 服务器,还可以避免烦人的「114 上网导航」页面……

二、为什么使用国外 DNS 会「慢」

我是在「慢」上加了引号的,因为这其实不是国外 DNS 慢,而是你要访问的网站的 CDN 分配错误,慢。由于国内各大运营商之间的主干线路带宽太窄,所以导致「最远的距离是从电信到网联通」,电信用户访问联通的服务器非常慢,联通用户访问电信的服务器也非常慢,相信这都是大家有体验的。因此,国内不少网站都用了双线 CDN,在电信的机房里放点服务器,再在联通的机房里放点服务器。运用智能 DNS 技术,当你访问网站的时候,DNS 根据你的来源 IP 判断你是电信用户还是联通用户,然后再返回相应的 IP 地址,这样你会访问到就近的、同运营商的服务器,访问速度就大大提升了。而如果使用国外的 DNS 的话,你的查询来源来自国外,国内网站的 DNS 无法判断你是电信用户还是联通用户,就胡乱分配你一个服务器。比如我是一个江苏电信的用户,但当我访问淘宝网的时候,淘宝的 DNS 把我解析到青岛联通的服务器上,奇慢无比。所以:

很多人认为 Google Public DNS, OpenDNS 等「慢」,主要不是查询慢,而是电信到联通之间太慢。

当然了,如果硬要比较查询的话,倒也是会慢很少一点的:

;; 使用 8.8.8.8 解析 www.google.com 耗时 79 毫秒

;; Query time: 79 msec

;; SERVER: 8.8.8.8#53(8.8.8.8)

;; WHEN: Thu Sep 6 17:20:37 2012

;; MSG SIZE rcvd: 143

;; 使用中国电信 221.228.255.1 服务器解析 www.google.com 耗时 6 毫秒

;; Query time: 6 msec

;; SERVER: 221.228.255.1#53(221.228.255.1)

;; WHEN: Thu Sep 6 17:20:44 2012

;; MSG SIZE rcvd: 284

别看 6 毫秒和 79 毫秒差别很大的样子,但是人类是很难感觉出来的,而且,这只是查询时间,与实际的访问速度无关,就算你一整天都在刷 www.google.com,也就每小时慢个几百毫秒的样子,根本感觉不出来。真正慢的原因,还是上文所说的「电信到联通」的问题。

三、问题的解决思路

现在问题明确了:使用国外 DNS 之后,查询来源变成国外的 IP,使用了 CDN 加速的国内网站的 DNS 会无法判断你的来源,胡乱给你分配一个地址,如果不是同一个运营商的,访问速度便会很慢。

那解决方案也就出现了:让国内网站的 DNS 服务器知晓你的来源,从而给你分配正确的服务器 IP。于是 Google 起草了一个专有协议,叫 EDNS,在 DNS 查询请求中包含源地址,这样淘宝就知道查询来源不是 Google 服务器,而是电信的某用户,就不会把你扔到联通服务器上了 。听起来很美好是吧?不过这个协议不开放,目前几乎没有人用,所以,问题丝毫没有解决。

新思路是:访问那些会因 CDN 加速解析错误而极其缓慢国内网站的时候,直接向国内的服务器发送请求,让 DNS 知晓你的来源,给你分配个正确的 IP。访问其他网站的时候,再通过国外的 DNS 查询。

听起来很简单的样子,实现起来也不难:用 dnsmasq 在本地搭个 DNS 缓存服务器,规定哪些域名用哪个服务器查就好了。

四、安装及配置 dnsmasq

安装 dnsmasq

dnsmasq 是一个非常轻量的 DNS 缓存及 DHCP 服务器,在我的 Arch Linux 上只占用了 368 KiB 的磁盘空间,相比功能极其强大的 BIND9 来说小多了(BIND9 的安装体积是 6.23 MiB)。不光是体积小,它的功能也很专一,配置起来也是十分方便的,五分钟就可以搞定。

Ubuntu 12.04 及之后的版本应该自带了 dnsmasq。如果没有,可以使用 sudo apt-get install dnsmasq 安装。Arch Linux 直接 sudo pacman -S dnsmasq 即可。我的笔记本电脑需要给手机 DHCP 及 IP 转发用,因此早就安装了 dnsmasq,但是直到今天才想起这么用它……

配置 dnsmasq

dnsmasq 的各参数可以通过 man dnsmasq 查看,配置文件中也有许多清晰明了的注释。默认的配置文件位于 /etc/dnsmasq.conf,打开它,可以更改这几个地方:

no-resolv

no-poll

server=8.8.8.8

server=8.8.4.4

server=/cn/114.114.114.114

server=/taobao.com/114.114.114.114

server=/taobaocdn.com/114.114.114.114

server=/tbcache.com/114.114.114.114

server=/tdimg.com/114.114.114.114

第一行的 no-resolv 和第二行的 no-pull 让 dnsmasq 不要通过 /etc/resolv.conf 确定上游服务器,也不要检测 /etc/resolv.conf 的变化(因为我们就是要拿本机当服务器嘛),接下来两行指定 dnsmasq 默认查询的上游服务器,此处以 Google Public DNS 为例,喜欢用 OpenDNS 的也可以改 OpenDNS。接下来就是规定一张名单了,把一些国内网站的域名写在这里即可。比如 server=/cn/114.114.114.114 便是把所有 .cn 的域名全部通过 114.114.114.114 这台国内 DNS 服务器来解析,你也可以改成其他的国内 DNS 比如你的运营商提供的 DNS。接下来四行是淘宝的几个域名,让它们也通过国内的 DNS 服务器解析。

这样分流操作之后,默认所有域名都通过 8.8.8.8 和 8.8.4.4 解析,但是所有的 .cn 域名以及淘宝的域名通过 114.114.114.114 这台国内 DNS 服务器解析。当然,除了淘宝网,你也可以添加更多的域名,根据自己的喜好,把经常访问,但是使用国外服务器解析到很慢的服务器上的网站域名都可以添加进去,不过:如果这个网站本身就只能一台服务器,没有 CDN 加速,那再怎么添加也是无济于事的,得让网站管理员去买双线机房……另外,在写这篇文章的时候,发现 @felixonmars 维护了一张国内常用的、但是通过国外 DNS 会解析错误的网站域名的列表,据他所说,这是他在公司里部署这一套东西之后,公司里其他人报怨「慢」的网站域名收集来的,应该囊括了绝大多数有此问题的网站,值得依赖,欢迎选用。如果觉得直接把这么多域名加在 /etc/dnsmasq.conf 里不爽的话,可以在 dnsmasq.conf 里把 conf-dir=/etc/dnsmasq.d 这一行取消注释,然后把在 /etc/dnsmasq.d 里弄点列表。比如我就是把 @felixonmars 维护的列表放在 /etc/dnsmasq.d/china.conf 里。

配置好之后,保存,Ubuntu 可用 sudo service dnsmasq restart,Arch Linux 可用 sudo rc.d restart dnsmasq 重启 dnsmasq。如果没有错误的话,这时本地的 dnsmasq 已经跑起来了。

测试 dnsmasq

测试一下:

wzyboy@vermilion:~$ dig www.taobao.com @8.8.8.8 +short

www.gslb.taobao.com.danuoyi.tbcache.com.

scorpio.danuoyi.tbcache.com.

119.167.195.251 → 这是淘宝的青岛联通的服务器,我用江苏电信连奇慢无比

119.167.195.241 → 这也是青岛联通

wzyboy@vermilion:~$ dig www.taobao.com @127.0.0.1 +short

www.gslb.taobao.com.danuoyi.tbcache.com.

scorpio.danuoyi.tbcache.com.

222.186.49.251 → 解析到常州电信了,快!

61.155.221.241 → 这是上海电信

wzyboy@vermilion:~$ dig twitter.com @127.0.0.1 +short

199.59.150.7 → Twitter 还是用 8.8.8.8 解析的,所以解析出来是未经污染的正确地址

199.59.148.82

199.59.149.230

效果很明显,这时可以把本地的 DNS 设为 127.0.0.1 了。大部分 Linux 用户直接更改 /etc/resolv.conf 的内容为

nameserver 127.0.0.1

即可。Ubuntu 12.04 及以后的用户,可能需要对 resolv.conf 做一些手脚,具体参考这里。如果不愿意改的话,可能每次联网都要手工改一次 resolv.conf,或者在 NetworkManager 中手工指定 127.0.0.1 为 DNS。DHCP 用户的话,可以通过 /etc/resolv.conf.head 之类的文件来保证 127.0.0.1 在第一行。

这样配置完之后,如果你没有在 dnsmasq 里限定查询 IP,那么你的家人、朋友们也是可以把你的电脑作为 DNS 服务器的。如果你本地是 VPN 全局翻墙的话,需要把你选择的国内 DNS 服务器通过路由表加入直连的范围内。当然,已经使用 chnroutes 的就不需要了。

五、我不是 Linux 用户怎么办?

如果你是 Windows 用户

参考这个问题,去配个 BIND9 的 Windows 版本试试吧。或者可以装个 dnsmasq 的 Windows 代替品。

如果你是 Mac OS X 用户

Mac OS X 的 resolver 比较独特,似乎有比较简陋的解决方法,参考这篇文章。另外,OS X 似乎也是自带 named 的,所以……

其实还有更通用的方法

听说过 VirtualBox 吗?开源、免费、强大的虚拟机软件。可以装个最配置非常低下的虚拟机,比如 32 MiB 内存甚至 16 MiB 内存的虚拟机(要知道 64M 内存的 Linux 已经可以跑 WordPress 这庞然大物了),装个最简单的小 Linux,比如只有 37M 的 Ubuntu Core,然后装上依赖包几乎没有的 dnsmasq,再把 Windows / OS X 的 DNS 设为虚拟机的 IP 地址,于是便可以用了。在当今内存动辄 4 GiB 的情况下,拿 16MiB 内存出来换个更舒畅的上网体验,还是很不错的。

六、尾声

祝各位读者折腾成功,上网愉悦。

补充:其实这样本地 DNS 缓存服务器,还有这样的好处:

wzyboy@vermilion:~$ dig wzyboy.im

;< <> > DiG 9.9.1-P2 < <> > wzyboy.im

;; global options: +cmd

;wzyboy.im. IN A

wzyboy.im. 103 IN A 198.244.51.13

;; Query time: 307 msec

;; SERVER: 127.0.0.1#53(127.0.0.1)

;; WHEN: Thu Sep 6 21:32:07 2012

;; MSG SIZE rcvd: 54

wzyboy@vermilion:~$ dig wzyboy.im

;< <> > DiG 9.9.1-P2< <> > wzyboy.im

;; global options: +cmd

;wzyboy.im. IN A

wzyboy.im. 95 IN A 198.244.51.13

;; Query time: 2 msec

;; SERVER: 127.0.0.1#53(127.0.0.1)

;; WHEN: Thu Sep 6 21:32:15 2012

;; MSG SIZE rcvd: 43

看出来了吧?

本文原载于 wzyboy’s blog,转载请注明本文地址: https://wzyboy.im/post/874.html ,谢谢合作。

(0)

相关推荐

  • 访问网站403错误 Forbidden解决方法

    403错误是访问网站过程中,常见的错误提示,资源不可用或者是服务器不处理.下面我们就来说说访问网站403错误 Forbidden解决方法 操作方法 01 403 Forbidden是http协议中的状 ...

  • win10系统下谷歌Chrome浏览器访问不了微软网站的原因及解决方法

    Win10系统下,用户使用谷歌Chrome浏览器访问微软网站过程中,遇到了无法连接的情况,包括微软主站和附属的应用商店等.这该怎么办呢?下面我们的小编就介绍该问题的解决方案. 原因分析: 其实,该情况 ...

  • 国外网站打不开解决方法

    相信很多小伙伴在浏览国外网站时都会遇到打不开的情况,那么我们怎么解决呢?下面小编就来为大家具体介绍.具体如下:1. 首先,进入任意一个打不开的国外网站.2. 在网站页面中,注册一个新账号.3. 页面中 ...

  • Win7本地连接IPV4无访问权限的解决方法

    有很多用户在使用Win7电脑上网的时候,突然就不能上网了:查看本地连接的时候发现本地连接IPV4无网络访问权限.出现这样的问题,我们应该怎么去解决呢?现在小编就和大家说一下Win7本地连接IPV4无访 ...

  • win10正式版升级后自动弹出你要以何方式打开此网站的原因及解决方法

    当用户将Windows10系统升级为正式版之后,遇到了自动弹出“你要以何方式打开此网站?”的提示,该怎么办?下面我们的小编就整理了 win10正式版升级后自动弹出你要以何方式打开此网站的原因及解决方法 ...

  • win8.1系统IE11访问工行网银提示网站出具的安全证书是为其他网站地址颁发的解决方法

    win8.1系统使用IE浏览器访问工行网银,当点击个人网银的“登录”却弹出提示“此网站出具的安全证书是为其他网站地址颁发的”怎么回事呢?如何解决此问题呢?下面我们的小编和大家分享具体的解决方法,有需要 ...

  • Win7宽带连接正常却无法访问网络的解决方法

    我们在上网的过程中经常会遇到各种各样的问题,大问题小问题比比皆是,有些不影响操作的问题我们忽略就行,但是影响到电脑正常使用的就是大问题了,必须得找到问题的解决方法才行,比如说win7电脑正常连接宽带但 ...

  • Win7打开网页遇到DNS无响应情况的原因和解决方法

    解决方法如下: 1.遇到这种情况,首先是先看看其它人的电脑或手机等设备连接网络是否正常,是否能打开网站.如果其它设备也都打不开,那当然是网络有问题了.否则就是电脑有问题了,这时首先尝试重启下电脑; 2 ...

  • Win7系统中双击U盘提示拒绝访问的有效解决方法

    当我们使用U盘的过程中难免会碰到一些问题,特别是双击U盘的时候出现无法访问的故障应该是比较常见的吧,出现这样的原因有很多,可能是电脑中毒了或者是U盘出现问题了,只要修改一下注册表就可以了哦,跟大家分享 ...