dnsmasq 内,转发缓存随 TTL 老化,host-record 则来自配置。SIGHUP 清转发缓存,配置记录仍保留,即使本地 TTL 为零。

dnsmasq 区分转发缓存与本地配置名称

dnsmasq 可以向上游转发 DNS 查询,在有界缓存中保留支持的回答,也可以提供本地配置的名称。这些是不同的数据来源。重复得到相同回答,可能来自缓存命中,也可能来自本地配置。主机名与权威数据不一致、或者清缓存后仍然解析到原地址时,先确认来源十分重要;否则容易把有效配置误认为没有清干净的缓存。 先识别回答来源。转发缓存与本地配置名称具有不同寿命:本地 TTL 零不等于删除配置。SIGHUP 清缓存并重载特定数据来源,通常不重读主配置。次数与地址复述文章历史示例,本次没有重跑。 坏掉的样子 启动 dnsmasq,不会自动让所有应用使用它。客户端必须把 DNS 查询交给预期监听,有的应用还会使用其他解析服务。同样,本地监听正常,也可能转发到错误上游或者读取了意外 hosts 配置。在增加缓存容量或重启服务前,应先确认真实查询路径。如果失败查询根本没到达这个进程,对它反复操作不会改变调用方看到的结果。 本地名称可以有意覆盖上游数据。清理转发缓存不会删除这个配置名称,因此反复清空也不能让上游地址获胜。应把本地记录当作有负责人、有用途的配置管理。即使回答的本地 TTL 为零,dnsmasq 仍可持续返回该值,因为它来自配置生成,不是靠保留某份转发回答维持。零 TTL 与删除本地配置并不是同一件事。 缓存容量和新鲜度解决不同问题。更大缓存可以保留更多合适条目,却不会延长条目的有效 TTL,也不会让上游故障期间所有名称都能查询成功。新名称与过期条目仍需要合适的解析路径。缓存大小也不直接代表可同时发送多少上游查询,更不能单独保证应用可用。应分别观察容量、寿命、并发与上游健康,而不是用一个参数代替所有约束。 快速验证 将脚本保存为 check-dnsmasq.py,准备 Docker 后执行 python3 check-dnsmasq.py。固定环境使用 dnsmasq 2.90 和 BIND 9.18.49。实验转发器忽略环境中的 resolv 和 hosts 文件,明确绑定回环监听,并只转发到自己的临时权威服务器。它不发布宿主端口,没有 DHCP 配置,结束后清理自己的实例,不影响现有服务: ...

四月 15, 2028 · 2 分钟 · XB Field Notes
文中三次查询相隔 1.2 秒:TTL 1 时回源三次,TTL 20 时回源一次。到期本身不会安排查询。

DNS TTL 在重复回源查询与保留旧回答之间取舍

DNS TTL 是附着于缓存数据的寿命,不是每秒执行的刷新任务。只要条目仍被保留且有效,缓存可以复用它;过期后的下一次请求通常需要重新解析,除非启用了其他明确行为。无人查询的记录,并不一定在 TTL 归零时主动产生上游请求。因此讨论成本时,要同时看请求到达方式与缓存状态,不能把 TTL 直接当成定时查询频率。 文中受控示例将三次查询间隔设为 1.2 秒:TTL 1 回源三次,TTL 20 回源一次。下游收到剩余寿命,而非重置的 TTL。此图复述来源所述行为,本次制图没有运行解析器实验。 坏掉的样子 持续查询相同数据时,缩短 TTL 可能增加上游工作,却不会让所有权威流量按同一个固定倍数增长。查询频率、解析器共享程度、缓存容量、预取和名称多样性都会影响结果。一个热门名称使用短 TTL,与大量只问一次的名称流,行为不同。没有这些负载条件,就无法仅凭 TTL 数字预测真实查询量或容量需求。 长 TTL 允许在权威数据修改后继续使用先前回答。该缓存仍可能符合最初收到的寿命要求,尽管内容已经不同于最新区域。把所有不一致都叫成过期或损坏,会混淆实际契约。TTL 表示允许保留多久,不承诺持续与权威同步。修改 TTL 同样不能追溯改变已经保存的更长寿命,需要等那些旧副本自然退出普通有效期。 多层转发通常不会让每一跳重新获得原始完整 TTL。缓存返回剩余寿命,下一层再继续计时。按层数累加完整 TTL,会虚构普通合规转发并不产生的传播延迟。本地 TTL 覆盖、提供陈旧回答等是另外的配置行为,存在时应明确识别。不能先假设所有解析器都遵守同一种特殊策略,再用这个假设解释实际观测。 ...

三月 1, 2028 · 2 分钟 · XB Field Notes
IPv4 DNS 传输承载 AAAA 中的 IPv6 地址;验证服务需要另行连接。

AAAA 发布 IPv6 地址,不证明该地址可达

一条 AAAA 资源记录保存一个一百二十八位 IPv6 地址,A 记录则保存 IPv4 地址。同一个名称可以只有其中一类、同时拥有两类,或者在每类中包含多个地址。A 与 AAAA 属于不同记录集,因此可以使用不同 TTL。发布 AAAA 让地址能够通过 DNS 被发现,却不会替你创建接口、路由、监听套接字或可用应用;这些条件需要在实际服务路径上成立。 AAAA 发布的 IPv6 数据独立于 DNS 查询传输。文章实验另行验证本地 HTTP 可达性,不证明公网 IPv6 连通性或主机名 TLS。 坏掉的样子 AAAA 查询成功之后,连接仍可能失败。发布的地址可能已经停用,服务可能只监听 IPv4,网络也可能缺少可用 IPv6 路由。两种地址族的防火墙与 TLS 配置也可能不同。只通过 IPv4 做可用性检查,会漏掉这些问题,而双栈用户可能正沿着公开的 IPv6 路径遭遇延迟或错误。记录存在与服务可用是两个需要分别观察的事实。 ...

十二月 30, 2027 · 3 分钟 · XB Field Notes
来源示例中,主服务器在序列号 10 改为 127.0.0.3,副本仍保留 127.0.0.2。提升为序列号 11 后,副本取得新地址。

区域传送按明确授权与序列号规则复制权威数据

AXFR 传送一个完整 DNS 区域,让另一个服务器或获授权客户端取得数据,副本随后可以依据本地副本提供权威回答。协议不会神奇地识别调用方一定是合法权威服务器,谁能传送由访问控制决定。区域也是明确的权威边界,不等于所有委派子区域的记录,更不是整个组织的 DNS 命名空间。描述复制范围时,应以实际区域内容为准。 同时比较序列号与真实数据。来源中 10 到 11 的修复是具体案例;一般比较使用三十二位序列算术。完整传送边界、TSIG 授权与 SOA 过期各自需要检查。本次未重跑区域传送实验,也未生成共享秘密。 坏掉的样子 修改主服务器数据却不更新 SOA serial,可能让副本以相同版本号提供不同内容。重载主服务器,不会强迫所有副本替换看起来没有变化的区域。DNS 序列号比较使用三十二位序列算术,包括回绕规则;看起来像日期的数字只是运维约定,并不独立保证任何数值修改都表示更新。排查副本差异时,应同时看版本比较与真实数据。 不限制区域传送,可以让任意请求客户端一次取得完整区域内容。来源限制与 TSIG 可以控制访问,但配置语义必须正确。尤其在普通 BIND 允许列表里同时列出地址和密钥,不会自动成为两者都必须满足的条件。应审阅实际访问规则,并从相关来源测试未授权请求,不能因为配置里出现两项限制,就假定它们按预想的逻辑组合生效。 ...

十二月 5, 2027 · 3 分钟 · XB Field Notes
TLS 边界保护客户端到解析器的连接。所选解析器能读取 DNS 问题,后续递归不会自动加密。

DoT 与 DoH 保护通往已认证解析器的连接

DNS over TLS 和 DNS over HTTPS 保护其端点之间加密连接上的 DNS 流量。对于典型客户端,这条连接终止于选定解析器;解析器能够读取问题与回答,它随后发出的查询还可能使用不同传输。加密这一跳,不会自动加密整个递归过程,也不会让解析器失去记录所处理名称的能力。隐私范围应按真实连接边界说明,而不是笼统称为整个 DNS 都已保密。 分别观察加密边界与认证证据。853/443 为常用协议端口;8531/8443 属于文章的回环实验。证书失败诊断不能被零退出码掩盖。本图仅依据来源制作:加密 DNS 运行审阅仍待完成,实验未重跑。 坏掉的样子 加密套接字如果没有按预期验证证书,也可能连接到错误端点。应同时验证证书信任链和客户端期望的解析器身份;握手成功本身不能证明这两项检查已启用。失败时悄悄改用其他解析器或明文路径的配置,也会改变隐私契约。需要通过真实调用方了解这些行为,不能只看到配置文件中有一个 TLS 或 HTTPS 地址,就认定所有查询都符合预期。 DoH 使用 HTTPS,但四百四十三端口不会让它在所有网络中都无法识别、无法阻止或完全等同于任意网页流量。目的地址、连接时间和其他元信息仍可观察,TLS 终止点还可以检查明文 HTTP。选择解析器和传输策略时,应考虑这些边界,不能假定 HTTPS URL 会消除所有与 DNS 活动有关的信息暴露,也不能由加密推导解析器不会保存日志。 ...

十月 7, 2027 · 3 分钟 · XB Field Notes
三个依赖框显示 alias、middle、target,分别标注同一回答中独立的 9、12、20 秒 TTL。独立 HTTP 身份栏保留 Host 为 alias.lab.test 加临时端口。箭头表示 DNS 依赖,不是 URL 重定向。

CNAME 改变 DNS 解析路径,请求主机名仍保持原样

CNAME 记录把一个别名与另一个 DNS 名称关联起来。通过别名解析地址时,解析器沿目标继续查找,直到获得请求的数据或遇到失败。这可以让公开主机名保持稳定,同时改变它背后的 DNS 依赖。它不会让浏览器跳转到另一个 URL,也不会替换应用正在请求的主机名;是否改变客户端可见地址,应由相应应用协议行为决定。 坏掉的样子 别名解析完全正常,目标服务器仍可能返回错误网站。HTTP 继续标识原始主机名,HTTPS 证书验证也关联所请求的服务身份。如果只配置目标名称对应的虚拟主机或证书,原别名请求未必能够工作。DNS 提供的是获得地址的路径,选中的服务器还必须接受用户和应用真正请求的名称。仅检查最终 IP 相同,无法验证这项应用契约。 CNAME 不能与普通 A、AAAA、TXT 等数据共存于同一个所有者名称。DNSSEC 元数据存在特定例外,但这不会让 CNAME 与 A 共存变得有效。普通区域顶点本来就需要 SOA 和 NS,因此在顶点放传统 CNAME 会产生冲突。服务商提供的别名展平等功能,应依据其实际文档理解,不能把界面里类似的名称直接当成标准 CNAME 规则发生变化。 别名链可能终止于不存在的数据,也可能形成循环。每个依赖还有自己的缓存寿命与管理边界;缩短别名 TTL,不会缩短以另一个记录集缓存的目标地址。同时,并非每增加一个别名都必然增加一次网络往返:服务器可能在同一回答中附带多段链,解析器也可能已经缓存相关数据。延迟分析应结合实际问答,而不是机械按链长计数。 解析别名,保留请求身份。 依据原文与明确限制静态绘制;未为本图重跑原文夹具。 快速验证 将脚本保存为 check-cname.py,准备 Docker 后执行 python3 check-cname.py。固定环境使用 BIND 9.18.49、dnsmasq 2.90 和小型 HTTP 服务。所有名称均属于隔离测试区域;解析配置修改和候选区域文件留在可丢弃容器内部,不改公共域名或宿主解析器。运行结束后,脚本清理自己创建的实例和临时镜像标签: ...

七月 9, 2027 · 3 分钟 · XB Field Notes
DNS 回答在 A、B 与 B、A 顺序之间轮换,但文章示例的应用保留一次选择,将十二次请求发给选中端点,另一端点收到零次。

多个 DNS 地址不保证流量均匀或端点健康

同一名称下的多条 A 或 AAAA 记录提供一个地址集合。DNS 服务器可能轮换返回顺序,但收到集合后如何使用,由解析器和应用决定。普通地址记录不携带请求负载测量或应用健康结果;仅仅存在多个地址,不能保证均匀流量、自动故障转移,甚至不能保证不同实现看到相同的第一个地址。应将地址发现与后续选择分别理解。 轮换地址集合不会按应用请求调度,也不会自动检测端点健康。文章中的一次保存选择造成十二比零分布,恢复依赖客户端明确重试。此图未新增运行验证。 坏掉的样子 DNS 回答分布与应用请求分布的分母不同。一个递归解析器可以用缓存回答许多客户端,一个应用也可能只查询一次,随后发出数千次请求。连接池会进一步强化这种差异。即便权威回答中的首个地址完美交替,实际服务器请求量仍可能严重不均。只统计 DNS 查询数量,不能证明用户业务已经按同样比例分配。 普通静态记录集中的端点失败后,其地址仍会保留,直到 DNS 数据被修改或另一个系统主动修改它。DNS 服务器不会仅因返回地址就知道应用健康状态。有的客户端连接失败后会尝试其他地址,有的会耗尽截止时间或者直接向调用方报错。是否重试、何时重试及哪些操作可重试,都应针对实际客户端和业务验证,不能默认由 DNS 完成。 把这种机制描述成保证公平的抛硬币,也不准确。顺序可能由配置决定、被随机化、被缓存保留,或者被地址选择策略重排。客户端可能选择首项、并发尝试,或复用先前结果。要解释一次分布观察,除了后端请求计数,还需要知道 DNS 配置、解析器行为、连接复用和工作负载;少了这些条件,无法判断不均衡出现在哪一层。 快速验证 将脚本保存为 check-dns-addresses.py,准备 Docker 后执行 python3 check-dns-addresses.py。固定环境使用 BIND 9.18.49,并明确把 rrset-order 设置为循环顺序。两个真实 HTTP 监听在隔离容器中绑定不同回环地址、使用相同临时端口,响应正文标识真正处理请求的端点。脚本不依赖公网域名,也不会访问现有业务服务器: ...

七月 6, 2027 · 3 分钟 · XB Field Notes
健康的优先级 10、权重 1 目标先于优先级 20、权重 65535 备机;客户端在连接失败后回退。

SRV 提供目标和端口,客户端必须理解其选择规则

SRV 通过优先级、权重、端口和目标主机名描述服务位置。它的所有者通常组合服务标签、传输标签与域名,例如 _echo._tcp.lab.test。理解该服务的客户端可以先查 SRV,再通过 A 或 AAAA 取得目标地址,连接记录给出的端口。普通主机名查询不会自动执行这套应用相关的发现流程,服务名与查询方式必须由调用方契约明确。 优先级选择可达的组,权重只在同组内起作用。文章每组只有一个目标;故障转移展示客户端处理,不是同组加权选择或 DNS 健康摘除。 坏掉的样子 发布 SRV 不会让所有现有客户端自动采用它。应用需要规定服务标签,并实际支持相应发现行为。只接受普通主机名和配置端口的浏览器或库,可能根本不询问 SRV。因此,手工查询 SRV 成功,不能证明应用已经改变端点选择,也不能据此宣布今后不再需要更新配置。验证应沿真实调用方进行,不能止于区域里已有记录。 优先级和权重不是可互换字段。在可达目标中,较低数值优先级更优先;权重只影响相同优先级记录之间的选择。较高数值备机即使具有很大权重,也不能越过可用的低数值目标。把所有记录按权重统一排序,或直接采用报文中的首项,都可能反转服务所有者设计的主备关系。解释结果前,应确认客户端是否正确使用这些字段。 发现也不证明健康。监听停止后,目标仍可继续被发布,SRV 与目标地址记录集还具有各自缓存寿命。客户端需要连接截止时间与适当重试策略。连接被拒绝后重试读取,与重复可能已产生副作用的操作不同;端点故障转移必须符合应用协议,不能因为还有候选项,就无条件把每个业务动作再执行一遍。 快速验证 将脚本保存为 check-srv-discovery.py,准备 Docker 后执行 python3 check-srv-discovery.py。固定 BIND 9.18.49 环境发布测试 _echo._tcp 服务,两个真实 HTTP 监听在不同临时端口提供可识别的只读响应。HTTP 只是实验中便于观察的载荷;示例是自定义 SRV 客户端,不代表通用 HTTP 客户端本来就实现了这个服务标签: ...

三月 13, 2027 · 3 分钟 · XB Field Notes