2014年7月5日星期六

翻墙教程之DNSCrypt+unbound

翻墙教程之DNSCrypt+unbound

介绍

最近没写什么文章,在家呆久了状态时好时坏,很是纠结,日记、冥想、锻炼时断时续……有点偏了>_<。还是说说GFW吧,GFW的主要屏蔽手段有三种,一是DNS污染、二是IP封锁、三是关键字过滤。其中DNS污染是最基础也是应用最广的一种,如果能够解决DNS污染问题,90%的网站我们都可以正常访问了。其应对方法一般是将从域名服务器解析得到的正确的域名-IP对放到本地电脑的hosts文件中,这样一来在访问相应的网站时,就不需要在去域名服务器查询了,因为在我们自己的电脑中已经有了相关的记录。
这种方法的优点是速度快,不需要再去域名服务器查询。缺点是必须人工维护hosts文件,如果一个网站的服务器改变了,并且hosts文件没有随之更新就会无法造成无法访问。通常都是做不到实时更新hosts文件的,而且也不可能将所有被DNS污染的网站都存放到hosts中,一般只有一些热门的被GFW的网站,其他相对冷门的网站就需要使用其他的方法了。而DNSCrypt-proxy+unbound可以做到动态解析,配置好之后与正常上网无异,以后再也不用担心hosts文件怎么还没有更新的问题啦。
由于DNS查询一般是使用的不可靠的UDP传输,所以给了GFW可乘之机,而DNSCrypt-proxy和unbound可将查询DNS的过程加密或使用可靠的TCP传输。DNSCrypt-proxy可以指定特定的DNS服务器并将与服务器传输的信息加密(并不是所有服务器都支持加密),unbound可以使用可靠的TCP传输并将解析到的结果缓存到本地。因为DNSCrypt使用的是海外服务器,查询最快也需要200ms左右,如果你不想每次点击网页都增加200ms,那么unbound缓存必不可少(首次解析可能会高一个数量级)。

安装与配置

怎么安装我想不用多说了吧,ubuntu上有unbound的包,而DNSCrypt-proxy只能从源码编译。两个软件都均支持跨平台,linux与windows版都有,其中DNSCrypt还支持ios和android,官网与下载地址如下:
两个网站上都有详细的安装说明,需要注意的是DNSCrypt需要安装libsodium。
windows上DNSCrypt可以直接作为服务安装,而linux上如果需要开机自启动则需要特别的配置。配置方法如下:
#首先创建DNSCrypt的用户和用户组
sudo adduser --system --quiet --home /run/dnscrypt --shell /bin/false --group --disabled-password --disabled-login dnscrypt

#再将下面两条命令添加到/etc/rc.local中
mkdir /run/dnscrypt
/usr/local/sbin/dnscrypt-proxy --provider-key=8768:C3DB:F70A:FBC6:3B64:8630:8167:2FD4:EE6F:E175:ECFD:46C9:22FC:7674:A1AC:2E2A --provider-name=2.dnscrypt-cert.ns2.jp.dns.opennic.glue --resolver-address=106.186.17.181:2053 --local-address=127.0.0.1:40 --daemonize --user=dnscrypt
其中--provider-key是与服务器验证用的,--provider-name--resolver-address都是指明使用的是哪台服务器,--daemonize是以守护进程启动,--user=dnscrypt是以dnscrypt用户启动。--local-address=127.0.0.1:40是在本地的40端口启动DNSCrypt,默认的DNS服务端口53需要让给unbound。DNSCrypt官网上提供了多个服务器地址,依次尝试过大部分其中上面的这个日本的服务器速度最快并且受GFW影响最少,但缺点该服务器没有缓存国内大多数网站,需要继续向上迭代查询花费时间较长,不过这个缺点可以使用unbound解决。另外虽然还有两个澳大利亚的服务器也很快,但是其返回的地址是根据地理位置进行优化过的,比如plus.google.com解析到CNAME里就带有china,这些地址可能受到GFW特别照顾,导致网站无法正常打开。
配置好DNSCrypt后再将本地的DNS改为127.0.0.1,linux用户可以直接将/etc/resolv.conf里的配置改为nameserver 127.0.0.1,windows用户也需要做相应的修改,上面的DNSCrypt启动时的选项也是。然后再将unbound的配置文件/etc/unbound/unbound.conf中添加以下信息就可以正常工作了:
1
2
3
4
5
6
#下面这条添加到原有的server小节末尾
    do-not-query-localhost: no
 
forward-zone:
    name: "."
    forward-addr: 127.0.0.1@40

优化

DNSCrypt没有什么可以优化的,主要是unbound的优化。先将我自己的配置文件贴出来再慢慢讲解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
server:
    verbosity: 0
 
    # use all CPUs
    num-threads: 2
 
    # power of 2 close to num-threads
    msg-cache-slabs: 2
    rrset-cache-slabs: 2
    infra-cache-slabs: 2
    key-cache-slabs: 2
 
    # more cache memory, rrset=msg*2
    rrset-cache-size: 100m
    msg-cache-size: 50m
 
    # more outgoing connections
    # depends on number of cores: 1024/cores - 50
    # with libeven no more 1024 limits
    outgoing-range: 450
    num-queries-per-thread: 512
 
    # enable extended statistics.
    statistics-interval: 0
    extended-statistics: yes
    # set to yes if graphing tool needs it
    statistics-cumulative: no
 
    log-time-ascii: yes
    hide-identity: yes
    hide-version: yes
    prefetch: yes
    do-ip4: yes
    do-ip6: no
    do-udp: yes
    do-tcp: yes
    tcp-upstream: yes
    do-daemonize: yes
    module-config: "validator iterator"
    do-not-query-localhost: no
 
forward-zone:
    name: "google.com"
    forward-addr: 127.0.0.1@40
 
forward-zone:
    name: "codeplayer.org"
    forward-addr: 127.0.0.1@40
    forward-addr: 114.114.114.114
 
forward-zone:
    name: "."
    forward-addr: 127.0.0.1@40
    # forward-addr: 208.67.222.222
    # forward-addr: 208.67.220.220
    forward-addr: 8.8.4.4
    # forward-addr: 8.8.8.8
 
remote-control:
    control-enable: no
其中比较关键的是forward-zone和server节中的prefetchtcp-upstream这段。后者是强制开启TCP防止GFW干扰,前者是unbound从哪里转发DNS到本机,forward-addr是转发源的DNS服务器地址,name哪些域名从该地址转发,比如name: "."就是所有的域名,name: "google.com"则是所有的gogle.com的域名。
forward-addr: 127.0.0.1@40的意思就是从DNSCrypt转发,还记得上面我们设置了将DNSCrypt从本地端口40启动吗?还有由于unbound无法在一节中设置多个name,所以必须将不同的name分成多个forward-zone节。另外在一节中配置多个forward-addr的情况,由于不清楚unbound程序内部使用的什么算法,经过几次测试推测是使用的先返回的DNS服务器。
另外server节一中还配置了一些性能和静态缓存的优化,不过我们只是在自己电脑上使用,不会有太大的流量,所以一般也不需要配置这些,感兴趣的可以看unbound官网上的资料。由上面的配置可以看出,我将大多数域名都设置为从8.8.4.4解析,因为8.8.4.4服务器的国内网站DNS缓存比较全,所以速度比较快。而只有google.com的域名使用了DNSCrypt加密传输,由8.8.4.4解析到的google部分服务的CNAME也带有china,所以无法正常访问。
如果使用了unbound却不能正常打开网页,尝试删掉原配置中的auto-trust-anchor-file: "/var/lib/unbound/root.key"试试。

总结

可以看出大部分域名解析其实不需要DNSCrypt就能完成了,unbound自带的强制TCP功能就可以满足大部分需求了,想要偷懒的不需要安装DNSCrypt也是可以的。DNSCrypt比unbound更加安全,不过缺点是不能缓存解析到的DNS,而且也只有少数的服务器支持DNSCrypt。
防止有人不知道,最后我再罗嗦两句。我们已经解决了DNS污染的问题,那么如果遇到了IP封锁与关键字过滤又该怎么办呢?如果所访问的网站支持https,则只要使用https访问就可以轻松破解关键字过滤的问题了,很多浏览器都有强制开启https的插件。如果遇到了IP封锁或网站不支持https,那么就需要goagent了,详情见这里:https://code.google.com/p/goagent

参考文章

没有评论:

发表评论