使用 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

文章写的好,软件不会用。

==========

 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:UsersAdmin>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:UsersAdmin>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

DNS 转发器
可以将 UDP 形式的 DNS 数据包,以 TCP 形式转发至指定的 DNS 服务器(默认为 Google DNS 8.8.4.4)。
因为听说 TCP 的 DNS 数据包不会被污染,于是做了这么个玩意,省得改系统文件了。

文件列表:
dnsforwarder.exe        主程序文件

使用方法:
直接打开 dnsforwarder.exe,如果没有自动退出,最小化就可以了。然后将系统的 DNS 设置为 127.0.0.1。
可能还需要重新连一下网。

在命令提示符中执行 “nslookup www.google.com 127.0.0.1”可以看到效果。

如果需要指定 DNS 服务器的话,那么在执行的时候加上一个参数就可以了,比如:

dnsforwarder.exe 203.80.96.10

最近 Google DNS 被干扰的比较厉害,出现很多错误,请指定其它 DNS。

软件很好用!
==========

以前还写过一些方法,可以查看 http://igfw.tk/archives/2960 (几个防止DNS污染的方法)

目前GFW对VPN或SSH代理服务域名大量进行DNS污染,无论是免费VPN还是收费VPN都大面积遭受GFW DNS污染,所以防止DNS污染是很有必要的。

本文由自动聚合程序取自网络,内容和观点不代表数字时代立场

定期获得翻墙信息?请电邮订阅数字时代