DNS 相关

验证工具

nslookup 、dig、ping 等

nslookup和dig 解析域名都是请求/etc/resolv.conf下面配置的第一个nameserver地址,而ping 工具会检查/etc/hosts然后是缓存,最后是/etc/resolv.conf里面的配置。

nslookup使用


$ nslookup time.geekbang.org

# 域名服务器及端口信息
Server:    114.114.114.114
Address:  114.114.114.114#53

# 非权威查询结果
Non-authoritative answer:
Name:  time.geekbang.org
Address: 39.106.233.17


这里要注意,由于 114.114.114.114 并不是直接管理 time.geekbang.org 的域名服务器,所以查询结果是非权威的。使用上面的命令,你只能得到 114.114.114.114 查询的结果。



开启调试模式,查看从哪个ns 获取解析服务

nslookup -debug www.baidu.com
Server: 172.31.0.2
Address: 172.31.0.2#53


------------
QUESTIONS:
www.baidu.com, type = A, class = IN
ANSWERS:
-> www.baidu.com
canonical name = www.a.shifen.com.
ttl = 300
-> www.a.shifen.com
internet address = 220.181.38.150
ttl = 277
-> www.a.shifen.com
internet address = 220.181.38.149
ttl = 277
AUTHORITY RECORDS:
ADDITIONAL RECORDS:
------------
Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com.
Name: www.a.shifen.com
Address: 220.181.38.150
Name: www.a.shifen.com
Address: 220.181.38.149

 
查看解析时间
time nslookup www.baidu.com

dig使用

除了 nslookup,另外一个常用的 DNS 解析工具 dig ,就提供了 trace 功能,可以展示递归查询的整个过程。比如你可以执行下面的命令,得到查询结果:

# +trace表示开启跟踪查询
# +nodnssec表示禁止DNS安全扩展
$ dig +trace +nodnssec time.geekbang.org

; <<>> DiG 9.11.3-1ubuntu1.3-Ubuntu <<>> +trace +nodnssec time.geekbang.org
;; global options: +cmd
.      322086  IN  NS  m.root-servers.net.
.      322086  IN  NS  a.root-servers.net.
.      322086  IN  NS  i.root-servers.net.
.      322086  IN  NS  d.root-servers.net.
.      322086  IN  NS  g.root-servers.net.
.      322086  IN  NS  l.root-servers.net.
.      322086  IN  NS  c.root-servers.net.
.      322086  IN  NS  b.root-servers.net.
.      322086  IN  NS  h.root-servers.net.
.      322086  IN  NS  e.root-servers.net.
.      322086  IN  NS  k.root-servers.net.
.      322086  IN  NS  j.root-servers.net.
.      322086  IN  NS  f.root-servers.net.
;; Received 239 bytes from 114.114.114.114#53(114.114.114.114) in 1340 ms

org.      172800  IN  NS  a0.org.afilias-nst.info.
org.      172800  IN  NS  a2.org.afilias-nst.info.
org.      172800  IN  NS  b0.org.afilias-nst.org.
org.      172800  IN  NS  b2.org.afilias-nst.org.
org.      172800  IN  NS  c0.org.afilias-nst.info.
org.      172800  IN  NS  d0.org.afilias-nst.org.
;; Received 448 bytes from 198.97.190.53#53(h.root-servers.net) in 708 ms

geekbang.org.    86400  IN  NS  dns9.hichina.com.
geekbang.org.    86400  IN  NS  dns10.hichina.com.
;; Received 96 bytes from 199.19.54.1#53(b0.org.afilias-nst.org) in 1833 ms

time.geekbang.org.  600  IN  A  39.106.233.176
;; Received 62 bytes from 140.205.41.16#53(dns10.hichina.com) in 4 ms




dig trace 的输出,主要包括四部分。
第一部分,是从 114.114.114.114 查到的一些根域名服务器(.)的 NS 记录。
第二部分,是从 NS 记录结果中选一个(h.root-servers.net),并查询顶级域名 org. 的 NS 记录。
第三部分,是从 org. 的 NS 记录中选择一个(b0.org.afilias-nst.org),并查询二级域名 geekbang.org. 的 NS 服务器。最后一部分,就是从 geekbang.org. 的 NS 服务器(dns10.hichina.com)查询最终主机 time.geekbang.org. 的 A 记录。

DNS缓存

nscd

dnsmasq
 

域名解析流程

glibc 相关服务

  • DNS域名解析的时候先根据 /etc/nsswitch.conf 配置的顺序进行dns解析(name service switch),一般是这样配置:hosts: files dns 【files代表 /etc/hosts ; dns 代表 /etc/resolv.conf】(ping是这个流程,但是nslookup和dig不是)
  • 如果本地有DNS Client Cache,先走Cache查询,所以有时候看不到DNS网络包。Linux下nscd可以做这个cache,Windows下有 ipconfig /displaydns ipconfig /flushdns
  • 如果 /etc/resolv.conf 中配置了多个nameserver,默认使用第一个,只有第一个失败【如53端口不响应、查不到域名后再用后面的nameserver顶上】
  • 如果 /etc/resolv.conf 中配置了rotate,那么多个nameserver轮流使用. 但是因为底层库的原因用了rotate 会触发nameserver排序的时候第二个总是排在第一位
 

关于glibc服务介绍

服务基于glibc开发的各类网络服务,基本上来讲我们能见到的一些编程语言和开发框架最终均会调用到glibc的网络解析的函数(如GETHOSTBYNAME or GETHOSTBYADDR等),因此绝大部分程序能够使用NSCD提供的缓存服务。当然了如果是应用端自己用socker编写了一个网络client就无法使用NSCD提供的缓存服务,比如DNS领域常见的dig命令不会使用NSCD提供的缓存,而作为对比ping得到的DNS解析结果将使用NSCD提供的缓存
 

glibc函数

glibc 的解析器(revolver code) 提供了下面两个函数实现名称到 ip 地址的解析, gethostbyname 函数以同步阻塞的方式提供服务, 没有超时等选项, 仅提供 IPv4 的解析. getaddrinfo 则没有这些限制, 同时支持 IPv4, IPv6, 也支持 IPv4 到 IPv6 的映射选项. 包含 Linux 在内的很多系统都已废弃 gethostbyname 函数, 使用 getaddrinfo 函数代替. 不过从现实的情况来看, 还是有很多程序或网络库使用 gethostbyname 进行服务.

glibc中对rotate的处理

glibc 2.2.5(2010年的版本),如果有rotate逻辑就是把第一个nameserver总是丢到最后一个去(为了均衡nameserver的负载,保护第一个nameserver)

在2017年这个代码逻辑终于改了,不过还不是默认用第一个,而是随机取一个,rotate搞成random了

也就是2010年之前的版本都是把第一个默认挪到最后一个(为了保护第一个nameserver),到2017年改掉了这个问题,不过改成随机取nameserver, 作者不认为这是一个bug,他觉得配置rotate就是要平衡多个nameserver的性能,所以random最公平,因为大多程序都是查一次域名缓存好久,不随机轮询的话第一个nameserver压力太大

也就是2010年之前的glibc版本在rotate模式下都是把第一个nameserver默认挪到最后一个(为了保护第一个nameserver),这样rotate模式下默认第一个nameserver总是/etc/resolov.conf配置文件中的第二个,到2017年改掉了这个问题,不过改成随机取nameserver, 作者不认为这是一个bug,他觉得配置rotate就是要平衡多个nameserver的性能,所以random最公平,因为大多程序都是查一次域名缓存好久,不随机轮询的话第一个nameserver压力太大

备注:

线上开启 nscd 前, 建议做好程序的测试, nscd 仅支持通过 glibc, c 标准机制运行的程序, 没有基于 glibc 运行的程序可能不支持 nscd. 另外一些 go, perl 等编程语言网络库的解析函数是单独实现的, 不会走 nscd 的 socket, 这种情况下程序可以进行名称解析, 但不会使用 nscd 缓存. 不过我们在测试环境中使用go, java 的常规网络库都可以正常连接 nscd 的 socket 进行请求; perl 语言使用 Net::DNS 模块, 不会使用 nscd 缓存; python 语言使用 python-dns 模块, 不会使用 nscd 缓存. python 和 perl 不使用模块的时候进行解析还是遵循上述的过程, 同时使用 nscd 缓存.

DNS劫持

防范措施

1、使用 HTTPDNS 取代常规的 DNS 解析。这是很多移动应用会选择的方法,特别是如今域名劫持普遍存在,使用 HTTP 协议绕过链路中的 DNS 服务器,就可以避免域名劫持的问题。

2、http 配置为https ,使用权威认证的证书

原文地址:https://www.cnblogs.com/fanggege/p/14317178.html