起因是我这(beijing urban network co. ltd)把DNS服务器改为8.8.8.8或者8.8.4.4的时候就无法使用了,表现为发出DnsQuery后没有任何响应,猜测大概是GFW搞的鬼 吧。唔。。。不管是不是反正这黑锅都让GFW来背,呵呵。

默认情况下Windows的DNS交互使用UDP协议承载,于是抱着试试的心理尝试了一下用TCP来发送DNS请求,结果Google DNS很给力的返回了结果。
接下来的工作就是怎样让Windows用TCP来发送了。悲催的是翻了一遍组策略,网络连接属性等等都没找到哪个选项可以让Windows发送 TCP的DNSQuery,也不知道是真没有还是没找到。没办法只好自己动手丰衣足食啦,分析后发现判断用UDP或TCP的关键位置在 DnsApi.dll中,修改之,覆盖,重启,用Wireshark看到发送的都是TCP的DNS请求,目前除了nslookup工具,其他使用一切正 常,用nslookup发出的请求不受影响,默认还是UDP的,反正不影响上网,无视了。
提一下用的系统是Win7 Ultimate,版本号 6.1.7601
DnsApi.dll版本号为6.1.7601.17570
.text:6DC08FC8 8B 46 10        mov     eax, [esi+10h]
.text:6DC08FCB 89 45 F4        mov     [ebp+var_C], eax
关键代码,此处让var_C值为2即可,这里给出我的修改方法
85A0: 90 90 90 90 90 -> 33 C0 40 EB 25
85C8: 8B 46 10 -> EB D6 40
 
后记:
测试了一下似乎也能绕过GFW的DNS投毒
测试方法:
1. 用UDP协议dig www.google.com,没有任何返回
2. 仍用UDP协议dig www.twitter.com 有返回结果,不过给的IP地址不正确,是随机值
说明GFW的DNS投毒在拦截DNS请求之前,下面看看TCP协议请求的实验结果
1. 用TCP协议dig www.google.com 返回正确IP
2. 用TCP协议dig www.twitter.com 也返回了正确的IP
均返回了正确结果,看来GFW的DNS劫持目前还仅限于UDP协议,对于TCP协议则没有过滤:)
不过这仅是我这里的情况,还不知道是否在其他网络中也适用,如果不适用说明GFW可以根据不同的运营商或者地区来部署不同的版本。那就比较恶心了。
附上修改后的DnsApi.dll
Size: 270,336 bytes
MD5Sum   : c2e583928d087a631cff925e27a5edb4
Download :  http://www.bingtech.net/wordpress/?download=dnsapi_dll
from:http://www.bingtech.net/wordpress/?p=233
------------------------------------------------------------------------
不太推荐上文的方法。 在本地开一个dns代理,然后用tcp2udp
(项目地址: https://github.com/lp0/dns-tcp2udp,下载地址:
https://nodeload.github.com/lp0/dns-tcp2udp/zipball/master,仅限linux desktop os 使用),专为本机服务,这样可以不必费力给系统打补丁。
------------------------------------------------------------------------
可以在linux和windows xp上强制使用tcp解析dns的python脚本

http://min.us/mvoilIn
http://k.min.us/ie91M.7z
在linux上使用tcp dns防止dns污染

看了某篇文章,对tcp dns开始感兴趣,于是动手写了一个小脚本
可以把udp和tcp的dns请求全部转换到tcp发送到dns服务器

使用方法:
使用sudo或者root下执行python tcpdns.py
(绑定1024以下的端口需要root权限)
然后把本机dns设为127.0.0.1
需要安装python和python-twisted-core

dns设置方法:
在/etc/resolv.conf中添加nameserver 127.0.0.1

注意:
默认dns为8.8.4.4 可自己打开脚本修改

其他:
为保证安全性在绑定端口后会把脚本降低权限,默认为os.setuid(1000)
使用前请检查当前用户的uid是否为1000然后做出修改,在/etc/passwd中可以查到

在xp上也可以使用,需要安装python、twisted和zope,可以在以下地址中下载
http://www.python.org/
http://twistedmatrix.com/trac/wiki/Downloads
http://pypi.python.org/pypi/zope.interface#download
-----------------------------------------------------------------------

用本地DNS代理防止DNS 缓存投毒攻击

解决方案: 在本地开设DNS 代理服务器. 本地DNS 服务器与上游DNS 服务器之间通过TCP 协议进行查询, 将结果通过UDP 协议返回给本机客户端, 这样就不会被旁路干扰.
使用方法:
1. 安装好python 后打开Tcp-DNS-proxy , 下载tcpdns.py 运行;
2. 在命令行下运行 netstat -an 检查是否存在 UDP 127.0.0.1:53 结果
3. 修改网络设置, 将DNS 服务器改成 127.0.0.1
4. 在命令行下运行nslookup www.Twitter.com , 应该能得到正确的结果
服务器: UnKnown
Address: 127.0.0.1
非权威应答:
名称: Twitter.com
Addresses: 199.59.149.230
199.59.150.7
199.59.148.82
Aliases: www.twitter.com
注. 如果Windows 用户不想 安装python, 可以下载打包好的exe 程序包, 运行tcpdns.exe
----------------------------------------------------------------------------------------------

试试Python写的tcpdns.py吧,下载地址
http://pydnsproxy.googlecode.com/issues/attachment?aid=110006000&name=tcpdns.py&token=67aa134641497bc8a93fe250d1879a31
需要安装Python2.7,Twisted,zope.interface-3.6.3
参考网址:https://code.google.com/p/pydnsproxy/issues/detail?id=11

pydnsproxy—-忽略GFW的DNS缓存污染

用Python写的一个小程序,用了个非常简单的方法来忽略GFW的DNS缓存污染(暂不公布方法)。使用方法如下:

Windows

1. 下载pydnsproxy,安装在你喜欢的位置。(注:Windows Vista/7 的用户请使用管理员模式安装)
2. 将宽带连接(或者其他你喜爱的名字的连接)的dns服务器设置为127.0.0.1
3. Enjoy it!

备注

1. 本软件默认使用OpenDNS的DNS服务器,如果你喜爱其他的境外DNS服务器,请修改主目录下的dnsserver.conf文件。(不知道的话请用Google搜索,注意别设成境内的了,不然就又回到祖国妈妈的怀抱了)
2. 修改dnsserver.conf后,请在控制面板->管理工具->服务中重启DNSProxy服务。
3. exe只是简单的7zip打包,如杀毒软件报告病毒应属误报。提供两个在线扫描结果:VirusTotalVirScan

Linux、Mac

目前没有针对Linux和Mac的包,但可以到SVN里把py的源码checkout下来,除需要手动设置外,使用方法类似于Windows。

什么是DNS缓存污染?参见维基百科的这篇条目
DNSProxy只提供绕过DNS缓存污染的功能,而不能为你解决连接被重置的问题,更不能为你提供代理服务器翻墙。其他业务,请查询GAppProxy
既然不能翻墙,为什么开发这个工具?要知道能解决DNS缓存污染也能对付掉一部分GFW的封锁。比如说你可以使用IPv6,如果能解决掉DNS缓存污染,那么GFW在IPv6唯一的封锁手段(现今)也失效了。