短名 service 经 lab.test、branch.lab.test 两个搜索域分支,分别到 127.0.0.2、127.0.0.3;底部说明绝对名称 service.lab.test. 在两种上下文中保持明确。

有用的主机名应区分本地身份、服务名称与查询范围

有用的名称为人和软件提供一个可以跨地址变化继续使用的引用,但这个引用需要明确范围与负责人。机器的本地主机名、服务 DNS 名称和实例标识可以有意不同。清楚命名有助于理解日志和部署,而不是假定一个标签自动建立系统中的所有其他身份。规划名称时,应先说明它标识的是哪类对象,以及希望保持稳定多久。 坏掉的样子 设置本地主机名,本身不会向权威区域发布 A 或 AAAA。注册可能由独立部署或网络管理软件完成,但那条流程必须实际存在。反过来,修改 DNS 地址也不会重命名内核的本地主机名。混淆两者,会产生本地标签看似正确、客户端却无法发现服务的机器。排障时应分别检查本地状态、注册动作和权威数据,不能用其中一个代替其他证据。 短名称依赖查询上下文。即使两台机器都使用正常 DNS 配置,service 在不同搜索域下仍可能指向不同目的地。复制的运行手册命令因此可能到达与作者测试不同的环境。配置中不能容忍歧义时,应使用完整目标 DNS 名称;交互操作使用短名时,也应保留解释它所需的上下文。名称看起来一样,并不意味着它在所有进程里具有相同范围。 人类可读的含义也有限制。app-prod-01 可以提示角色、环境与实例,却不是权限、归属或当前工作负载的权威证据。复用旧实例名称还可能混淆历史日志。服务名称与替换机器的生命周期不同时,应分别命名,并使用运维元数据记录变化事实,不要试图把所有信息都塞进主机名。方便阅读的前缀也不能成为授予访问权限的依据。 短名继承查询上下文。 依据原文与明确限制静态绘制;未为本图重跑原文夹具。 快速验证 将脚本保存为 check-hostnames.py,准备 Docker 后执行 python3 check-hostnames.py。固定环境使用 BIND 9.18.49、dnsmasq 2.90 和 Python 3.11,解析器及 NSS 配置都位于可丢弃容器中。本实验关闭转发缓存,使搜索域和地址变化可以直接观察,不必等待上一代缓存寿命;这项设置用于隔离变量,不代表所有生产客户端都应关闭缓存: ...

十二月 1, 2026 · 3 分钟 · XB Field Notes
文章的关闭 EDNS 实验中,UDP 返回 462 字节,设置 TC,只含四条 TXT 中的两条;可用 TCP 路径重试返回 892 字节,TC 清除,包含全部四条。

UDP 回答被截断时,DNS 需要可工作的 TCP 路径

DNS 同时支持 UDP 和 TCP。服务器因可用消息空间而截断响应时,会设置 TC 标志。客户端收到该标志,需要处理结果不完整的情况,通常通过 TCP 重新查询。这涉及当前使用的 DNS 响应限制,并不直接证明物理网络无法承载任何更大的 UDP 数据报。排障时应先确认协议层发生了什么,再讨论传输路径的实际容量。 即使包含记录,TC 仍说明回答不完整。可用 TCP 路径能取回完整集合,只提供 UDP 的端点则无法完成。文章还展示消息边界与连接复用;这不表示 DNS 已加密。 坏掉的样子 允许 UDP 五十三端口却阻止 TCP 五十三端口的网络,可能小查询正常,大回答失败。DNSSEC 数据和较大记录集容易暴露这种差异,但 TCP 并不只用于这些特殊情况。通用 DNS 实现需要支持 TCP,客户端也可以直接选择它。因此,一次小型 UDP 查询成功,不能证明整个 DNS 服务的传输路径完整,尤其不能代替对 TCP 监听和访问规则的检查。 ...

十一月 19, 2026 · 3 分钟 · XB Field Notes
原文的本地示例中,IPv6 仍排在候选列表首位,但已停止的监听拒绝连接;按序尝试的客户端随后通过 IPv4 成功。

双栈地址排序与最终成功的连接选择是不同步骤

发现 A 与 AAAA 记录,只提供可能的目的地,本身不会选出成功连接。地址排序、源地址选择、路由以及应用连接算法都会参与结果。RFC 6724 描述默认源地址和目的地址选择规则,应用仍可作自己的选择。如果程序只请求 IPv4,那么在任何双栈连接策略开始工作前,它就已经缩小了候选范围。解释行为时,应先确认实际调用方请求了什么。 坏掉的样子 地址偏好不是应用健康探测。某个 IPv6 目的地可能符合本地策略和路由条件,远端服务却已经停止,或者更后面的网络跳点会丢包,因此优先候选仍可能失败。如果假定操作系统已经测试了返回列表中每个端点,就会忽略连接截止时间和尝试其他地址的必要性。查询成功只能证明获得候选信息,不能代替服务通信结果。 RFC 6724 的规则是按顺序比较条件,并不是对网络成本或速度打一个总分。相关属性包括可用性、作用域、策略标签、优先顺序和匹配前缀,但它们不测量应用响应时间。目的地址选择还应与路由表最长前缀匹配区分:后者决定已选目的地的数据包如何发送。混用这两个阶段,会把主机偏好错误解释成已经知道整条路径延迟最低。 Happy Eyeballs 属于另一层,通过协调地址发现和错开连接尝试,减少某个地址族出问题时的等待。按顺序逐个尝试地址的客户端,并不自动实现该算法。立即拒绝连接与静默丢弃连接尝试,可能造成非常不同的等待时间,即使最后都能通过 IPv4 成功。不能只看最终用了另一个地址族,就把过程统称为相同的快速竞速机制。 首个候选只代表偏好,不能证明服务健康。图示 IPv6 优先顺序仅属于原文的本地进程。网络示例执行仍受阻,本草稿未重跑。 快速验证 将脚本保存为 check-address-selection.py,准备 Docker 后执行 python3 check-address-selection.py。固定环境使用 glibc 2.36、Python 3.11,以及提供 DNS 的 BIND 9.18.49 和 dnsmasq 2.90。两个真实 HTTP 监听分别使用 IPv4 与 IPv6 回环,端口相同。实验没有公网路径,因此观察到的排序明确属于这个本地环境,不作为所有客户端的默认承诺: ...

十一月 4, 2026 · 3 分钟 · XB Field Notes
客户端宣告 4096 字节,但文章服务器把 UDP 限制为 1232。截断回答可能需要 TCP;实际交付仍依赖路径。

EDNS 宣告 UDP 容量,不保证沿途网络交付

EDNS 通过 OPT 伪记录扩展 DNS,其中一项作用是让请求发送方宣告自己准备接收的 UDP 载荷大小,从而允许回答超过传统五百一十二字节 DNS 限制。这是 DNS 交换中的容量宣告,不是网络路径 MTU 发现协议,也不承诺所有中间设备都会交付相同大小的数据报。理解这一区别,才能准确解释大回答为何仍可能失败。 图中数值来自文章明确的回环配置与记录的 DNS 消息长度,不是统一默认值或路径 MTU 测量。OPT 宣告容量,客户端仍须理解 TC 并保留 TCP 访问。 坏掉的样子 客户端宣告四千零九十六字节,不会强迫服务器发送同样大小的响应。服务器可以实施更小的发送上限;需要的回答放不下时,可以返回 TC,客户端仍需可工作的 TCP 路径。增加客户端数字,不能修复服务器有意采用较小预算的策略。应查看两端实际配置与返回内容,而不是把请求里出现的大数值当成双方已承诺一定使用的大小。 ...

十月 28, 2026 · 3 分钟 · XB Field Notes
无别名直接查询中,NXDOMAIN 表示名称缺失,NODATA 表示请求类型缺失。权威负向寿命取 SOA TTL 与 MINIMUM 中较小值。

负向 DNS 回答会把不存在的数据记到缓存寿命结束

DNS 可以通过说明数据缺失提供有效信息。NXDOMAIN 表示名称错误,NODATA 则描述成功响应中没有所请求类型的数据。对于没有别名的直接查询,两者区分名称不存在,以及名称存在但缺少该类数据。缓存这些结果,可以避免每次客户端请求都重新进行相同的无结果上游查询。负向回答也是有内容、有寿命的状态,并不是“没有收到任何东西”。 先分类回答,再解释缓存。来源中的 SOA TTL/MINIMUM 组合 8/4 和 2/9 分别产生四秒和两秒寿命。负向条目可能在权威发布后继续存在。SERVFAIL、超时与验证失败使用另一类失败缓存规则。历史解析器示例未重跑。 坏掉的样子 部署已经创建正确记录,先前缓存过缺失结果的客户端却可能仍然失败。权威返回新数据,缓存则在寿命结束前继续返回旧否定结果。反复删除重建记录,不会使远端缓存自动失效。这种情况常出现在应用提前查询尚未配置完成的服务名称时;排障应对照查询发生时间和缓存寿命,而不是只检查现在的区域文件是否包含记录。 仅凭回答区为空,不能完整分类 DNS 结果。需要检查响应码、权威区和可能存在的别名链。转介与权威否定回答不同,NXDOMAIN 也可能指向 CNAME 最终目标,而非最初请求的别名本身。把所有空结果都说成“域名不存在”,可能让调查去改错误的记录。应保留原始问答的类型、名称及各区数据,避免过早简化成一句错误描述。 对于 RFC 2308 规定的权威 NXDOMAIN 和 NODATA,负向寿命取 SOA.MINIMUM 与 SOA 记录 TTL 中的较小值。该值放在否定回答的 SOA TTL 上,再由缓存继续递减。MINIMUM 不是所有正向记录 TTL 的统一下限;只改变将来正向记录的 TTL,也不会缩短已经缓存的不存在结论。操作时应确认正在调整哪类数据的哪一代寿命。 ...

十月 22, 2026 · 3 分钟 · XB Field Notes
配置信任锚通向父区签名的 DS 记录集。DS 摘要标识子区 DNSKEY,再沿子区密钥关系验证签名记录集。父区不直接签署子区密钥。

DNSSEC 验证签名数据链,不只检查签名是否存在

DNSSEC 为 DNS 数据增加来源认证和完整性检查。RRSIG 对记录集签名,DNSKEY 发布验证密钥,父区 DS 则通过摘要标识一个子区 DNSKEY。父区签名的是自己的 DS 记录集,不是简单直接签署子区公钥。验证从配置的信任锚出发,沿这些关系抵达所请求数据。理解链中每类记录的责任,才能准确定位发布与验证之间的差异。 摘要边标识子区密钥;签名边验证记录集。来源使用本地 lab.test 锚,不测试公共根或注册商路径。经认证的无 DS 委派属于不安全状态,与损坏的安全链不同。制图未执行 DNSSEC 实验,也未创建密钥。 坏掉的样子 如果委派没有建立预期信任路径,仅发布签名并不足够。缺失 DS 可能让子区处于不安全状态,错误 DS 则可能让原本应安全的子区验证失败;这是不同状态。已经安全证明不存在 DS,并不要求把每个未签名或独立签名的子区回答都当成无效数据拒绝。不能把“没有形成认证链”和“已有安全链却证明失败”混成一种结果。 ...

十月 21, 2026 · 3 分钟 · XB Field Notes
choice.lab.test 走两条解析路径:在 files dns 策略下,glibc 应用取得 hosts 中的 127.0.0.9;直接 dig 权威查询取得 DNS 中的 127.0.0.2。

解析顺序取决于应用及其名称服务路径

主机名查询首先由具体程序发起。在 Linux 上,使用 glibc 名称服务接口的应用,可以依照 /etc/nsswitch.conf 中 hosts 项列出的服务查询;使用自有 DNS 客户端的程序则可能走另一条路径。并不存在所有应用都遵守的“先缓存、再 hosts、最后互联网”固定顺序。定位问题的起点是实际调用方,而不是凭操作系统名称假定完整流程。 同名可以经本地文件与直接 DNS 得到不同结果。修改上游记录前,先检查 NSS 动作、调用标志和实际进程环境。此图整理文章中的机制,未重跑实验。 坏掉的样子 当 files 位于 dns 前面时,hosts 文件条目可以覆盖正确的 DNS 回答。修改权威区域不会删除这个本地覆盖。直接 DNS 查询可能已经看到新地址,应用却仍使用本地文件中的旧值;这两项观察可以同时正确,因为它们实际回答的是不同来源的查询。仅凭 dig 正常就认定应用一定使用同一个地址,会漏掉最直接的配置原因。 ...

八月 2, 2026 · 3 分钟 · XB Field Notes
DNS 切换时,新端点已准备就绪,旧端点继续服务。两者重叠持续到观察阶段;修改 TTL 不会改写已有缓存应答。

DNS 变更需要一个感知缓存的回滚窗口

提前准备 TTL,观察权威与递归应答,并让两个端点在整个缓存窗口内都有效。

六月 18, 2026 · 1 分钟 · XB Field Notes