DNS:互联网的地址簿

举报
yd_232225224 发表于 2026/10/19 15:07:13 2026/10/19
【摘要】 在浏览器中输入一个网站的名称,按下回车,页面便开始加载。这个过程看似理所当然,但计算机之间的通信依靠的是 IP 地址,而不是人类容易记忆的名称。在浏览器真正与网站服务器建立连接之前,必须先回答一个问题:这个名称对应的 IP 地址是什么?负责回答这个问题的,是域名系统(Domain Name System,DNS)。它是互联网最基础的基础设施之一,几乎每一次网络访问都从一次 DNS 查询开始。...

在浏览器中输入一个网站的名称,按下回车,页面便开始加载。这个过程看似理所当然,但计算机之间的通信依靠的是 IP 地址,而不是人类容易记忆的名称。在浏览器真正与网站服务器建立连接之前,必须先回答一个问题:这个名称对应的 IP 地址是什么?

负责回答这个问题的,是域名系统(Domain Name System,DNS)。它是互联网最基础的基础设施之一,几乎每一次网络访问都从一次 DNS 查询开始。DNS 也远不只是一个简单的名称到地址的映射表:它是一个覆盖全球的分布式数据库,支撑着邮件投递、服务发现、负载均衡、内容分发、证书签发验证等大量功能。

本文介绍 DNS 的设计背景、层次化的命名结构、解析的完整过程、记录类型、缓存机制、常见的工程用法,以及 DNS 面临的安全与隐私问题和相应的改进方案。

一、为什么需要 DNS

从主机文件到分布式系统

在互联网的前身发展早期,网络中的主机数量很少。每台主机都维护一个主机文件,记录网络中所有主机的名称和地址。这个文件由一个中心机构统一维护,各主机定期下载最新的版本。

随着网络规模的扩大,这种方式很快暴露出问题:

  • 文件越来越大:每台主机都需要存储全网所有主机的信息;
  • 更新难以同步:任何一台主机的变化都需要通知中心机构,再分发给所有主机,延迟很长;
  • 名称冲突:没有统一的命名规则,不同组织可能使用相同的名称;
  • 中心机构成为瓶颈:所有的修改都需要经过一个机构,负担越来越重。

20 世纪 80 年代,DNS 被设计出来以取代主机文件。它的核心设计思想是:将命名空间分层,并将每一层的管理权下放给不同的组织。

DNS 的设计目标

DNS 的设计需要满足几个关键目标:

  • 可扩展:能够支撑数以亿计的名称和每秒海量的查询;
  • 分布式管理:每个组织能够独立管理自己的名称,无需经过中心机构的批准;
  • 高可用:不存在单点故障,部分服务器的故障不影响整体系统的运行;
  • 高性能:查询应当快速完成,大部分查询可以通过缓存直接回答。

这些目标在今天看来依然具有很强的指导意义,DNS 的整体架构在几十年间基本保持不变,却支撑起了规模增长了数百万倍的互联网。

二、域名的层次结构

域名空间

DNS 的命名空间是一棵倒置的树:

  • 树的顶端是根,用一个空标签表示,书写时通常省略,有时写作末尾的一个点;
  • 根之下是顶级域(Top-Level Domain,TLD),包括通用顶级域,例如代表商业、组织、网络的顶级域,以及国家和地区代码顶级域,每个国家或地区有一个两字母的代码;
  • 顶级域之下是二级域,通常由组织或个人注册,例如一家公司的名称;
  • 再往下可以有任意多层子域,由二级域的持有者自行决定和管理。

一个完整的域名,是从树中某个节点到根的路径上所有标签的组合,标签之间用点分隔,从左到右层级依次升高。最右边是顶级域,最左边是最具体的主机或服务名称。末尾带有表示根的点的域名,称为完全限定域名。

授权与区域

DNS 层次结构的关键,在于授权(Delegation)。

  • 根的管理者负责维护所有顶级域的信息,并将每个顶级域的管理权授权给相应的注册管理机构;
  • 顶级域的管理者负责维护其下所有二级域的信息,并将每个二级域的管理权授权给注册了该域名的组织;
  • 二级域的持有者可以自行管理其下的所有子域,也可以将某个子域再授权给其他人管理。

DNS 将一个由同一个管理者负责的连续部分称为一个区域(Zone)。一个区域包含了该部分域名的所有记录,以及指向其下被授权出去的子区域的指针。区域的数据存储在一组权威域名服务器(Authoritative Name Server)上,这些服务器对该区域内的名称拥有最终的解释权。

正是通过这种层层授权的方式,DNS 将全球的命名管理工作分散到了无数个独立的组织中,每个组织只需维护自己负责的那一小部分,同时又形成了一个统一的命名空间。

根服务器

根区域的数据由根域名服务器提供。全球共有 13 个根服务器的名称,用字母 A 到 M 标识,由多个不同的组织运营。

13 这个数字源于早期 DNS 协议的限制:为了让对根服务器列表的查询响应能够放入一个 512 字节的 UDP 数据包中,根服务器的数量被限制在 13 个。

但这并不意味着全球只有 13 台根服务器。借助任播技术,每个根服务器名称背后,实际上都部署了分布在全球各地的大量服务器实例,它们宣告相同的 IP 地址,网络路由会自动将查询引导到最近的实例。目前,全球的根服务器实例数量已经超过一千个。

根服务器本身并不知道每个域名对应的地址,它只知道每个顶级域由哪些服务器负责。根服务器处理的查询,只是整个解析过程的第一步。

三、解析过程

解析中的角色

一次完整的 DNS 解析涉及几类不同的角色:

  • 存根解析器(Stub Resolver):运行在用户设备上的简单解析程序,通常是操作系统的一部分。它不进行复杂的查询,只是将查询发送给配置好的递归解析器,等待结果;
  • 递归解析器(Recursive Resolver):负责代替客户端完成整个解析过程。它从根开始,逐级查询,直到获得最终答案,然后将结果返回给客户端,并缓存起来。递归解析器通常由网络运营商、企业或公共 DNS 服务提供;
  • 权威域名服务器:存储某个区域的数据,对该区域内的查询给出权威的回答。

递归查询与迭代查询

DNS 查询有两种方式:

  • 递归查询:客户端要求服务器给出最终答案。服务器如果不知道,就必须自己去查询,直到找到答案或确认答案不存在。存根解析器向递归解析器发出的通常是递归查询;
  • 迭代查询:服务器只需给出自己所知道的最好的答案。如果它不知道最终答案,就返回一个引荐(Referral),告诉客户端应该去问谁。递归解析器向权威服务器发出的通常是迭代查询。

完整的解析流程

假设用户要访问某公司网站的主机,其域名由主机名、公司的二级域名和一个通用顶级域组成。在没有任何缓存的情况下,解析过程如下:

  1. 用户设备检查本地:存根解析器首先检查本地的主机文件和操作系统的 DNS 缓存。如果没有找到,就向配置的递归解析器发送查询;
  2. 递归解析器询问根服务器:递归解析器检查自己的缓存,没有找到。它向一个根服务器发送查询。根服务器不知道该主机的地址,但它知道该顶级域由哪些服务器负责,于是返回一个引荐,包含这些顶级域服务器的名称和地址;
  3. 递归解析器询问顶级域服务器:递归解析器向其中一个顶级域服务器发送查询。顶级域服务器也不知道该主机的地址,但它知道该公司的二级域由哪些服务器负责,于是返回另一个引荐;
  4. 递归解析器询问权威服务器:递归解析器向该公司二级域的权威服务器发送查询。权威服务器在其区域数据中找到了该主机的记录,返回对应的 IP 地址;
  5. 返回结果:递归解析器将结果缓存起来,并返回给用户设备。用户设备也将结果缓存,然后用这个 IP 地址与网站服务器建立连接。

粘合记录

在上述过程中,有一个看似循环依赖的问题:顶级域服务器告诉递归解析器"该二级域的权威服务器是某某名称",而如果这个权威服务器的名称恰好位于该二级域之内,递归解析器要查询它的地址,就需要先问这个权威服务器本身,形成了死循环。

为了解决这个问题,上级区域在返回引荐时,会同时附带这些权威服务器的 IP 地址,这些附带的地址记录称为粘合记录(Glue Record)。有了粘合记录,递归解析器就可以直接联系权威服务器,打破循环依赖。

缓存的作用

在实际中,绝大多数 DNS 查询并不需要走完上述完整的流程。

递归解析器会缓存所有查询过程中获得的信息,包括最终的答案,以及中间获得的引荐信息。根服务器和常见顶级域服务器的信息会被缓存很长时间,热门域名的记录也会被频繁地命中缓存。一个服务大量用户的递归解析器,其缓存命中率通常非常高,绝大部分查询都能直接从缓存中回答,只有少数查询需要访问权威服务器。

正是缓存使得 DNS 能够以较少的服务器支撑海量的查询,也使得根服务器的负载保持在可控的范围内。

四、资源记录

DNS 中存储的数据以资源记录(Resource Record)的形式组织。每条资源记录包含以下几个字段:

  • 名称:这条记录所属的域名;
  • 类型:记录的种类,决定了数据的含义;
  • 类别:几乎总是表示互联网的类别;
  • 生存时间(Time To Live,TTL):这条记录可以被缓存的时长,单位为秒;
  • 数据:记录的具体内容,格式取决于记录的类型。

常见的记录类型

A 记录:将域名映射到一个 IPv4 地址。这是最基本、最常用的记录类型。一个域名可以有多条 A 记录,对应多个地址。

AAAA 记录:将域名映射到一个 IPv6 地址。名称中的四个 A,代表 IPv6 地址的长度是 IPv4 地址的四倍。

CNAME 记录:规范名称记录,将一个域名设置为另一个域名的别名。当解析器查询一个别名时,会得到它指向的规范名称,然后继续解析规范名称。CNAME 记录常用于将多个名称指向同一个服务,或者将自有域名指向第三方服务提供的域名,例如内容分发网络或云服务。

CNAME 有一个重要的限制:一个设置了 CNAME 记录的名称,不能同时拥有其他类型的记录。由于区域的根节点,即二级域本身,必须拥有用于区域管理的记录,因此二级域本身无法直接设置为 CNAME。为了解决这一问题,许多 DNS 服务商提供了一种非标准的扩展功能,在权威服务器端将别名在查询时直接展开为对应的地址记录返回。

NS 记录:指明负责某个区域的权威域名服务器。授权关系正是通过 NS 记录建立的:上级区域中包含指向下级区域权威服务器的 NS 记录。

SOA 记录:起始授权记录,每个区域都有且仅有一条。它包含区域的主服务器名称、管理员的联系方式、区域的序列号,以及控制区域数据同步和否定缓存的若干时间参数。

MX 记录:邮件交换记录,指明负责接收某个域名的电子邮件的服务器,以及一个优先级数值。发送邮件时,邮件服务器会查询收件人域名的 MX 记录,按优先级从高到低依次尝试投递。多条 MX 记录可以实现邮件服务的冗余。

TXT 记录:存储任意的文本数据。TXT 记录最初没有特定的用途,但如今被广泛用于各种验证和策略声明:

  • 证明对域名的控制权,例如在申请证书或接入第三方服务时,按要求添加一条特定内容的 TXT 记录;
  • 声明邮件发送策略,例如指明哪些服务器有权代表该域名发送邮件,以及邮件签名的公钥和验证失败时的处理策略。这些机制共同用于防范邮件伪造和垃圾邮件。

PTR 记录:指针记录,用于反向解析,即从 IP 地址查询对应的域名。反向解析使用一个专门的域,将 IP 地址的各部分倒序排列后作为域名进行查询。反向解析常用于日志分析、邮件服务器的身份验证等场景。

SRV 记录:服务定位记录,用于指明某种服务由哪些主机提供,包含主机名、端口号、优先级和权重。客户端可以通过查询 SRV 记录,自动发现服务的位置和端口,而不必预先配置。许多通信协议和服务发现机制使用 SRV 记录。

CAA 记录:证书颁发机构授权记录,声明哪些证书颁发机构被允许为该域名签发证书。证书颁发机构在签发证书前必须检查这一记录,如果自己不在允许的列表中,就必须拒绝签发。这降低了证书被错误签发的风险。

HTTPS 和 SVCB 记录:较新的记录类型,用于在 DNS 中提供连接到某个服务所需的更多信息,例如支持的应用层协议、可使用的端口、IP 地址提示,以及用于加密客户端问候的公钥配置。客户端在一次 DNS 查询中就能获得这些信息,从而更快地建立连接,并且解决了二级域本身无法使用 CNAME 的问题。

五、TTL 与缓存

TTL 的作用

每条资源记录都有一个 TTL,它告诉各级缓存:这条记录在多长时间内可以直接使用缓存的副本,而无需重新查询。

TTL 的设置是一个权衡:

  • 较长的 TTL:缓存命中率高,查询延迟低,权威服务器的负载小,在权威服务器短暂故障时,缓存仍然可以继续提供服务。但当记录需要修改时,旧的记录会在各处缓存中存留很久,变更生效慢;
  • 较短的 TTL:记录的变更能够更快地生效,便于进行故障切换和流量调度。但会增加查询的次数,提高延迟,加重权威服务器的负担,并且在权威服务器故障时,缓存很快就会过期,服务受影响更快。

常见的做法是:对于很少变化的记录,使用较长的 TTL,例如数小时到一天;对于需要灵活调度的记录,使用较短的 TTL,例如几十秒到几分钟。

在计划进行重要的 DNS 变更,例如迁移服务器时,一个常用的技巧是:提前将相关记录的 TTL 调低,等待旧的较长 TTL 过期,确保所有缓存都已经采用了新的较短 TTL,然后再进行实际的变更。这样变更可以在很短的时间内在全网生效。变更完成并稳定后,再将 TTL 恢复为较长的值。

否定缓存

当查询的域名不存在,或者域名存在但没有所查询类型的记录时,权威服务器会返回一个否定的回答。这个否定回答同样会被缓存,称为否定缓存。否定缓存的时长由区域 SOA 记录中的一个参数决定。

否定缓存避免了对不存在的名称反复查询,但它也可能带来一个问题:如果在添加一条新记录之前,有人查询过这个名称并缓存了"不存在"的结果,那么在否定缓存过期之前,新添加的记录对这些缓存来说是不可见的。

多级缓存

在一次 DNS 解析的路径上,可能存在多级缓存:

  • 应用程序自身的缓存,例如浏览器和某些语言的运行时;
  • 操作系统的缓存;
  • 本地网络中的缓存,例如家用路由器;
  • 递归解析器的缓存。

多级缓存提高了性能,但也使得 DNS 变更的传播变得更加复杂。某些应用程序或运行时可能不遵守 TTL,例如在进程的整个生命周期中只解析一次,或者使用一个固定的缓存时长。这可能导致 DNS 变更后,部分客户端长时间仍然访问旧的地址。在进行故障切换等操作时,需要考虑这些客户端的行为。

六、区域数据的同步与高可用

主从复制

为了保证可用性,每个区域通常由多个权威服务器提供服务,并且这些服务器应当分布在不同的网络和地理位置上,避免单一故障导致整个区域无法解析。

传统的做法是主从复制:

  • 区域数据在一台主服务器上维护;
  • 若干台从服务器定期从主服务器同步区域数据,这个过程称为区域传送;
  • 从服务器根据 SOA 记录中的序列号判断数据是否有更新:如果主服务器上的序列号大于本地的序列号,就进行同步;
  • 区域传送可以是完整传送,即复制整个区域的数据,也可以是增量传送,即只传输发生变化的记录;
  • 主服务器在数据更新后,可以主动通知从服务器,使其立即检查并同步,而不必等待下一次定期检查。

由于区域传送会暴露区域内的所有记录,应当限制只有授权的从服务器才能发起区域传送,否则攻击者可以借此获取一个组织的全部域名信息。

托管 DNS 服务

在今天,许多组织不再自行运营权威 DNS 服务器,而是使用专业的托管 DNS 服务。这些服务通常借助任播技术,在全球部署大量的服务器节点,提供高可用性、低延迟和抵御大规模拒绝服务攻击的能力,并通过网页界面或编程接口管理记录。

即便如此,DNS 服务商本身也可能发生故障。历史上曾发生过大型 DNS 服务商遭受攻击或出现故障,导致大量依赖它的知名网站同时无法访问的事件。因此,对可用性要求极高的组织,会选择同时使用多个独立的 DNS 服务商,将它们都配置为区域的权威服务器,避免单一服务商成为单点故障。

七、DNS 的工程用途

除了基本的名称解析,DNS 在现代系统中还承担着许多重要的工程职能。

负载均衡与流量调度

为一个域名配置多条 A 记录,递归解析器或客户端可能会在多个地址之间轮流选择,实现简单的轮询负载均衡。

更进一步,许多 DNS 服务提供智能解析功能,根据查询的来源、服务器的健康状态和预设的策略,返回不同的结果:

  • 基于地理位置:根据用户所在的地区,返回最近的服务节点的地址;
  • 基于延迟:根据测量数据,返回对用户而言延迟最低的节点;
  • 基于权重:按照设定的比例,在多个节点之间分配流量,可用于灰度发布;
  • 故障切换:持续检查各节点的健康状态,当某个节点不可用时,自动从解析结果中移除。

这是全局负载均衡最常见的实现方式。如前所述,它受到 TTL 和缓存的限制,切换无法做到即时生效。

内容分发网络

内容分发网络(CDN)在全球部署大量的边缘节点,将内容缓存在离用户更近的地方。DNS 是将用户引导到合适边缘节点的关键环节:网站将自己的域名通过 CNAME 指向内容分发网络提供的域名,内容分发网络的权威 DNS 服务器根据用户的位置和各节点的负载情况,返回最合适的边缘节点地址。

定位用户的挑战

基于 DNS 的流量调度面临一个问题:权威服务器看到的查询来源,是递归解析器的地址,而不是最终用户的地址。如果用户使用的递归解析器距离用户很远,例如用户使用了一个公共 DNS 服务,而该服务的节点位于另一个地区,权威服务器就可能根据递归解析器的位置做出错误的判断,将用户调度到一个较远的节点。

为了解决这一问题,DNS 引入了一种扩展机制,允许递归解析器在向权威服务器查询时,附带用户所在网段的部分信息。权威服务器可以据此做出更准确的调度决策。为了保护隐私,通常只附带地址的前缀部分,而不是完整的地址。不过这一机制本身也引发了隐私方面的讨论,并非所有递归解析器都启用了它。

服务发现

在容器编排平台和微服务架构中,服务的实例经常动态地创建和销毁,地址不断变化。DNS 常被用作一种简单的服务发现机制:每个服务对应一个域名,服务的实例变化时自动更新相应的 DNS 记录,其他服务通过解析该域名找到当前可用的实例。

这种方式的优点是几乎所有的程序和语言都原生支持 DNS,无需引入额外的客户端库。缺点是 DNS 的缓存可能导致客户端获取到过时的地址,并且 DNS 本身不提供健康检查和更复杂的负载均衡能力。

所有权验证

许多服务需要验证用户确实拥有某个域名,例如签发证书、接入邮件服务、验证网站所有权。一种常用的方式是要求用户在域名中添加一条包含特定随机值的 TXT 记录。由于只有域名的实际控制者才能修改其 DNS 记录,服务可以通过查询这条记录来确认用户的所有权。自动化证书签发协议中的一种验证方式,就是基于这一原理。

八、DNS 的安全问题

DNS 设计于互联网早期,当时网络中的参与者之间相互信任,安全性并不是设计的重点。原始的 DNS 协议没有任何身份验证和加密机制,这给它带来了诸多安全隐患。

缓存投毒

缓存投毒(Cache Poisoning)是针对 DNS 最经典的攻击之一。攻击者的目标是让递归解析器的缓存中存入一条伪造的记录,使得所有使用该解析器的用户,在查询某个域名时都得到攻击者控制的地址。

DNS 查询通常使用 UDP 协议。递归解析器向权威服务器发出查询后,会等待响应。如果攻击者能够在真正的响应到达之前,伪造一个看起来来自权威服务器的响应,并且这个伪造响应能够通过解析器的校验,解析器就会接受它并缓存起来。

早期,解析器校验响应的主要依据是一个 16 位的事务标识,只有 65536 种可能。攻击者可以在短时间内发送大量猜测不同事务标识的伪造响应,有相当的概率猜中。

2008 年公开的一种攻击方法使问题变得更加严重:攻击者不再针对某个具体的域名,而是不断地让解析器查询目标域名下大量随机的、不存在的子域名,每次查询都为攻击者提供了一次伪造响应的机会。伪造的响应中不仅包含对这个随机子域名的回答,还在附加部分中包含了将整个目标域的权威服务器篡改为攻击者服务器的引荐记录。一旦成功,攻击者就控制了整个域名的解析。

针对这类攻击,解析器采取了多种防御措施:

  • 源端口随机化:每次查询使用一个随机的源端口,攻击者需要同时猜中事务标识和端口号,猜测空间扩大了数万倍;
  • 查询名称大小写随机化:DNS 名称不区分大小写,但响应会原样复制查询中的名称。解析器随机改变查询名称中字母的大小写,并检查响应中的名称是否与之完全一致,进一步增加了伪造的难度;
  • 严格校验附加记录:只接受与当前查询相关、来自有权威的区域的记录,拒绝那些越权的附加信息。

这些措施大大增加了缓存投毒的难度,但并不能从根本上杜绝伪造。

DNSSEC

DNS 安全扩展(DNSSEC)通过数字签名,从根本上解决了 DNS 数据的真实性和完整性问题。

DNSSEC 的基本原理是:

  • 每个区域拥有一对密钥。区域的管理者用私钥对区域中的记录进行签名,签名作为新的记录类型与原记录一起发布;
  • 解析器在收到记录后,用区域的公钥验证签名,确认数据确实来自该区域的管理者,并且没有被篡改;
  • 区域的公钥本身也发布在 DNS 中。为了让解析器信任这个公钥,上级区域会发布一条记录,包含下级区域公钥的摘要,并由上级区域签名;
  • 这样,从根区域开始,形成了一条信任链:根区域的公钥是解析器预先信任的信任锚,根区域为各顶级域的公钥担保,顶级域为二级域的公钥担保,依此类推。

为了在保证安全的同时方便密钥的轮换,DNSSEC 通常为每个区域使用两类密钥:一类较长期的密钥签名密钥,只用于签名区域的密钥集合,其摘要登记在上级区域中;另一类区域签名密钥,用于签名区域中的普通记录,可以更频繁地更换而无需通知上级区域。

DNSSEC 还需要能够证明某个名称不存在。如果攻击者可以伪造"不存在"的响应,就能阻止用户访问合法的域名。DNSSEC 通过对区域中按顺序排列的名称之间的"空隙"进行签名来实现这一点:一条签名记录声明"在名称甲和名称乙之间不存在其他名称"。早期的方案会使攻击者能够遍历出区域中的所有名称,后来的改进方案对名称进行哈希处理后再排序,增加了遍历的难度,还有一些方案在查询时动态生成最小化的否定证明。

DNSSEC 提供了强有力的安全保证,但它的部署进展一直较为缓慢,主要原因包括:

  • 配置和运维复杂:需要管理密钥、定期更新签名、正确地进行密钥轮换。操作失误可能导致整个区域无法被验证,从而对启用了验证的用户完全不可访问;
  • 响应体积增大:签名记录显著增加了 DNS 响应的大小,可能超出 UDP 的限制,需要回退到 TCP,也加剧了放大攻击的风险;
  • 只保护真实性,不提供机密性:DNSSEC 保证数据没有被篡改,但查询和响应仍然是明文传输的,任何网络观察者都能看到用户查询了哪些域名;
  • 最后一公里的问题:DNSSEC 的验证通常在递归解析器上进行,从递归解析器到用户设备之间的通信,如果没有额外的保护,仍然可能被篡改。

放大攻击

DNS 也常被利用来发动反射放大攻击:

  • 攻击者伪造受害者的 IP 地址作为源地址,向大量开放的递归解析器或权威服务器发送 DNS 查询;
  • 攻击者选择那些会产生很大响应的查询,例如查询带有大量记录或签名的名称;
  • 这些服务器将响应发送给受害者。

由于一个几十字节的查询可能产生几千字节的响应,攻击流量被放大了数十倍。攻击者利用大量的服务器,可以产生规模惊人的流量,淹没受害者的网络。

防御措施包括:不对外开放递归解析服务,只为自己的用户提供服务;在权威服务器上实施响应速率限制,对同一来源的大量相似查询进行限流;在网络层面实施源地址验证,阻止伪造源地址的数据包进入网络。

其他威胁

  • 域名劫持:攻击者通过窃取域名注册账户的凭据,或者利用注册商的漏洞,修改域名的权威服务器设置,从而完全控制域名的解析。保护域名注册账户的安全,启用多因素认证,启用注册商提供的注册锁定服务,都是重要的防护手段;
  • 子域名接管:一个组织的某个子域名通过 CNAME 指向某个第三方服务,例如云存储或托管平台。后来该组织停止使用这项服务,删除了第三方上的资源,却忘记删除 DNS 记录。攻击者随后在该第三方服务上注册了同名的资源,就可以控制这个子域名的内容。定期审查和清理不再使用的 DNS 记录,可以避免这类问题;
  • DNS 隧道:利用 DNS 查询和响应传输任意数据,绕过网络防火墙的限制,或者用于恶意软件与控制服务器之间的隐蔽通信。由于 DNS 流量通常被允许通过,这种手段较难被发现。可以通过分析 DNS 查询的模式,例如异常长的域名、异常高的查询频率、大量不同的子域名,来检测此类行为。

九、DNS 的隐私问题

传统的 DNS 查询以明文传输,这带来了明显的隐私问题。

用户访问的每一个网站、使用的每一个应用,几乎都会产生 DNS 查询。网络路径上的任何观察者,包括本地网络的管理者、网络运营商,都可以看到用户查询了哪些域名,从而了解用户的浏览习惯和行为。在不安全的网络中,攻击者还可以篡改 DNS 响应,将用户引导到恶意网站。

此外,递归解析器本身也能看到用户的全部查询记录。选择哪个递归解析器,实际上就是选择将自己的浏览记录交给谁。

加密的 DNS

为了保护 DNS 查询的隐私,出现了多种对 DNS 通信进行加密的协议:

基于 TLS 的 DNS(DNS over TLS,DoT):在 TLS 连接中传输 DNS 消息,使用一个专门的端口。它提供了加密和服务器身份验证。由于使用专门的端口,网络管理者可以很容易地识别甚至阻止这类流量。

基于 HTTPS 的 DNS(DNS over HTTPS,DoH):将 DNS 查询封装在 HTTPS 请求中,使用与普通网页访问相同的端口。由于与普通的网页流量混在一起,网络观察者难以将其区分出来,也更难以阻止。许多浏览器内置了对这一协议的支持。

基于 QUIC 的 DNS(DNS over QUIC,DoQ):使用 QUIC 协议传输 DNS 消息,兼顾了加密和低延迟,避免了 TCP 的队头阻塞问题,连接建立也更快。

加密的 DNS 也引发了一些争议。在企业和学校等环境中,网络管理者常常依赖 DNS 实现内容过滤、安全监控和内部域名解析。当应用绕过系统配置,直接使用其内置的加密 DNS 服务时,这些管理功能可能会失效。此外,如果大量用户都将查询发送到少数几个大型公共 DNS 服务,也会造成 DNS 基础设施和用户数据的集中化。

查询名称最小化

在传统的解析过程中,递归解析器向根服务器和顶级域服务器发送查询时,会发送完整的域名。但实际上,根服务器只需要知道顶级域部分,就能给出正确的引荐;顶级域服务器只需要知道二级域部分。完整的域名被不必要地暴露给了这些上级服务器。

查询名称最小化是一种改进:递归解析器在向每一级服务器查询时,只发送该级服务器做出回答所需的最少部分。这减少了暴露给中间服务器的信息,且无需对协议进行任何修改。目前许多递归解析器已经默认启用了这一功能。

不经意 DNS

即使使用了加密的 DNS,递归解析器本身仍然能够同时看到用户的身份,即 IP 地址,以及用户查询的内容。不经意 DNS(Oblivious DNS)试图将这两者分离:

  • 客户端用目标解析器的公钥加密查询内容,然后通过一个中间代理发送;
  • 代理知道客户端的身份,但看不到查询的内容;
  • 解析器能够解密并处理查询,但只知道请求来自代理,不知道客户端的真实身份。

只要代理和解析器由不同的组织运营,并且它们不相互勾结,就没有任何一方能够同时知道"谁"查询了"什么"。

十、实践建议

为权威服务提供冗余。 确保区域至少有两个权威服务器,分布在不同的网络中。对于关键业务,考虑使用多个独立的 DNS 服务商,避免单一服务商的故障导致服务完全中断。

根据需要设置 TTL。 对稳定的记录使用较长的 TTL,以提高性能和容错能力;对需要灵活调度的记录使用较短的 TTL。在计划进行重大变更前,提前降低 TTL。

保护域名注册账户。 域名注册账户是控制域名的最高权限。为其启用强密码和多因素认证,开启注册锁定,并确保账户的联系信息有效,以免错过续费提醒导致域名过期被他人注册。

定期审查 DNS 记录。 清理不再使用的记录,特别是那些指向第三方服务的 CNAME 记录,避免子域名接管。限制区域传送,只允许授权的服务器进行同步。

配置邮件相关记录。 为域名配置邮件发送策略相关的 TXT 记录,防止他人伪造该域名发送邮件。即使一个域名不用于发送邮件,也应当发布明确拒绝所有发送的策略。

配置证书颁发授权记录。 声明允许为域名签发证书的机构,降低证书被错误签发的风险。

评估是否启用 DNSSEC。 对于安全要求较高的域名,考虑启用 DNSSEC,并确保使用的 DNS 服务商能够可靠地管理密钥和签名,避免因操作失误导致域名无法解析。

监控 DNS 的可用性和正确性。 从多个地区、多个网络定期查询关键域名,确认解析结果正确、响应及时。监控记录的意外变化,以便及时发现劫持或配置错误。

在应用中正确处理 DNS。 确保应用程序和运行时遵守 TTL,不要无限期地缓存解析结果。在连接失败时,能够重新解析并尝试其他地址。对于长连接,在适当的时候重新解析,以便感知后端地址的变化。

结语

DNS 是互联网最古老的基础协议之一,它以层次化的命名空间、分级授权的管理模式和无处不在的缓存,将全球的命名管理分散到无数独立的组织中,又将它们组织成一个统一、高效、可扩展的整体。几十年来,互联网的规模增长了数百万倍,DNS 的基本架构却几乎没有改变,这本身就是对其设计的最好证明。

与此同时,DNS 也在不断地演进:从最初只提供地址映射,到承载邮件路由、服务发现、所有权验证、安全策略声明、连接参数协商等越来越多的功能;从完全不设防的明文协议,到借助 DNSSEC 保证数据的真实性,借助加密传输保护查询的隐私。

正因为 DNS 处于几乎所有网络访问的起点,它的可用性、正确性和安全性对整个系统至关重要。一次 DNS 配置错误、一个服务商的故障、一次域名劫持,都可能导致服务完全不可用。理解 DNS 的工作原理、缓存行为和安全风险,是每一个构建和运维网络服务的人都应当具备的基础知识。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。