Total Pageviews

Sunday 15 April 2012

用PDNSD + PUBLIC DNS SERVER获得高速正确的dns解析结果

使用pdnsd的目的在于将UDP的DNS请求转换为TCP进行发送,虽然TCP协议的DNS在效率上不及UDP协议,但是可以实现一些UDP很难做到的功能,比如通过Socks5代理端口进行透明代理。所以TCP的DNS在一些领域还是很有市场。

早期的方案一般是使用Pdnsd建立本地的DNS服务器,然后将请求该服务器的UDP请求转换为TCP请求向上游服务器进行发送,同时还可进行DNS缓存,而且可以设置超长时间的缓存时间。更厉害的是,Pdnsd可以设置DNS结果黑名单自动使用备用DNS服务器进行“二次请求”,是应对DNS污染的大杀器。Pdnsd虽然运行很稳定,但是也已经五六年没有好好更新过了,源码可以在https://github.com/SAPikachu/pdnsd上获得
-----------------------

首先必须要感谢Google 因为伟大的不仅是免费提供了8.8.8.8;8.8.4.4这两个dns服务器,而且同时提供了能够以TCP方式解析的Google DNS服务器
摘dnsmasq那一篇的一段: 至于DNS在瓷器国被污染的这回事,不用多解释了,正确的DNS解析对于使用squid透明代理进行翻墙极为重要,因为在squid在收到http请求前,域名已经在客户端先解析了。 

因为以TCP方式查询DNS,不会被GFW污染!
我们来做一个实验:
首先,用 udp方式查询google dns:

再强制用tcp方式查询google dns


看出差别了么, 用tcp方式得到的解析结果完全不同于udp方式的。可悲的是系统默认的dns访问都是用udp进行的。


本文讲解如何利用pdnsd + public dns server做高速并正确的dns解析。


上一篇讲了利用DnsMasq来搭建正确解析的DNS服务器,但是,你有没有发现,dnsmasq并没有起到加速的作用。。。 没过几分钟,dig一下试试,响应时间又特别长了,刚开始的0ms响应时间不见了,又回到几百个ms了,慢,卡又回来了。

为什么?

答案是DNS服务的TTL,下面举例:

注意到了么 twitter.com 后面跟了个数字30,这个数字的单位是秒,也就是说twitter.com域名的A记录再过30秒就过期了,30秒后你就必须再从twitter.com 的SOA(主域名解析服务器)去重新获得twitter.com的解析,dnsmasq发现过期后,就会向你境外的服务器,再去取一次DNS解析。注意, 这次解析的时间是几百毫秒。这就是为什么慢!!!

甚至国内ISP的CDN,也用了很低的TTL值,这就导致了用dnsmasq访问各种网站都极慢。
你不妨dig一下static.t.126.net,或者网易的 img cache什么的。

问题是ISP为什么要用这么低TTL值呢?
答案是负载均衡,CDN可以动态去调整每个服务器的访问量。


你应该猜到了,根据以上分析, 优化dns响应时间,有两个途径:
1. 降低访问远程DNS服务器的时间。
2. 提高TTL值。

途径一,可以通过访问google dns server实现,google dns是目前我这里ping值最低的能正确解析域名的服务器。

途径二,用pdnsd实现。
在mac上,brew install pdnsd

pdnsd 配置如下:
sudo nano /usr/local/etc/pdnsd.conf

global {
        perm_cache=4096;
        cache_dir="/var/cache/pdnsd";
#       pid_file = /var/run/pdnsd.pid;
        run_as="root";
        paranoid=on; 
        par_queries=5; 
        server_ip = 127.0.0.1;  
        server_port = 53;
        status_ctl = on;         
        query_method=tcp_only;  // 仅用TCP查询
        min_ttl=1d;             // 把ttl最小时间提升为一天 (1 day)
        max_ttl=1w;        # One week.
        timeout=10;        # Global timeout option (10 seconds).
        neg_rrs_pol=on;
        udpbufsize=1024;   # Upper limit on the size of UDP messages.
}

# The following section is most appropriate if you have a fixed connection to
# the Internet and an ISP which provides good DNS servers.
server {
        label="opendns";
        ip=208.67.222.222;  #注意:远程dns server的地址不能写成1.2.3.4:2233这种形式。
        port=5353;
        timeout=4;         # Server timeout; this may be much shorter
                           # that the global timeout option.
        uptest=ping;         # Test if the network interface is active.
        proxy_only=on;
        purge_cache=off;   # Keep stale cache entries in case the ISP's
                           # DNS servers go offline.
        edns_query=no;    # Use EDNS for outgoing queries to allow UDP messages
                           # larger than 512 bytes. May cause trouble with some
                           # legacy systems.
}


sudo chown -R root /usr/local/etc/pdnsd.conf
(意思是把 /usr/local/etc/pdnsd.conf文件的owner改为root)
sudo pdnsd -c /usr/local/etc/pdnsd.conf

运行pdnsd,我们再试试dig twitter.com



看到了么 twitter.com后面的82504 这个数字,单位是秒,也就意味着一天之内都不用再去google dns查询了, pdnsd已经缓存了。

终于,我们期待的毫秒级的dns解析又回来了。

(pdnsd.conf文件分为数个区域,主要修改global区域和server区域,其他区域保留默认值即可。具体的配置文件详情请查阅官方文档:pdnsd Documents
给pdnsd设置开机启动:
1
/etc/init.d/pdnsd enable  )



最后,以策万全,如果你有境外VPS,自己搭建域名解析服务器,以应对不知何时GFW干扰google dns tcp通信,是最佳的方式!


还是用 autossh 这个利器转发DNS数据包: 例如:

/usr/bin/autossh -M 21000 -f -N -C -c blowfish -m hmac-md5-96 -L 53:localhost:53 root@your_vps_ip -p22 -i /root/server_usa
from  http://bullshitlie.blogspot.co.uk/2012/03/pdnsd-google-dns-dns.html
------------------------------------------------------------------

利用pdnsd搭建DNS服务器简易教程


Assume that you use Ubuntu.

Download & Install pdnsd:   
apt-get install pdnsd

At the setup configuration step, choose manual. Then modify the config file: /etc/pdnsd.conf

At the global section, change server_ip, add server_port, increase or decrease the perm_cache, change min_ttl & max_ttl at your own need, just like:


global {
perm_cache=4096; //cache size,KB
cache_dir="/var/cache/pdnsd"; //cache file position
run_as="root"; //just leave default
server_ip = 0.0.0.0; // Use your interface name, or your IP address
// or 0.0.0.0
server_port = 1212; //bind port, just do not use port 53
status_ctl = on;
paranoid=on;
// query_method=tcp_udp; // pdnsd must be compiled with tcp
// query support for this to work.
min_ttl=1d; // Retain cached entries at least 1 day.
max_ttl=1w; // One week.
neg_ttl=120s;
timeout=5; // Global timeout option (10 seconds).
}

Then add the upstream DNS server, just like:   
server {
label = "mydns";
root_server=on;
ip = 1.2.3.4
, 1.2.3.5
, 1.2.3.6
;
timeout = 3;
uptest = none;
purge_cache = off;
edns_query = on;
exclude = .localdomain;
}

Comment out the unnecessary sections, such as root-servers & resolvconf:
/*
server {
label="resolvconf";
}
*/
/*
server {
label = "root-servers";
root_server=on;
...
...
policy = included;
preset = off;
}
*/

Here’s an example for pdnsd.conf

To see more details of pdnsd, just look at pdnsd Documents

Modify the file /etc/default/pdnsd, change START_DAEMON=no to START_DAEMON=yes and save the file. Finally start pdnsd:   
service pdnsd start

Add firewall rule if neccessary (Assume that you use UFW):   
ufw allow 1212

Check it on your PC:
dig @X.X.X.X -p 1212 www.youtube.com
; <<>> DiG 9.9.5-3-Ubuntu <<>> @X.X.X.X -p 2121 www.youtube.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64845
;; flags: qr rd ra; QUERY: 1, ANSWER: 12, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1024
;; QUESTION SECTION:
;www.youtube.com. IN A
;; ANSWER SECTION:
www.youtube.com. 86400 IN CNAME youtube-ui.l.google.com.
youtube-ui.l.google.com. 86400 IN A 173.194.117.232
youtube-ui.l.google.com. 86400 IN A 173.194.117.231
youtube-ui.l.google.com. 86400 IN A 173.194.117.233
youtube-ui.l.google.com. 86400 IN A 173.194.117.238
youtube-ui.l.google.com. 86400 IN A 173.194.117.224
youtube-ui.l.google.com. 86400 IN A 173.194.117.227
youtube-ui.l.google.com. 86400 IN A 173.194.117.225
youtube-ui.l.google.com. 86400 IN A 173.194.117.230
youtube-ui.l.google.com. 86400 IN A 173.194.117.229
youtube-ui.l.google.com. 86400 IN A 173.194.117.228
youtube-ui.l.google.com. 86400 IN A 173.194.117.226
;; Query time: 80 msec
;; SERVER: X.X.X.X#1212(X.X.X.X)
;; WHEN: Sun Nov 16 10:13:39 UTC 2014
;; MSG SIZE rcvd: 254