1.域名及DNS介绍

域名主要是为了方便让人记住,而 IP 地址是机器间的通信的真正机制。把域名转换为 IP 地址的服务,也就是域名解析服务(DNS),而对应的服务器就是域名服务器,网络协议则是 DNS 协议。

域名以分层结构管理,​​比如www.baidu.com​​就分为三级。 域名解析使用递归方式发送给每个层级域名服务器,直到解析结果。以下例分析

+trace表示开启跟踪查询
+nodnssec表示禁止DNS安全扩展
dig +trace +nodnssec www.baidu.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.9 <<>> +trace +nodnssec www.baidu.com
;; global options: +cmd
. 518400 IN NS I.ROOT-SERVERS.NET.
. 518400 IN NS J.ROOT-SERVERS.NET.
. 518400 IN NS D.ROOT-SERVERS.NET.
. 518400 IN NS H.ROOT-SERVERS.NET.
. 518400 IN NS A.ROOT-SERVERS.NET.
. 518400 IN NS G.ROOT-SERVERS.NET.
. 518400 IN NS K.ROOT-SERVERS.NET.
. 518400 IN NS F.ROOT-SERVERS.NET.
. 518400 IN NS E.ROOT-SERVERS.NET.
. 518400 IN NS C.ROOT-SERVERS.NET.
. 518400 IN NS B.ROOT-SERVERS.NET.
. 518400 IN NS M.ROOT-SERVERS.NET.
. 518400 IN NS L.ROOT-SERVERS.NET.
;; Received 239 bytes from 100.125.1.250#53(100.125.1.250) in 1 ms
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
;; Received 838 bytes from 198.97.190.53#53(H.ROOT-SERVERS.NET) in 111 ms
baidu.com. 172800 IN NS ns2.baidu.com.
baidu.com. 172800 IN NS ns3.baidu.com.
baidu.com. 172800 IN NS ns4.baidu.com.
baidu.com. 172800 IN NS ns1.baidu.com.
baidu.com. 172800 IN NS ns7.baidu.com.
;; Received 300 bytes from 192.12.94.30#53(e.gtld-servers.net) in 228 ms

www.baidu.com. 1200 IN CNAME www.a.shifen.com.
;; Received 72 bytes from 36.152.45.193#53(ns3.baidu.com) in 23 ms

从本地配置的dns查到一些根域服务器(.)NS记录;然后从NS记录选一个(​​H.ROOT-SERVERS.NET​​​),并查询顶级域名com.的NS记录;是从com.的NS记录选择一个(​​e.gtld-servers.net​​​),并查询二级域名baidu.com.的NS记录;最后从baidu.com.的NS记录选择一个(​​ns3.baidu.com​​​)查询最终主机​​www.baidu.com​​.的A记录为36.152.45.193

2.DNS案例分析

首先启动容器

$ docker run -it --rm --cap-add=NET_ADMIN --dns 8.8.8.8 feisky/dnsutils bash
root@0cd3ee0c8ecb:/#

运行nslookup 命令,解析time.geekbang.org的ip地址。查看输出的解析时间,解析用时10s。有时解析会出现超时失败的情况。是什么原因呢?

/# time nslookup time.geekbang.org
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: ​​time.geekbang.org​​
Address: 39.106.233.176
real 0m10.349s
user 0m0.004s
sys 0m0.0

解析不稳定可能有几种情况:客户端到dns服务器网络延迟比较大;dns请求或者响应包,在某些情况下被某些网络设备弄丢了。 

ping 来测试下服务器的延迟。 延迟达到了140ms,运行多次,还有丢包的现象。这个dns是Google的dns服务,所以换成国内的dns服务就可以解决,比如换成114.114.114.114。

/# ping -c3 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=31 time=137.637 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=31 time=144.743 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=31 time=138.576 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 137.637/140.319/144.743/3.152 ms

思考:DNS解析带来的性能问题有没有好的优化方法呢? 

  • 可以在本服务器安装dnsmasq 服务,对DNS结果进行缓存,一旦缓存过期,去DNS服务器重新获取记录。
  • 使用 HTTPDNS 取代常规的 DNS 解析。这是很多移动应用会选择的方法,特别是如今域名劫持普遍存在,使用 HTTP 协议绕过链路中的 DNS 服务器,就可以避免域名劫持的问题。其实域名劫持的话一般用https代替http。

3.案例二

描述:nslookup 解析是成功的,但是ping 域名提示unknow host 

想查看本地情况可以用tcpdump抓包来分析。 如

tcpdump -i eth0 udp and port 53

抓包分析ping不通域名的时候是把域名丢掉/etc/resolv.conf中的第二台nameserver.或者根本没有发送到dns查询。根本原因就是挑选的nameserver不对,按照 /etc/resolv.conf 的逻辑都是使用第一个nameserver,失败后才使用第二、第三个备用nameserver。

但是第一个nameserver没有失败,为啥会解析到第二台nameserver上呢?在/etc/resolv.conf 发现了rotate(轮训多个nameserver),去掉后从第一个nameserver去解析。也可以正常能ping通了。