大陆地区的 DNS 劫持

撇开方院士的那个不谈,这种方式在大陆的流行情况我仅仅是听说,收到过我们客服的反馈而已,至于这个具体有多么的「生动」,我还真没遇到过(正常情况下,如果你的所有的流量都走 proxy,是不会遇到那种浏览器右下角弹广告的情况的,所以建议有能力的用户不管在哪里访问网络,都请主动走 proxy)。
直到我们开始启用了某个第三方的服务监控,才发现这个比例还不小,数据还是蛮有意思的,我找了两个列子,基本上一个 nslook 就能看出问题所在了。


这事要根本解决没强大的背景搞不定啊。

另外,这事对业务有没有影响,肯定是有的,但是有多大,还是要业务,比如面向最终用户的,一个访问了就是投诉过来了,但是如果是类似我们的这类看总体指标的业务,其实目前来看只要不是一个地区的大规模的劫持,还是能容忍的。

resolv.conf 的超时(timeout)与重试(attempts)机制

/etc/resolv.conf 有两个默认的值至关重要,一个是超时的 timeout,一个是重试的 attempts,默认情况下,前者是 5s 后者是 2 次。
这个估计很多工程师都不是很在意,一般情况下,使用默认的值倒没什么大问题,特殊情况我会在最后说明。

要测试,不要使用 dig, host, nslook 这类工具,因为他们并没有调用 resolver 的库,可以使用 getent 来测试。上面提到的只是一些诊断的工具,对于日常的应用来说,包括 web server、mail client、db 以及各种 app server 等等,任何使用 glibc resolver 都需要经过 resolv.conf 文件。

对于 libresolv 来说,只认 resolv.conf 的前三个 nameserver,所以写的再多也没什么意义。正常情况下,resolver 会从上至下进行解析,每个 nameserver 等待 timeout 的时间,如果一直到第三个都没结果,resolver 会重复上面的步骤 (attempts – 1) 次。

为了真正理解,例如下面这个场景:
search test.example.com example.com  
nameserver 192.168.0.1  
nameserver 192.168.0.2

假设 192.168.0.1 不返回结果(可能根本就不是台 DNS),我们假设需要解析 "www.devel",而这个仅仅在 www.devel.example.com 里面有记录,下面是整个执行的步骤:
1. "www.devel" on 192.168.0.1, wait until timeout (default 5 secs)
2. "www.devel" on 192.168.0.2, get reply: no such hostname
3. "www.devel" on 192.168.0.1, wait until timeout (default 5 secs)
4. "www.devel" on 192.168.0.2, get reply: no such hostname
5. "www.devel.test.example.com" on 192.168.0.1, wait until timeout (default 5 secs)
6. "www.devel.test.example.com" on 192.168.0.2, reply no such hostname
7. "www.devel.test.example.com" on 192.168.0.1, wait until timeout (default 5 secs)
8. "www.devel.test.example.com" on 192.168.0.2, reply no such hostname
9. "www.devel.example.com" on 192.168.0.1, wait until timeout (default 5 secs)
10. "www.devel.example.com" on 192.168.0.2, reply with IP address

默认情况下是 5s 超时,我做了两个简单的测试,把 resolv.conf 的前三个 nameserver 全部换成不存在的 1.1.1.1, 2.2.2.2, 3.3.3.3,然后可以观察下面 strace 跟踪的结果,对于 ping 以及 getent 来说,已经算是上层的应用结果了。
1. strace -t getent hosts baidu.com
2. strace ping baidu.com

把 timeout 设置为 1s 的结果可以看下面这个测试结果:
strace -t ping baidu.com(options timeout:1)

对于生产有什么意义了?
对于任何的代码,不管何种形式的(HTTP 的也好,DB 的连接也罢),只要是一端对另外一端的连接,都应该加上超时重试以及异常处理的。上面其实一共涉及三个点:
1. 超时,目前绝大多数的 API 都支持这类参数,包括我们线上用的 grequestsMySQLdb 等等
2. 重试,对于代码层面同样重要,跟上面类似
3. 异常处理,好的代码对于无法连接或者连接超时等问题应该及时的抛出异常打 log,而不是什么都没有,否则会加大问题定位的工作量,后期维护起来也会异常的麻烦。

这里有个有意思的脚本能检测最佳的 DNS。

最后,记得 dig, nslook 只会解析 resolv.conf 的内容,而不会解析 hosts 里面内容,所以如果想让 dig 解析 hosts 里面的内容,可以通过 dnsmasq 实现。

ref:
https://access.redhat.com/solutions/21420
http://serverfault.com/questions/562079/adjusting-how-long-linux-takes-to-fail-over-to-backup-dns-server-listed-in-resol

JVM 缓存对 DNS 的影响

迁移了 DNS 之后,大部分机器表现正常,但是跑 jvm 的机器由于其自身的 DNS cache 问题,仍然在向旧的机器请求。默认情况下,除非重启进程,否则 JVM 会一直的使用原有的 DNS 解析。可以通过在配置文件里面固定或者通过在命令行里面加参数的方式修改。
修改配置文件:
我们安装的 java 版本都在这个下面:
/usr/lib/jvm/java-sun/jre/lib/security

主要是下面这两个:
networkaddress.cache.ttl (default: -1)
networkaddress.cache.negative.ttl (default: 10)

命令行中加启动参数:
sun.net.inetaddr.ttl 这个对应于上面的 networkaddress.cache.ttl
sun.net.inetaddr.negative.ttl 这个对应于上面的 networkaddress.cache.negative.ttl

ref:
http://stackoverflow.com/questions/1256556/any-way-to-make-java-honor-the-dns-caching-timeout-ttl

记录几个 DNS

前两个太出名了,基本处于半墙状态,丢包率在 50% 左右。接下来的两个大家也应该都知道,后面的四个分别为 tw 以及 hk 的。拿出来跟大家共享下。
vpn 全局之后,恢复,各项解析正常。

8.8.8.8
8.8.4.4

208.67.222.222
208.67.222.220

168.95.192.1
168.95.192.2
203.80.96.9
203.80.96.10

公司主站域名放在国外解析,昨天上午某些无耻的运营商,不排除 wfg 的可能,屏蔽了公司在国外的域名解析商的 dns 服务,使用国内 DNS 的用户出现大面积的访问中断。紧急搬回国内,使用那个很山寨的啥 pod 服务,到目前(10/16/2011 10:30)为止,大部分地区已经恢复。

在局域网内做(移动)互联网真是件悲剧的事!

 

DNS

这里是配置 DNS 的相关命令 , 包括配置文件以及注意事项的总结 , 至于什么是 DNS , 怎么架设等问题可以 Google 之.
这个是繁体-简体说法对照表 , 不习惯的同学可以猛击试试 :-)

Fully Qualified Domain Name ( FQDN ) : 在 Internet 当中 , 任何一部合法的主机都具有独一无二的主机名称 , 这个主机名称包含了 hostname 与 domain name  , 并称为 FQDN .

DNS 伺服器的类型主要分为 master , slave 以及只进行快取记录的 cache-only 的 DNS 主机 .
Continue reading