Total Pageviews

Thursday, 7 February 2013

使用 TCP方式 进行DNS查询,以规避 DNS 污染(客户端程序为DnsTransponder)


  1. 狭义 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 污染了。
  • (另外一个作者的代码 : https://github.com/ekenchan/DnsTransponder
参考资料
  1. 深入理解GFW:DNS污染
  2. RFC 1035
我的补充说明:

在mac上。先安装nodejs环境。
git clone https://github.com/ekenchan/DnsTransponder DnsTransponder-by-ekenchan
cd DnsTransponder-by-ekenchan
nano configuration.js
(把config["remoteAddr"]的值改为8.8.8.8)
sudo node dnsserver.js

实际使用例子:

sudo wg-quick up wg0 
sudo networksetup -setdnsservers "Wi-Fi" 127.0.0.1
cd ~/DnsTransponder-by-ekenchan && source ~/.profile && sudo node dnsserver.js
----------------
DNS 转发器 UDP to TCP 解决 DNS 污染
DNS 转发器
可以将 UDP 形式的 DNS 数据包,以 TCP 形式转发至指定的 DNS 服务器(默认为 Google DNS 8.8.4.4)。
因为听说 TCP 的 DNS 数据包不会被污染或者被伪造,于是做了这么个玩意,省得改系统文件了。
有一个办法就是将首选 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