背景 智能DNS智能否 众所周知,DNS解析是我们访问internet的“第一跳”,若域名解析失常那是一件很可怕的事情。所以这一步走的需要更快,更稳。现在业界普遍采用了智能DNS来实现,其原理就是根据自身所保存的表项的ip和用户的所在位置对应来就近分配服务器的主机记录给用户。智能DNS现在用途很广泛,如:在CDN网络中,根据智能DNS实现GSLB全局负载均衡,就近分发可请求的缓存服务器(也有可能是下级GSLB的site ip);在跨多数据中心组网,其也很好的实现异地多活。等等。但是智能DNS真的是完美,智能吗?在DNS解析中,帮我们出去向根递归的是LDNS,如果我们的LDNS和本地用户不在一个地理位置,那么用户则会得到一个LDNS所在位置最近的IP地址,例如我们很多人喜欢吧LDNS设置为8.8.8.8(google的公开DNS,稳定),这样我们智能DNS则会让用户得到一个美国服务器IP这显然是不合理的。
做个小实验 先将LDNS指定google的8.8.8.8,再将LDNS指定为学校的DNSserver
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 zhxfei@zhxfei-HP-ENVY-15-Notebook-PC:~$ dig -t A www.alibaba.com @8.8.8.8 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> -t A www.alibaba.com @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3653 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;www.alibaba.com. IN A ;; ANSWER SECTION: www.alibaba.com. 164 IN CNAME www.gds.alibaba.com. www.gds.alibaba.com. 114 IN A 198.11.132.23 ;; Query time: 201 msec ;; SERVER: 8.8.8.8 ;; WHEN: Sun Jul 24 22:04:38 CST 2016 ;; MSG SIZE rcvd: 82
耗时201ms,解析结果为198.11.132.23,所在地美国,GeoIP: San Mateo, California, United States
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 zhxfei@zhxfei-HP-ENVY-15-Notebook-PC:~$ dig -t A www.alibaba.com @202.119.160.11 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> -t A www.alibaba.com @202.119.160.11 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18762 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.alibaba.com. IN A ;; ANSWER SECTION:zhiwei www.alibaba.com. 300 IN CNAME www-cn.gds.alibaba.com. www-cn.gds.alibaba.com. 120 IN A 106.11.62.61 ;; AUTHORITY SECTION: gds.alibaba.com. 6460 IN NS gdsns1.alibaba.com. gds.alibaba.com. 6460 IN NS gdsns2.alibaba.com. ;; Query time: 34 msec ;; SERVER: 202.119.160.11 ;; WHEN: Sun Jul 24 22:08:59 CST 2016 ;; MSG SIZE rcvd: 127
耗时34ms,解析结果为106.11.62.61,所在地上海,GeoIP: Hangzhou, Zhejiang, China
solution 面对这个情况,现在我知道的有以下两种解决方案:
HTTPDNS 来源于腾讯,将DNS请求借由HTTP来向HttpDNS接口发起查询。于绕过了运营商的LocalDNS,用户解析域名的请求通过Http协议直接透传到了腾讯的HttpDNS服务器IP上,用户在客户端的域名解析请求将不会遭受到运营商解析转发,DNS污染,劫持,出口多NAT等等困扰
ECS:来源于google,对EDNS0的扩展。在DNS请求的包中插入client的网段地址带到ADNS上,ADNS收到ECS段位的包根据client的IP去进行DNS记录匹配,google的公开name server已支持,此方式需要LDNS和ADNS(授权域名服务器)同时支持。现在大多数有CDN的厂商都支持了edns-client-subnet,但是运营商的LDNS都不支持,所以现在还是为正式被广泛使用。原生的bind目前还不支持目前只有在最新的bind9.11才被支持,而一般较新版本的bind-utils中的dig工具已经支持了此项的调试,无需编译就可使用。具体使用见后面的测试
PS:就小的看来HTTPDNS会越来越火,DNSPod也推出了相应的方案,听说现在已经集成到一部分app 的SDK里面了,做为正常DNS解析失常的备用方案。有时间研究下另开一篇胡说八道
环境搭建(ADNS测试) 编译bind edns-client-subnet(下简称ecs)其现在还没有正式被bind9支持,但是bind9给出了实验版本。需要对bind重新编译,ISC上有支持ecs authoritative的源码 ,git克隆到到本地编译即可。
完成的环境:
1 2 [root@localhost ~] Linux localhost.localdomain 2.6.32-431.el6.x86_64
安装
1 2 3 4 git clone https://source.isc.org/git/bind9.git cd bind9/./configure make && make install
设置ECS elements 设置bind的主配置文件,编辑/etc/named.conf:
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 [root@localhost ~] acl localnet{ ecs 120.0.0.1/24; }; acl externet{ any; }; options { directory "/var/named" ; }; view internal { match-clients { localnet; }; recursion yes; zone "." IN { type hint; file "named.ca" ; }; zone "zhxfei.com" IN { type master; file "zhxfei.com.localnet.zone" ; allow-transfer { none; }; }; }; view external { match-clients { externet; }; recursion no; zone "." IN { type hint; file "named.ca" ; }; zone "zhxfei.com" IN { type master; file "zhxfei.com.externnet.zone" ; allow-transfer { none; }; }; };
如上,在ADNS上的bind上,写acl来匹配ecs对应的ip,来看其作用:
ACLs can now include “ecs” elements which specify an address or network prefix; if an ECS option is included in a DNS query, then the address encoded in the option will be matched against “ecs” ACL elements. Also, if an ECS address is included in a query, then it will be used instead of the client source address when matching “geoip” ACL elements. This behavior can be overridden with “geoip-use-ecs no;”. When “ecs” or “geoip” ACL elements are used to select a view for a query, the response will include an ECS option to indicate which client network the answer is valid for.
简单翻译下:即在ADNS上如果ECS地址包含在查询内,它将使用其代替源IP进行解析查询(在没有使用“geoip-use-ecs no的情况下”),并将ECS 的网段地址写进response报文中,回复给LDNS,表明采用了ecs解析。
查询过程是这样的:
在我写的规则中,ACL localnet只有120.0.0.1/24这个网段,只有在收到的query报文中有ecs段位且匹配到了这个ecs的网段,才能命中internal视图
测试准备 通过 named 来开启bind进程,之后通过查看日志检查bind是否正常启动,以及端口是否开放正常
1 2 3 named tail /var/log /message netstat -tunlp | grep named
可以看到bind和rndc开放正常:
1 2 3 4 5 6 7 8 9 [root@localhost ~] tcp 0 0 172.16.130.129:53 0.0.0.0:* LISTEN 2124/named tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 2124/named tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 2124/named tcp 0 0 :::53 :::* LISTEN 2124/named tcp 0 0 ::1:953 :::* LISTEN 2124/named udp 0 0 172.16.130.129:53 0.0.0.0:* 2124/named udp 0 0 127.0.0.1:53 0.0.0.0:* 2124/named udp 0 0 :::53 :::* 2124/named
验证结果 在本地用dig调试
用200.0.0.1/24作为用户所在的网段:
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 zhxfei@zhxfei-HP-ENVY-15-Notebook-PC:~$ dig -t A www.zhxfei.com @172.16.130.129 +subnet=200.0.0.1/24 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> -t A www.zhxfei.com @172.16.130.129 +subnet=200.0.0.1/24 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11779 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ; CLIENT-SUBNET: 200.0.0.0/24/0 ;; QUESTION SECTION: ;www.zhxfei.com. IN A ;; ANSWER SECTION: www.zhxfei.com. 86400 IN A 1.1.1.1 ;; AUTHORITY SECTION: zhxfei.com. 86400 IN NS ns.zhxfei.com. ;; ADDITIONAL SECTION: ns.zhxfei.com. 86400 IN A 172.16.130.129 ;; Query time: 0 msec ;; SERVER: 172.16.130.129 ;; WHEN: Mon Jul 25 01:00:43 CST 2016 ;; MSG SIZE rcvd: 103
用120.0.0.1/24作为用户所在的网段
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 zhxfei@zhxfei-HP-ENVY-15-Notebook-PC:~$ dig -t A www.zhxfei.com @172.16.130.129 +subnet=120.0.0.1/24 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> -t A www.zhxfei.com @172.16.130.129 +subnet=120.0.0.1/24 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21300 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ; CLIENT-SUBNET: 120.0.0.0/24/24 ;; QUESTION SECTION: ;www.zhxfei.com. IN A ;; ANSWER SECTION: www.zhxfei.com. 86400 IN A 10.0.0.1 ;; AUTHORITY SECTION: zhxfei.com. 86400 IN NS ns.zhxfei.com. ;; ADDITIONAL SECTION: ns.zhxfei.com. 86400 IN A 172.16.130.129 ;; Query time: 0 msec ;; SERVER: 172.16.130.129 ;; WHEN: Mon Jul 25 01:00:53 CST 2016 ;; MSG SIZE rcvd: 103
验证如上,匹配到ecs elements的查询替代了源172.16.130.1的解析结果
抓包 附带抓包结果,有兴趣看一下: 第一次解析 第二次解析
其他 f5不支持edns-client-subnet 现在很多智能DNS都做在了专业的应用交付设备上,常用的有三款:F5的GTM(广域网流量管理器),citrix的NetScaler,还有radware linkproof。 其中F5的BIG-IP系列的GTM独占鳌头。但是遗憾的是不支持edns-client-subnet,即当其收到带有ecs段位的报文,会将请求drop掉。 详细情况请看sol16240: The BIG-IP system treats as malformed and drops DNS queries containing the EDNS Client subnet option