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

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

  一为什么要用国外 DNS

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

  wzyboy@vermilion~$ dig twittercom @ +short

  

  

  

  wzyboy@vermilion~$ dig twittercom @ +short

  

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

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

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

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

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

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

  ;; 使用 解析 wwwgooglecom 耗时 毫秒

  ;; Query time msec

  ;; SERVER #()

  ;; WHEN Thu Sep ::

  ;; MSG SIZE rcvd

  ;; 使用中国电信 服务器解析 wwwgooglecom 耗时 毫秒

  ;; Query time msec

  ;; SERVER #()

  ;; WHEN Thu Sep ::

  ;; MSG SIZE rcvd

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

  三问题的解决思路

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

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

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

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

  四安装及配置 dnsmasq

  安装 dnsmasq

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

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

  配置 dnsmasq

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

  noresolv

  nopoll

  server=

  server=

  server=/cn/

  server=/taobaocom/

  server=/taobaocdncom/

  server=/tbcachecom/

  server=/tdimgcom/

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

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

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

  测试 dnsmasq

  测试一下

  wzyboy@vermilion~$ dig wwwtaobaocom @ +short

  wwwgslbtaobaocomdanuoyitbcachecom

  scorpiodanuoyitbcachecom

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

   → 这也是青岛联通

  wzyboy@vermilion~$ dig wwwtaobaocom @ +short

  wwwgslbtaobaocomdanuoyitbcachecom

  scorpiodanuoyitbcachecom

   → 解析到常州电信了快!

   → 这是上海电信

  wzyboy@vermilion~$ dig twittercom @ +short

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

  

  

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

  nameserver

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

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

  五我不是 Linux 用户怎么办?

  如果你是 Windows 用户

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

  如果你是 Mac OS X 用户

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

  其实还有更通用的方法

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

  六尾声

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

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

  wzyboy@vermilion~$ dig wzyboyim

  ;< <> >DiG P< <> >wzyboyim

  ;; global options +cmd

  ;wzyboyim IN A

  wzyboyim IN A

  ;; Query time msec

  ;; SERVER #()

  ;; WHEN Thu Sep ::

  ;; MSG SIZE rcvd

  wzyboy@vermilion~$ dig wzyboyim

  ;< <> > DiG P< <> > wzyboyim

  ;; global options +cmd

  ;wzyboyim IN A

  wzyboyim IN A

  ;; Query time msec

  ;; SERVER #()

  ;; WHEN Thu Sep ::

  ;; MSG SIZE rcvd

  看出来了吧?

  本文原载于 wzyboy’s blog转载请注明本文地址谢谢合作

自己不喜欢的人,可以报之以沉默微笑;

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

相关文章:

你感兴趣的文章:

标签云: