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

2011年11月8日 | 分类: 翻墙相关 | 标签: , ,

使用 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
软件很好用!
==========

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

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

下载:http://sharesend.com/ddszb

  1. 2011年11月21日17:42

    livuerfeifei :经实验发现,用 udp 协议发出 dns 查询的时候,如果数据包的大小在 1000 字节以上的话,就不会受到污染了

    大于 1024 字节的 DNS 查询自动使用 TCP 协议。

  2. 老F
    2011年11月10日13:51

    哎,现在ISP更厉害,连TCP的DNS都能劫持了,我WIN7下用OLLYDBG调试了DNSAPI修改为TCP方式发送,结果收到N多广告推送,都指到了某广告服务器

    • dump
      2011年11月10日15:44

      这个怎么DNSAPI怎么调试,能不能做出一份教程来,教教我们

    • z235689785
      2011年11月10日21:31

      个人认为这个纯属ISP无耻的“用户桌面占领计划”的一部分。其实应该不是TCP的DNS查询请求被劫持了,而是ISP随机拦劫你的TCP数据包并插入东西返回(此流氓技术本来是为给浏览器右下角跳广告框框开发的,估计是歪打正着吧)。对付这个很简单,直接给工信部投诉就OK了

  3. livuerfeifei
    2011年11月9日11:51

    经实验发现,用 udp 协议发出 dns 查询的时候,如果数据包的大小在 1000 字节以上的话,就不会受到污染了

    • iGFW
      2011年11月9日11:55

      那么,这个发现如何应用到防止DNS污染中呢?

      • Dunv
        2011年11月9日16:00

        可以尝试向报文末端填入随机生成的数据强行把数据包胀到1000字节以上,不过这个原理上估计也要采用和本文类似的手段(更改系统文件,或监听udp53拦截本机发出的dns查询数据包)来实现。

        • iGFW
          2011年11月9日16:17

          哦,感谢解答。
          那能编写一个可用的程序实现,分享出来吗?

        • Ben
          2011年11月10日11:23

          这个应该不行吧,DNS查询报文是没有Additional Records的,随机填充数据要写在哪里呢?

  4. Kimi
    2011年11月8日19:39

    最近發現手機上也被污染了. -.-!

    • iGFW
      2011年11月8日23:19

      手机被电脑网络封锁了还要严重,有不少是移动、联通、电信封的

  5. KImi
    2011年11月8日19:37

    如何測試第一個軟件JAVA已經運行, 并已起作用了呢?

    • iGFW
      2011年11月8日23:18

      甚至本机DNS服务器为127.0.0.1了吗?

    • Ben
      2011年11月9日09:28

      第一个软件运行后,将您的主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站点都提示域名查询失败,不知道是不是个案。。。

      • Kimi
        2011年11月10日15:31

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

  6. catdog
    2011年11月8日16:27

    第一个软件是解包后是.jar格式,也就是JAVA可执行文件,得装JRE。

    如果图标变成winrar压缩包的样子,那是winrar自作多情跟.jar格式关联了,取消即可

    • iGFW
      2011年11月8日17:05

      呵呵,谢谢支持,我懂了

  7. catdog
    2011年11月8日16:26

    我用namebench 跟 DNS Benchmark测试了这几个小程序,其中上文第一个(用JAVA写的那个)效率最高,稳定性也最好,推荐使用

    • iGFW
      2011年11月8日16:28

      JAVA写的那个怎么个用法呀?

  8. AS
    2011年11月8日16:09

    scholarzhang
    Intrusion detection evasion and black box mechanism research of the Great Firewall of China
    https://code.google.com/p/scholarzhang/downloads/list
    “Kernet-stable-20111103.pkg kernet stable – mac os x port Featured 4 days ago 4 days ago 30.0 KB …..”

    (“待月西厢下,迎风户半开,隔墙花影动,疑是玉人来。”)

    • Ben
      2011年11月8日16:40

      矮油,西厢记诈尸了,这可是本年度翻墙界头大新闻啊…撒花…

      • AS
        2011年11月8日22:25

        Ist das unnutzlich ?

        (“你好”)

        • Ben
          2011年11月9日09:14

          Ja, für eine Weile war es erfolgreich durch GFW blockiert. Aber jetzt ist es wieder verwendbar.

          (你好 ^_^)