Total Pageviews

Wednesday, 6 March 2013

Tcp-DNS-proxy

建议先读相关帖子:http://briteming.blogspot.com/2012/11/tcp-dns-proxydns.html

-----------------------

How to use this python script ?

  1. change your dns server to 127.0.0.1 $ vi /etc/resolve.conf
    nameserver 127.0.0.1
  2. restart the network $ sudo /etc/init.d/networking restart
  3. run the script $ sudo python tcpdns.py

    from https://github.com/henices/Tcp-DNS-proxy 
windows下的程序为http://opengg-clean-player.googlecode.com/files/tcpdns.zip,
https://github.com/binyuj/binyuj/raw/master/tools/Tcp-DNS-proxy/tcpdns.exe
Windows用户如果不想安装这么多东西或者不会安装,可以下载过来,直接运行tcpdns.exe即可,同时提供一个使用goagent的taskbar修改出来的托盘代理-
https://github.com/binyuj/binyuj/raw/master/tools/Tcp-DNS-proxy/tcpdns-taskbar.exe,使用tcpdns-taskbar.exe启动可使程序在托盘中运行。


由于众所周知的原因, 某些域名遭受着持续的DNS缓存投毒攻击,DNS污染只对UDP协议的DNS查询有效,对TCP协议的DNS查询无效,我们只需要使用TCP协议来查询DNS就可以了。
在 Windows下,使用nslookup命令时加上-vc参数就可以强制使用TCP协议而不是UDP协议进行DNS查询。例如查询 encrypted.google.com,输入命令nslookup -vc encrypted.google.com 8.8.8.8进行DNS查询就可以得到正确的查询结果。但是这种方式很不方便,除非把结果加入系统hosts,否则没法用。
Tcp-DNS-proxy通过在本地搭建一个DNS服务器,本地DNS服务器使用TCP协议与上游服务器进行查询,可以避免被干扰。Tcp-DNS-proxy支持解析AAAA地址,IPv6环境下,使用这个之后可以直接看youtube视频。配合https可访问谷歌服务。
使用:
安装python dnspython, gevent 为可选安装。 下载Tcp-DNS-proxy,使用python tcpdns.py 运行 tcpdns.py。把系统DNS设置为127.0.0.1
 缺点:可能导致部分国内网站载入慢,因为使用的是境外DNS服务器,国内DNS服务器都被污染了,要不然也就不需要这东西了
------------------------------------

使用基于TCP的DNS解析服务,防止DNS污染


本文通过使用开源项目tcpdns帮助读者使用纯净的DNS服务。本文所提供的方案试图解决如下问题:
* 大多数ISP网络中(避免使用代理,并高速的)访问被封锁的、有SSL而没被IP封锁的网站,其中比较著名的网站包括(Facebook, Google全系列服务, Youtube)。
* 防止你的ISP通过DNS投毒插入广告
如果您对原理知识不感兴趣,您可以直接跳转到下面了解具体的使用方法。

DNS污染

在之前的文章中已经讲过关于DNS污染的相关问题,这里大概复述一下。DNS污染的主要症状是解析出的IP地址明显不合法,用浏览器访问时显示连接 超时或找不到服务器。DNS污染的主要手段是ISP或GFW发现非法DNS请求时,冒充正常的DNS服务器发送错误的解析结果。

DNS污染的传统对策分析

应对DNS污染的传统对策包括:使用VPN、代理服务器、SOCKS5a标准端口转发等通用翻墙方法,以及修改Hosts文件的方法。同样,在 CERNET2中的同学们也会使用hosts文件访问IPv6网站。以上方法的内在原理在于,通过可靠的信道获取正确的DNS信息,防止DNS污染。
传统对策的弱点在于:
1. 使用通用翻墙方法浪费大量代理服务器的带宽,事实上受污染的只有DNS数据,而代理服务器、VPN等通用翻墙方式将所有信息全部加密或通过代理转发。使用此方法的代价是传输速率的下降,以及严重依赖代理服务器的状态,设置复杂且容易出错。
2. 使用hosts文件方法事实上相当于自己构建了一个保留了“纯净”DNS信息的DNS服务器副本。这种方法灵活性非常差,而且使用不甚方便。如果要在不同网络状况下切换,每次都需要对hosts文件进行修改。

应对DNS污染的新思路

通过分析发现,DNS污染之所以实现,是因为客户DNS请求使用UDP协议与服务器通信。UDP协议作为一个无连接协议,容易被中间人植入信息,并且难以被发现。GFW使用这个原理,冒充真正的DNS服务器发送错误的UDP包,从而使客户无法获得正确的IP地址。 同时可以注意到的是,DNS协议同样可以基于TCP协议实现。而由于TCP 协议是有连接协议,植入信息需要动态的对数据流做分析。代价很大因此GFW并没做这么做。因此,如果使用基于TCP的DNS解析服务,就可以应对目前GFW的DNS污染。

解决方案和代码

解决方案

由于大多数操作系统无法设置DNS为使用TCP连接。因此解决方案设计为,在本地设置一个简单的DNS代理,它接受从操作系统发出的DNS请求(基 于UDP),然后向可信的DNS服务器发送内容相同,但基于TCP的DNS请求,获得结果后通过UDP返回给操作系统。在操作系统看来,上述过程完全是虚 拟的。只需要将系统的DNS服务器设置为本机即可。
这个项目 用Python实现了上述方案。在此基础上,项目:
https://github.com/Ronald-Liu/Tcp-DNS-proxy 为了方便更多人,尤其是Linux用户的使用,增加了对IPv6 DNS 的支持和自动修改resolv.conf的功能

使用方法

下载处于ipv6分支下的tcpdns.py 你同样可以下载稳定版的tcpdns.py文件。

Linux用户

使用sudo python tcpdns.py -f tcpdns.json.example启动。如果你使用DHCP,你可能需要手动在Network-Manager里或wicd里将DNS Server设置为127.0.0.1
如果你使用带有OpenRC的系统(如Gentoo, Debian),下载位于ipv6分支下的tcp-dns-proxy(编辑它,将APP_PATH设置为存放tcpdns.py的绝对地址。然后把tcp-dns-proxy 拷贝入/etc/init.d。最后用sudo rc-update add tcp-dns-proxy default使其默认启动。使用命令sudo /etc/init.d/tcp-dns-proxy start可以立即启动程序.

Windows用户

安装Python 2.7环境
双击tcpdns.py
设置系统DNS为127.0.0.1
--------------------------------

在Mac上设置Tcp-DNS-proxy

由于一些莫名其妙的天灾原因,我们的DNS似乎总是傲娇不停,不愿意为我们指向正确的服务器IP呢(原因你懂的,亲!).
具体请在Terminal下尝试以下三条命令,并对比结果就会明白了呢,亲:

1
2
3
$nslookup twitter.com
$nslookup twitter.com 8.8.8.8
$nslookup -vc twitter.com 8.8.8.8

PS:-vc表示强制以TCP协议联系DNS.
如果你看明白了以上,就会知道以下办法的原理了,亲.

1
2
$c

  • 启动后不要关闭终端窗口,将本机DNS设置为127.0.0.1
当然为了方便使用,我们会让Tcp-DNS-proxy在开机时自启动,我们可以用以下办法将其加入开机启动列表:

1
$sudo vim /Library/LaunchDaemons/com.go.tcpdns.plist

将以下代码复制到其中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
        "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.go.agent</string>
        <key>ProgramArguments</key>
        <array>
<string>python</string>
<string>你存放Tcp-DNS的绝对路径/tcpdns.py</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

保存之后,每次开机时就会自动启动Tcp-DNS-proxy了呢,亲!
------------

用本地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

相关帖子:http://briteming.blogspot.com/2012/11/tcp-dns-proxydns.html
-----------------------

搭建无污染的DNS缓存服务器 for MacOS


以前经常为DNS缓存的问题苦恼,比如有的时候早上起来刚上网的时候忘记开OpenVPN了,这时就会被DNS污染,而在开了OpenVPN之后由于有DNS缓存的存在,要经过相当一段漫长的时间才能够清理掉被污染的DNS。所幸后来发现了Tcp-DNS-proxy,这个问题迎刃而解了。但后来时间长了,又觉得每次都要索引DNS太慢了,为了加速网络,我决定在给Tcp-DNS-proxy配一个缓存软件。
在网上搜索一番之后决定使用Dnsmasq,配置简单,功能强大。
如上所述,安装Tcp-DNS-Proxy
配置Tcp-DNS-Proxy
编辑tcpdns.py文件,将ThreadedUDPServer后的53修改为55; => 修改为55是因为Dnsmasq默认为53端口,这样也便于系统使用,为了防止端口冲突,所以需要修改Tcp-DNS-proxy的端口为55。
安装Homebrew
Homebrew的安装方法见http://mxcl.github.io/homebrew/;
安装Dnsmasq


1
2
3
4
5
6
7
$brew install dnsmasq #安装dnsmasq
$sudo cp /usr/local/Cellar/dnsmasq/x.xx/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf 
<=从配置文件模板拷贝新建配置文件
$sudo cp /usr/local/Cellar/dnsmasq/x.xx/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons/ 
<=从启动文件模板拷贝到启动文件配置目录
$sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist 
<=加载启动文件

配置Dnsmasq
编辑/usr/local/etc/dnsmasq.conf,修改server=后为127.0.0.1#55
结尾
最后保存所有配置,重启计算机,如果配置一切无误的话,在Terminal中输入nslookup twitter.com 127.0.0.1就会返回正确无污染的解析,而解析会被Dnsmasq保存在缓存之中,以加速下次解析。现在你就可以将计算机的网络设置里的DNS服务器地址修改为127.0.0.1,开始享受快速而无污染的DNS服务了。