计算机网络 DNS & HTTPDNS 原理
1. DNS 原理
1.1 DNS 简介
域名(Domain Name,Domain) 是一个在互联网上标识主机或主机组的名称,相当于 IP 地址的别名,相对于晦涩难记的 IP 地址,域名更显得易于记忆。
域名系统(Domain Name System,DNS) 则是将域名解析 IP 地址的一项互联网基础服务,提供该服务的服务器称为 域名服务器(Domain Name Server)。
域名结构
[外链图片转存中…(img-0k8TMR9B-1647421813282)]
注意:最前面的一定是主机,最后一个点表示根域,通常是省略不写的,但实际上www.abc.com=www.abc.com.
1.2 DNS 解析过程
名词介绍
ttl是 Time To Live的缩写,是一个ip协议的值,它告诉网络,数据包在网络中的时间是否太长而应被丢弃。有很多原因使包在一定时间内不能被传递到目的地。
TTL的最初设想是确定一个时间范围,超过此时间就把包丢弃。由于每个路由器都至少要把TTL域减一,TTL通常表示包在被丢弃前最多能经过的路由器个数。当记数到0时,路由器决定丢弃该包,并发送一个ICMP报文给最初的发送者。
[root@localhost wqz]# cat /proc/sys/net/ipv4/ip_default_ttl
64
本地域名服务器(Local Name Server,local DNS):如果通过 DHCP 配置,local DNS 由互联网服务提供商(ISP,如联通、电信)提供;
根域名服务器(Root Name Server):当 local DNS 查询不到解析结果时,第一步会向它进行查询,并获取顶级域名服务器的IP地址。全球一共有 13 个根域名服务器(除了它们的镜像),它们并不直接用于域名解析,仅用于指出可查询的顶级域名服务器。这个网站记录了现有的 13 个根域名服务器:www.internic.net/domain/name…;
顶级域名服务器(Top-level Name Server):负责管理在该顶级域名服务器下注册的二级域名,例如**.com 顶级域名服务器**,而 baidu.com 权威服务器是注册在 .com 的权威域名服务器;
权威域名服务器(Authoritative Name Server):在特定区域内具有唯一性,负责维护该区域内的域名与 IP 地址的映射关系。在 DNS 应答报文中,标志位 AA 标识本次 DNS 记录是否来自权威域名服务器,否则可能来自缓存。
流程
当我们在地址栏输入一个www.baidu.com时,DNS域名解析会经历以下过程:
1.浏览器先检查自身的缓存有没有解析过这个域名对应的IP,如果有解析结束。
2.如果没有(专业名词叫做没有命中,后面都说没有命中)浏览器会检查操作系统中有没有对应的已解析过的结果,并且操作系统也有自己的解析过程,如linux中的/etc/hosts中设置的一些。
3.如果到此还没有命中,才会真正去请求本地的域名服务器(LDNS)来解析这个域名,这台服务器会遍布在城市中的某个角落,并且性能很好,一般都会缓存域名解析结果。
4.如果LDNS仍然没有命中,会进行Root Server域名服务器请求解析。
5.根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如 .com .cn .org等)地址。
6.此时LDNS再发送请求给上一步返回的gTLD。
7.接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器。
8.Name Server根据映射关系表找到目标ip,返回给LDNS。
9.LDNS缓存这个域名和对应的ip。
10.LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束。
DNS 解析分为 递归查询 和 迭代查询 两种方式。其中,客户端与 Local DNS 之间一般采用递归查询,而 DNS 服务器之间一般采用迭代查询。
- 递归查询:
所谓递归查询,与我们经常提及的递归函数的思想是一致的,即:如果 DNS 服务器查不到该域名,那么它将重新以客户端的身份向其他 DNS 服务器发送查询请求报文,客户端只要等待最终结果即可。
- 迭代查询:
所谓迭代查询,即:如果 DNS 服务器查不到该域名,它不会替客户端完成后续的查询工作,而是回复下一步应当向哪一个域名服务器进行查询,随后客户端重新向这个新的 DNS 服务器发送查询请求。
1.3 DNS 报文
[外链图片转存中…(img-MSBr3A3D-1647421813284)]
网络层有四个协议:ARP协议,IP协议,ICMP协议,IGMP协议。
ARP协议为IP协议提供服务,IP协议为ICMP协议提供服务,ICMP协议为IGMP协议提供服务。
网络层的IP报文头介绍:IP数据包也叫IP报文分组,传输在ISO网络7层结构中的网络层,它由IP报文头和IP报文用户数据组成,IP报文头的长度一般在20到60个字节之间,而一个IP分组的最大长度则不能超过65535个字节。
下图为IP分组的报文头格式,报文头的前20个字节是固定的,后面的可变。
版本:占4位(bit),指IP协议的版本号。目前的主要版本为IPV4,即第4版本号,也有一些教育网和科研机构在使用IPV6。在进行通信时,通信双方的IP协议版本号必须一致,否则无法直接通信。
首部长度:占4位(bit),指IP报文头的长度。最大的长度(即4个bit都为1时)为15个长度单位,每个长度单位为4字节(TCP/IP标准,DoubleWord),所以IP协议报文头的最大长度为60个字节,最短为上图所示的20个字节。
服务类型:占8位(bit),用来获得更好的服务。其中的前3位表示报文的优先级,后面的几位分别表示要求更低时延、更高的吞吐量、更高的可靠性、更低的路由代价等。对应位为1即有相应要求,为0则不要求。
总长度:16位(bit),指报文的总长度(包括报文头)。注意这里的单位为字节,而不是4字节,所以一个IP报文的的最大长度为65535个字节。
标识(identification):该字段标记当前分片为第几个分片,在数据报重组时很有用。
标志(flag):该字段用于标记该报文是否为分片(有一些可能不需要分片,或不希望分片),后面是否还有分片(是否是最后一个分片)。
片偏移:指当前分片在原数据报(分片前的数据报)中相对于用户数据字段的偏移量,即在原数据报中的相对位置。
生存时间:TTL(Time to Live)。该字段表明当前报文还能生存多久。每经过1ms或者一个网关,TTL的值自动减1,当生存时间为0时,报文将被认为目的主机不可到达而丢弃。使用过Ping命令的用户应该有印象,在windows中输入ping命令,在返回的结果中即有TTL的数值。
协议:该字段指出在上层(网络7层结构或TCP/IP的传输层)使用的协议,可能的协议有UDP、TCP、ICMP、IGMP、IGP等。
首部校验和:用于检验IP报文头部在传播的过程中是否出错,主要校验报文头中是否有某一个或几个bit被污染或修改了。
源IP地址:32位(bit),4个字节,每一个字节为0~255之间的整数,及我们日常见到的IP地址格式。
目的IP地址:32位(bit),4个字节,每一个字节为0~255之间的整数,及我们日常见到的IP地址格式。
应用层的dns数据段:DNS 协议定义了三种报文,查询报文 & 应答报文 & 更新报文,它们的总体上结构是一致的。
-
报文首部(Header)
- 1、事务 ID(Transaction ID):用来关联 DNS 查询与应答,DNS客户端每次发送查询请求都会使用不同的 ID,而服务器在响应中重复这个 ID
- 2、标志(Flags):报文的标志字段,详见下图
- 3、问题数(Question Count):指定问题部分条目数
- 4、回答资源记录数(Answer Resource Record count):指定应答部分中回答资源条目数
- 5、权威资源记录数(Authority Resource Record count):指定权威资源记录数
- 6、附加资源记录数(Additional Resource Record count):指定附加资源记录数
-
问题(Question)
问题用于表达具体查询的问题,问题个数与报文首部中的 **问题数(Question Count)**字段一致。需要注意的是,按照 DNS 查询的目的,DNS 解析可以分为 正向解析 和 反向解析 两种,正向解析将域名解析为 IP 地址,而反向解析则恰恰相反,用于将 IP 地址解析域名。问题条目中 查询类型 是比较重要的字段,这里仅列出 5 个比较常用的类型:
QTYPE | 描述 |
---|---|
A(1) | 将域名解析为 IPv4 地址 |
NS(2) | 查询域名服务 |
CNAME(5) | 规范名称 |
PTR(12) | IP 地址解析为域名 |
AAAA(28) | 将域名解析为 IPv6 地址 |
1.4 DNS 报文的传输协议
DNS 协议在传输层同时使用 TCP 和 UDP 协议,占用的是 53 端口,那么在什么情况下使用这两种协议?
- 在区域传输时使用 TCP 协议
主辅域名服务器在进行区域传送时(主辅域名服务器用于平衡负载),需要传送的数据比简单的查询 & 应答报文的数据量要大得多了。使用 UDP 传输不可靠,所以采用应用于传输大量数据,可靠性更高的 TCP 协议。
- 在域名解析时使用 UDP 协议
为了得到一个域名的 IP 地址,往往会向多个域名服务器查询,如果使用 TCP 协议,那么每次请求都会存在三次握手连接时延,这样使 DNS 服务变得很慢。
需要注意的是,DNS 协议规定 UDP 报文段的最大长度为 512 字节,如果 DNS 报文段过长时会被截断(此时 DNS 报文头中标志位 TC(Truncation)置为 1),多余的数据会直接丢弃。这是因为 UDP 是无连接的,无法确定哪几个 UDP 包是属于同一个 DNS 报文段的。
1.5 DNS 解析实战
步骤一: 在过滤条件栏输入条件:ip.addr == 172.29.156.211 && icmp || dns
,如下图:
步骤二:终端 ping www.baidu.com
步骤三:查看DNS 查询应答报文
(1)Frame: 物理层的数据帧概况
(2)Ethernet II: 数据链路层以太网帧头部信息
(3)Internet Protocol Version 4: 互联网层IP包头部信息
(4)Transmission Control Protocol: 传输层T的数据段头部信息,此处是TCP
(5)Hypertext Transfer Protocol: 应用层的信息,此处是HTTP协议
查询报文
应答报文
1.6 DNS 缓存
一次完整的 DNS 查询过程需要访问多台 DNS 服务器才能得到最终的结果,这肯定会带来一定的时延。为了改善时延,DNS 服务并不是每次请求都要去访问 DNS 服务器,而是访问过一次后将 DNS 记录缓存在本地。具体来说,DNS 服务是一个多级的缓存:
浏览器缓存 -> 操作系统缓存 -> 路由器缓存 -> local DNS 缓存 -> DNS 查询
2. DNS 存在的问题
2.1 DNS 查询时延
从第一节的分析可以看出,一次完整的 DNS 查询过程需要访问多台 DNS 服务器才能得到最终的结果,这肯定会带来一定的时延。从实践来看,这个时间还不容小觑。
2.2 缓存一致性
DNS 缓存的存在虽然减少了时延,却是以牺牲一致性(consistency)为代价的。具体来说:Local DNS 是分地区、分运营商的,在域名解析缓存的处理上,实现策略就不统一了。有时候 Local DNS 的解析结果 可能不是最近、最优的节点,有的时候并不会遵从 TTL 的限制,而是设置一个固定时间。这就会导致域名指向新的 IP 地址后,一些客户端依然访问了缓存中 旧的 IP 地址。
除了运营商的缓存策略外,缓存投毒也是降低 DNS 可用性的原因。攻击者可以通过 DNS 劫持,利用 DNS 的缓存机制不对应答数据做检查的漏洞,诱骗 DNS 服务器缓存较大 TTL 的虚假 DNS 记录,从而长期欺骗客户端。
2.3 DNS 劫持(中间人攻击)
由于 DNS 缺乏 加密、认证、完整性保护的安全机制,容易引发网络完全问题。最常见的域名劫持攻击是针对 DNS 报文首部的 事务 ID 进行欺骗,由于事务 ID 在查询报文和应答报文中是匹配的,因此伪装 DNS 服务器可以提前将事务 ID 相同的伪造报文发送到客户端,以实现域名劫持(前提是合法的报文还未到达),把目标网站域名解析到错误的 IP 地址。
2.4 调度不精准问题
由于存在缓存、转发、NAT 等问题,权威的 DNS 服务器可能会误判客户端所在的位置和运营商,从而导致解析出跨运营商访问的 IP 地址,用户的访问速度降低。
3. HTTPDNS 原理
虽然 DNS 存在不少问题,但也不能因噎废食放弃整套域名系统,解决方案无非是不走寻常路,换一种方式获取 IP 地址 —— HTTPDNS。
3.1 HTTPDNS 简介
与传统的 DNS 解析不同,HTTPDNS 是自己搭建基于 HTTP 协议的服务器,当客户端需要 DNS 解析的时候,不再向 local 发送 DNS 查询报文,而是直接通过请求直接访问 HTTPDNS 接口。而服务端则根据客户端的位置和所属运营商,返回就近的 IP 地址。
当然了,基于容灾考虑,当出现 HTTPDNS 不可用时会触发降级策略,使用运营商 LocalDNS 进行域名解析。
3.2 HTTPDNS 优势
相对与 DNS,HTTPDNS 的主要优点如下:
- 降低时延
缩短了查询链路,不像 DNS 查询那样需要访问多台 DNS 服务器才能得到最终的结果;
- 域名防劫持 域名解析请求直接发送至HTTPDNS服务器,绕过运营商 Local DNS,避免域名劫持问题;
- 调度精准 由于 DNS 服务器端获取的是真实客户端 IP 而非 Local DNS 的 IP,能够精确基于客户端位置、运营商信息,获得最精准的解析结果,让客户端就近接入业务节点
- 快速生效
域名解析结果变更时,HTTPDNS 服务没有传统DNS 服务多级缓存的影响,域名更新能够更快地覆盖到全量客户端。
wireshark使用
Filter: ip.addr == 119.75.217.26 and icmp # 表示只显示ICPM协议且源主机IP或者目的主机IP为119.75.217.26的数据包。
ip.addr == 172.29.156.211 && icmp || dns
ip过滤
ip.src ==192.168.1.104 显示源地址为192.168.1.104的数据包列表
ip.dst==192.168.1.104, 显示目标地址为192.168.1.104的数据包列表
ip.addr == 192.168.1.104 显示源IP地址或目标IP地址为192.168.1.104的数据包列表
端口过滤
tcp.port ==80, 显示源主机或者目的主机端口为80的数据包列表。
tcp.srcport == 80, 只显示TCP协议的源主机端口为80的数据包列表。
tcp.dstport == 80,只显示TCP协议的目的主机端口为80的数据包列表。
Http模式过滤
http.request.method=="GET", 只显示HTTP GET方法的。
显示源IP地址或目标IP地址为192.168.1.104的数据包列表
端口过滤
tcp.port ==80, 显示源主机或者目的主机端口为80的数据包列表。
tcp.srcport == 80, 只显示TCP协议的源主机端口为80的数据包列表。
tcp.dstport == 80,只显示TCP协议的目的主机端口为80的数据包列表。
Http模式过滤
http.request.method==“GET”, 只显示HTTP GET方法的。