Total Pageviews

Thursday, 10 November 2011

使用TCP方式进行DNS查询以规避DNS污染



什么是 DNS 污染?
广义上的 DNS(Domain Name System)污染是一种让一般用户由于得到虚假目标主机 IP 而不能与其通信的方法,是 GFW 的主要手段之一。其手段又可以分为 DNS 劫持与狭义 DNS 污染两种:
  1. DNS 劫持指的是通过行政手段控制墙内的 DNS 服务器,使其对敏感查询直接返回伪造的错误结果。
  2. 狭义 DNS 污染则是指监控经过 GFW 的 DNS 查询请求,发现敏感查询时抢先向查询客户端返回伪造的错误结果。
体现在最终用户上,出现的现象就是:使用墙内 DNS 服务器必然会遭遇 DNS 劫持,而使用墙外 DNS 服务器又会遭遇 DNS 污染。前者是以行政手段实现的,无法以技术手段规避;而后者则是可以通过技术手段予以规避的。

DNS 污染的原理及应对
原理
注意到如下事实:现行标准中 DNS 查询通常使用 UDP 协议并且没有任何验证机制,并且根据惯例查询者会接受第一个返回的结果而抛弃之后的。
因此 GFW 只需监控 53 端口(DNS 标准端口)的 UDP 查询数据报并分析,一旦发现敏感查询,则抢先向查询者返回一个伪造的错误结果,从而实现 DNS 污染。
应对
针对上述原理,可以提出很多针对的应对方法:
  1. 给 DNS 查询协议增加验证机制:DNSSEC。这是最根本的解决方法,但是目前支持 DNSSEC 的服务器及客户端都还没有普及,希望在不久的将来能够用上。
  2. 尝试在返回的查询结果辨认出伪造结果并予以抛弃:最简单的方法是抛弃第一个接收到返回结果而使用第二个,稍复杂一点的方法可以接收多个返回结果然后观察统计结果,等等。
  3. 根据 RFC 1035,DNS 查询除了 UDP 协议之外,也可能通过 TCP 方式进行,而 TCP 协议是无法被伪造返回结果的,因此可以通过 TCP 方式的 DNS 查询来规避 DNS 污染。
其中,2 3 两种方法都较易实现,而后者更为可靠,因此接下来介绍方法 3 的实现。
使用 TCP 方式 DNS 查询规避 DNS 污染的具体实现
准备
RFC 1035 4. Messages 一节记载了 DNS 查询请求的数据格式,及 UDP 与 TCP 两种协议的发送格式。
设计
总的来说,需要设计的是一个 DNS 转发器,其工作流程如下:
  1. 接收客户端的 UDP 协议 DNS 查询请求
  2. 将 UDP 查询转换成 TCP 查询并转发给墙外的某支持 TCP 协议的服务器,如 Google Public DNS ( 8.8.8.8 , 8.8.4.4 ), Ordns.he.net ( 2001:470:20::2 )
  3. 接收服务器通过 TCP 协议返回的查询结果
  4. 将查询结果换成 UDP 协议格式并返回给客户端
理论上,有了这样一个转发器之后,将其部署在一个墙内的机器上(方便起见通常可以部署在客户端本机),并将客户端的 DNS 服务器设为该机器就可以绕开 GFW 的 DNS 污染了。
实现
大概半年前用 Java 写过一个简单实现,虽然代码简陋,但使用至今也没有发现大的问题,现共享出来,权作抛砖引玉,欢迎完善或者提出更好的想法。
注:可执行文件在 64 位 Win7 下生成,不保证其他系统可用
参考资料
  1. 深入理解GFW:DNS污染
  2. RFC 1035
来源http://wordpress.pinepara.info/tech/avoid-dns-pollution-using-tcp
文章写的好,软件也很用。
安装Java后,运行dnsserver.jar(后台运行),设置本机DNS服务器为127.0.0.1即可。
==========
 DNS 转发器 UDP to TCP 解决 DNS 污染
DNS 转发器
可以将 UDP 形式的 DNS 数据包,以 TCP 形式转发至指定的 DNS 服务器(默认为 Google DNS 8.8.4.4)。
因为听说 TCP 的 DNS 数据包不会被污染或者被伪造,于是做了这么个玩意,省得改系统文件了。
下载链接:http://www.upload-drive.com/file/1000870/dnsforwarder-zip.html
有一个办法就是将首选 DNS 设为 127.0.0.1,将候选 DNS 设为其他,这样当 DNS 转发器没有启动时也不会影响正常使用。
这是直接通过 8.8.8.8 进行的查询(存在 DNS 伪造):
 C:\Users\Admin>nslookup twitter.com 8.8.8.8
服务器:  google-public-dns-a.google.com
Address:  8.8.8.8非权威应答:
名称:    twitter.com
Addresses:  37.61.54.158
159.106.121.75
这是通过转发器进行的查询:
C:\Users\Admin>nslookup twitter.com 127.0.0.1
服务器:  localhost
Address:  127.0.0.1
非权威应答:
名称:    twitter.com
Addresses:  199.59.148.82
199.59.148.10
199.59.149.198
这是使用 http://www.kloth.net/services/nslookup.php 进行的查询:
DNS server handling your query: 8.8.8.8
DNS server’s address: 8.8.8.8#53
Non-authoritative answer:
Name: twitter.com
Address: 199.59.148.10
Name: twitter.com
Address: 199.59.149.230
Name: twitter.com
Address: 199.59.148.82
来源http://micasmica.blogspot.com/2011/08/dns.html
软件很好用!
目前GFW对VPN或SSH代理服务域名大量进行DNS污染,无论是免费VPN还是收费VPN都大面积遭受GFW DNS污染,所以防止DNS污染是很有必要的。
下载:http://sharesend.com/ddszb

第一个软件是解包后是.jar格式,也就是JAVA可执行文件,得装JRE。
如果图标变成winrar压缩包的样子,那是winrar自作多情跟.jar格式关联了,取消即可。
第一个软件运行后,将您的主DNS设置成127.0.0.1即可使用。
要知道这个jar是不是成功运行了,只要打开任务管理器,若发现有javaw.exe这个进程出现了,就说明它在运行了。不过这个占用的内存有点多,20多MB甚至30多MB都有可能。
要知道这个jar是不是真的起作用了,就在命令行窗口中输入nslookup twitter.com (这个域名可换为其它在中国不能正常解析的域名用于测试),然后看返回结果中是不是列出你的dns服务器是127.0.0.1,如果是,说明它已经成功了。
顺便来点试用心得:
XP sp3,用上了之后可明显感觉到很多国外网站载入的速度提升,尤其是国外的博客、资源网站等(因为这些网站你打开一张网页就可能查询很多个不同的国外域名比如嵌在页面的广告、侧边栏、统计插件等),因为没有dns污染了,打开网页需要的全部域名查询请求都会飞速完成。
Win7 sp1 x64,我用了这个之后情况很不好,查询域名比用本地ISP的DNS服务器还慢,而且一切IPv6站点都提示域名查询失败,不知道是不是个案。

恩, 本机DNS已经设为127.0.0.1了, 按你提供的方法测试, 已经起作用.
我的是Win7 SP1 X64, 确实是用了dsserver.jar后, IPv6都连接失败, 应该是这软件为支持IPv6吧.为了减少被污染, 先用着IPv4了 。

No comments:

Post a Comment