众所周知,在我朝局域网当中想要获取国外 DNS 信息,必定会遭到关键字污染。为此,有人想到了使用异常端口,比如5353而不使用 DNS 专用端口53——因为目前 Girl Friend Wall 只污染53;也有人想到了使用 TCP 连接请求,因为 DNS 的应答机制(参考 DHCP)决定了它会接受第一个返回的响应,后边的会被丢弃,而使用 TCP 则强制接受选定的数据包;甚至有人想到了把那些发污染包的 IP 地址收集起来,然后在客户端处过滤——加入黑名单,这样最终就会收到正确的响应包。
总之,这些都不是什么长久之计,使用 OpenDNS 出品的 dnscrypt 是一个不错的选择,它在 DNS 的基础之上增加了加密的选项,让你的 DNS 请求能够像使用 ssl 一样加密地请求服务器,这样便从根本上杜绝了 DNS 污染问题。
那么问题来了,就算你是用了 dnscrypt,可是服务器 IP 被认证了呢?答案是——这就是最近 dnscrypt 越来越不给力的原因。另外,OpenDNS 虽然捣鼓出了这么个给力的玩意儿,但是他们却没有公开服务端——也就是说你必须使用那有限的几个国外的服务器,速度绝对快不到哪里去。
所以,我朝有大神根据 dnscrypt 的客户端写出了牛逼闪闪的服务端——dnscrypt-wrapper!
我们现在可以自己在境外服务器搭建一个 dnscrypt 服务器,本地来连接就好了——你可以选择一个速度比较快的 vps。
教程开始
作为演示,我这里的服务器是 ubuntu 14.04.
编译安装依赖库文件
dnscrypt-wrapper 依赖 libsodium 和 libevent2;前者一般源里没有,后者一般默认版本不是2而是比较旧的1,我们得先来手动编译这两个库。
我们从这里下载 libsodium 的最新版本 ,截止到本文完成时,最新版本为1.0.2:
cd ~
wget http://download.libsodium.org/libsodium/releases/libsodium-1.0.2.tar.gz
tar xf libsodium-1.0.2.tar.gz
cd libsodium-1.0.2
CFLAGS="-O3 -fPIC" ./configure
make
make install
ldconfig
然后我们从这里下载 libevent2 ,这里我们选择 2.0.22 稳定版:
cd ~
wget https://sourceforge.net/projects/levent/files/libevent/libevent-2.0/libevent-2.0.22-stable.tar.gz
tar xf libevent-2.0.22-stable.tar.gz
cd libevent-2.0.22-stable
./configure --prefix=/usr
make
make install
echo /usr/local/lib > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig
搞定两个依赖库之后,就可以开始编译 dnscrypt-wrapper 啦:
apt-get update && apt-get upgrade
apt-get install git
cd ~
git clone --recursive git://github.com/Cofyc/dnscrypt-wrapper.git
cd dnscrypt-wrapper
make configure
./configure
如果你在 make configure 这一步出错,你可能需要先安装 autoconfig:
apt-get install autoconfig
如果没什么问题,那么就可以开始编译安装了:
make
make install
//安装完成会出现如下提示:
# make install
install -d -m 755 ‘/usr/local/bin’
install -p dnscrypt-wrapper ‘/usr/local/bin’
至此编译完成。
dnscrypt-wrapper 的配置和使用
cd ~
mkdir dnskey
//新建一个目录来存放证书
cd dnskey
dnscrypt-wrapper --gen-provider-keypair
//生成提供商密钥对
这里系统会反馈一个指纹信息,这个信息就是客户端配置时候需要的“provider_public_key”!所以一定要保存好。
类似这个样子:
4298:5F65:C295:DFAE:2BFB:20AD:5C47:F565:78EB:2404:EF83:198C:85DB:68F1:3E33:E952
然后,我们使用命令生成加密密钥对以及生成预签名证书:
dnscrypt-wrapper --gen-crypt-keypair
dnscrypt-wrapper --crypt-secretkey-file crypt_secret.key --crypt-publickey-file=crypt_public.key --provider-publickey-file=public.key --provider-secretkey-file=secret.key --gen-cert-file
这样,dnscrypt-wrapper 就已经准备好了。
使用命令来运行 dnscrypt-wrapper,用“-VV”来显示比较详细的 debug 信息:
cd ~/dnskey
dnscrypt-wrapper -r 8.8.8.8:53 -a 0.0.0.0:5353 --crypt-secretkey-file=crypt_secret.key --crypt-publickey-file=crypt_public.key --provider-cert-file=dnscrypt.cert --provider-name=2.dnscrypt-cert.logcg.com -VV
然后去客户端配置一下:
vi /etc/default/dnscrypt-proxy
#要修改的就只有如下几处,其他注释和配置已略去。
local-address=127.0.0.1:5301
#本地监听地址和端口
resolver-address=128.199.131.196:5353
#远端的服务器地址和端口
provider-name=2.dnscrypt-cert.logcg.com
provider-key=4298:5F65:C295:DFAE:2BFB:20AD:5C47:F565:78EB:2404:EF83:198C:85DB:68F1:3E33:E952
#先前使用dnscrypt-wrapper --gen-provider-keypair命令时候生成的指纹信息。
保存后使用如下命令重启客户端服务,如果你的端口没有被防火墙撸掉,那服务器那边就应该能够看到 debug 信息,表示已经有客户端接入。
service dnscrypt-proxy restart
使用命令来测试一下:
root@MyServer:~# dig -p 5301 twitter.com @127.0.0.1
; <<>> DiG 9.8.1-P1 <<>> -p 5301 twitter.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45379
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;twitter.com. IN A
;; ANSWER SECTION:
twitter.com. 5 IN A 199.16.158.179
twitter.com. 5 IN A 199.16.158.168
;; Query time: 273 msec
;; SERVER: 127.0.0.1#5301(127.0.0.1)
;; WHEN: Wed May 6 19:51:42 2015
;; MSG SIZE rcvd: 72
多次重复命令,发现获取到的 IP 均相同且为真正的正确 IP 地址,服务生效。
创建脚本
每次直接运行命令多少有些不方便,即使使用“-d”来后台执行,一样让人感到不适,我们使用 shell 来创建一个启动 dnscrypt-wrapper 的脚本。
cd ~/dnskey
vi start-dnscrypt-wrapper.sh
#加入以下内容
#!/bin/bash
dnscrypt-wrapper -d -a 0.0.0.0:5353 -r 8.8.8.8:53 \
--crypt-secretkey-file=crypt_secret.key \
--crypt-publickey-file=crypt_public.key --provider-cert-file=dnscrypt.cert \
--provider-name=2.dnscrypt-cert.logcg.com \
--logfile=/var/log/dnscrypt-wrapper.log
以后则只需要使用 sh start-dnscrypt-wrapper.sh 就可以启动了。
——至于关闭嘛,使用命令“killall dnscrypt-wrapper”。
延伸阅读:
https://github.com/Cofyc/dnscrypt-wrapper
http://03k.org/dnscrypt-wrapper-usage.html
编译安装 dnscrypt-wrapper 搭建防污染 DNS 服务器,首发于落格 - logcg.com。