DNS 协议中 SOA 是干嘛的?好像域[2026/8/17 15:23:43]
 

查看: 6  |  回复: 0
 DNS 协议中 SOA 是干嘛的?好像域名认证需要它?
楼主
发表于 今天 13:38 

DNS SOA 记录

SOA(Start of Authority,起始授权记录),是一个 DNS 区域(zone)的核心记录,代表这个域名区域的权威信息起点,每个 DNS 解析域必须有且仅有一条 SOA 记录,它和域名认证有间接关系,但本身不是认证记录。

SOA 主要作用

标记谁是本域的权威 DNS 服务器标明这个域名由哪一台主 DNS 服务器负责,同时写上域名管理员邮箱。

控制区域数据同步(主从 DNS 服务器)从服务器依靠 SOA 里面的参数,判断要不要从主服务器同步域名解析数据。

定义这套 DNS 记录的 TTL / 刷新 / 重试 / 过期时间SOA 里面有 5 个时间参数,管控从服务器缓存、拉取、失效的行为。

一条典型 SOA 记录示例

example.com.  IN  SOA  ns1.example.com. admin.example.com. (
   2026081701   ; Serial 序列号
   3600         ; Refresh 从服务器多久来刷新(秒)
   600          ; Retry 刷新失败重试间隔
   86400        ; Expire 如果一直连不上主服务器,多久之后放弃解析
   300          ; Minimum TTL 否定缓存TTL(查不到记录时缓存多久)
)

各字段含义:

Serial(序列号):最重要,主 DNS 修改解析记录后,要把这个数字 + 1。从服务器发现序列号变大,就知道有更新,就同步新记录。一般用年月日+序号格式。

Refresh:从服务器隔多少秒向主服务器查询有没有更新。

Retry:刷新失败,隔多久重试。

Expire:如果长期连不上主 DNS,从服务器最多还能继续提供多久解析,超时后直接宣告该区域失效,不再返回解析结果。

Minimum TTL:NXDOMAIN 缓存时间,域名不存在的结果会被缓存这个时长。

SOA 和域名认证是什么关系?

SOA 本身不做域名认证,但很多域名所有权验证场景会间接依赖它。

域名所有权认证(比如 SSL 证书、企业微信、DNS 验证、谷歌搜索控制台)常用两种方式:

添加 TXT 记录(主流)

添加 CNAME 记录不是 SOA。


那为什么很多资料会提到 SOA?

① 通过查询 SOA,可以知道这个域名当前用的是哪家 DNS 服务商。比如你要做 DNS 验证,首先看 SOA 就知道你的域名解析托管在哪,就要去那家平台添加验证记录。

例:查域名 SOA,发现是阿里云 DNS 服务器,那就要去阿里云 DNS 后台加 TXT,不要跑到别的服务商。如果你改了 NS 服务器,SOA 记录也会跟着变。

② DNSSEC(DNS 安全扩展)会用到 SOA:DNSSEC 给域名解析做签名防篡改,SOA 区域是 DNSSEC 签名保护的对象,用来证明解析记录真实性,这才是 DNS 层面的 “认证”。

容易混淆

记录-作用

SOA    区域权威元数据,主从同步、时间参数    

TXT    存文本,域名所有权验证、SPF、DKIM    

DNSSEC    对整个 zone 签名,防 DNS 劫持篡改,依赖 SOA 区域    

NS    列出域名的 DNS 服务器列表,SOA 指定其中一台为主服务器    

小实操,你可以在本地测试查询 SOA

windows/mac 终端:

dig example.com SOA

总结:

SOA = DNS 区域的 “总说明书”,记录主 DNS、管理员、同步 / 缓存时间,每个域名 zone 必备。

本身不直接用来做域名所有权认证,但是:

SOA 能看出你当前域名托管在哪家 DNS;

DNSSEC 安全认证,以 SOA 为区域起点做签名。

我们平时申请证书、平台验证域名所有权,用的是 TXT 记录,不是修改 SOA。

1楼
发表于 今天 13:48 

Serial 如果减少,会被认为是变动吗?

SOA Serial 序列号减小会发生什么

核心结论:Serial 变小,从服务器会认为:区域没有更新,拒绝同步,不会拉取新记录。DNS 从服务器逻辑非常简单:

如果 收到的Serial > 本地保存的Serial → 有更新,执行区域传送(AXFR/IXFR)同步数据

如果 收到的Serial ≤ 本地保存的Serial → 认为版本一样 / 更旧,不做任何同步

👉 Serial 减小 ≠ 触发更新,反而被当作旧版本直接忽略。

举例子

从服务器本地保存 Serial:2026081701

主服务器 Serial-从服务器行为

2026081702(更大)    大于本地 → 同步新解析数据 ✅    

2026081701(相等)    等于 → 忽略,不同步    

2026081699(变小)    小于 → 判定为旧版本,直接拒绝同步 ❌    

坑场景:你改了主 DNS,手滑把 Serial 改小,哪怕解析记录全部变了,从服务器完全不会更新,外网一直看到旧解析。

那我必须把 Serial 改小怎么办?(回滚版本)

比如你用了日期格式YYYYMMDDNN,不小心跳到明天,现在想回退,数值变小了。标准 DNS 有一个专门机制:Serial Number Art(序列号算法,RFC 1982),是 32 位无符号整数的环形比较。

RFC1982 规则:

当两个 32 位序列号 A、B:A 被认为比 B 新,当且仅当0 < (A − B) < 2^31

简单理解:最多往前 “跳” 2¹⁰⁷³⁷⁴¹⁸²³(2^31‑1),不能跳更大的差值。

举个 32 位环形例子:本地旧 serial = 100如果你设置新 serial = 40000000004000000000 − 100 大于 2^31,从机认为 40 亿是更旧版本。

如果你需要强制回滚、把版本号往低走:

方案 A(稳妥推荐):直接往上加,不要减小,不要回退数字。哪怕是回滚解析内容,Serial 依然 + 1。

解析内容恢复旧内容,序列号继续递增,从服务器正常同步。绝大多数 DNS 面板(阿里云、Cloudflare、Bind)都是这么干的,你改记录后台自动 + 1Serial。

方案 B:迫不得已要降低 Serial

新 serial 需要比旧 serial大半个 32 位环以内(差值小于 2^31),RFC1982 才识别为新版本。

如果差值太大,RFC 算法失效,此时只能:全部从服务器删除该 zone 缓存,强制重新拉取。普通云 DNS 服务商你没法操作从服务器,所以这个方案几乎用不上。

⚠️ 现实生产:不要依赖 RFC1982 做回滚,很多简易 DNS 实现、部分老旧从服务器没有严格实现 RFC1982,只做简单整数大小比较,环形算法直接失效。

常见踩坑

手动写 BIND 配置,修改解析记录忘记增加 Serial → 从服务器永远不更新。

把 Serial 写成时间戳,跨年后手贱改小,解析死活不生效。

迁移 DNS 服务商:新服务商 SOA Serial 比旧的小,NS 切过去之后,部分老从服务器不刷新记录,出现解析撕裂。

迁移 DNS 时,新 DNS 的 Serial 建议设置成一个很大的数字,高于旧 DNS 的 Serial。

补充:云 DNS(Cloudflare / 阿里云 DNS)

你看不到 Serial,后台自动维护,每次修改记录自动 + 1,用户不用管;只有自建 BIND、PowerDNS 手动编辑 zone 文件的时候,才需要手动维护 Serial。

一句话总结:

Serial 单纯数字减小,绝大多数情况从服务器判定为旧版本,不会触发同步。

回滚解析,正确做法:解析记录恢复旧值,Serial 仍然递增 + 1,不要减小序列号。

RFC1982 环形算法理论支持有限范围 “往小跳”,生产环境不建议依赖,兼容性风险高。

2楼
发表于 今天 13:48 

如果一不小心把 Serial 变很大了,需要变小有办法吗?

前提:Serial 是32 位无符号整数,范围 0‑4294967295;RFC1982 环形比较,单次增量不能超过 2¹⁰⁷³⁷⁴¹⁸²³(2^31‑1)。

场景举例:手滑写成 3500000000,想回到日常格式2026081701,直接改成 2026081701 会直接悲剧:所有从服务器看到主 Serial 变小,拒绝同步,永远拿不到新记录。

一共有 3 套方案,按现实生产可行性排序。

方案 1:你能管控全部从服务器(自建 BIND,自己有所有 slave 的 shell)✅最稳妥

主 DNS 直接改成你想要的小 Serial,zone 文件写好,重载。

每一台从服务器执行强制全量拉取,忽略 Serial 判断:

bash

rndc retransfer example.com

这条命令直接删掉本地 zone 副本,主动 AXFR 从主服务器拉全新数据,完全不理会 Serial 大小。

缺点:只适合你完全掌控所有辅助 DNS。如果用第三方云辅助 DNS、公共从服务器,你执行不了对方机器命令,不能用这个方案。

方案 2:RFC1982 环形回滚(不用碰从服务器,标准官方流程)

原理:利用 32 位无符号数环形;一次最多加 2147483647,不能超过。

步骤:

当前错误大 Serial = S_big

计算中间值:S_mid = ( S_big + 2147483647 ) mod 4294967296

把主 DNS Serial 设置为S_mid,重载 zone,等待所有从服务器全部同步到这个 S_mid

等待时间建议:Refresh时间 ×2,确保全部 slave 拿到 S_mid。可以 dig 每台从服务器 SOA 确认。

全部从机已经拿到 S_mid 之后,再改成你想要的小目标 Serial S_target,重载 zone。此时 S_target 相对于S_mid的增量在 2^31‑1 以内,RFC1982 判定为新版本,从服务器正常同步。

举个例子:

当前错误 Serial:3500000000

加 2147483647,取模 4294967295,得到中间值

主 DNS 先设置中间值,等全部从服务器同步完成

再改成目标:2026081701

⚠️ 巨大风险点

有部分老旧 DNS 实现只做简单整数对比,不实现 RFC1982 环形算法,这套流程对它们无效,依旧拒绝更新。

等待窗口期间不能做任何其他 zone 修改;必须确认所有 slave 全部更新到中间 Serial,否则部分机器会卡住。

单次增量绝对不能超过 2147483647。

现实运维:很多工程师尽量避免使用这个方案,兼容性坑不少。

方案 3:摆烂,不往回改,继续往上递增(强烈推荐,生产首选)

不重置 Serial,就维持这个很大的数字,以后每次修改继续+1。

Serial 只是版本号,没有业务含义,不是必须 YYYYMMDDNN 格式,它只是一个 32 位数字。

哪怕现在是 35 亿,后续每次改解析继续 + 1,主从同步完全正常。

等到数字走到接近上限 4294967295,再用方案 2 做一次环形翻转。

✅优点:零风险,不会出现主从撕裂,不需要等待时间,不用操作从服务器。

很多运维踩坑之后,就直接放弃日期格式 Serial,改用简单递增数字。

❌绝对不要做

直接把大 Serial 强行改成小数字。

结果:主 DNS 配置生效,但是全部从服务器认为版本变旧,拒绝同步 zone。你改再多解析,外网辅助 DNS 永远返回旧记录,故障很难排查。

云 DNS 场景(阿里云 / Cloudflare 等)

云托管 DNS:Serial 是服务商内部自动管理,用户不能手动写。

如果你迁移 DNS,新服务商的 Serial 比旧服务商小,会发生同步异常。处理:

旧 DNS 服务商保留 NS 记录,等到 SOA 的 Expire 时间过期;

或者迁移前把旧 DNS 的 Serial 推到一个极大值,再切 NS。

补充:Serial 溢出

最大值4294967295,再加 1 就溢出变成 0,这是 32 位无符号数的自然回绕。但不要主动靠溢出做重置,要严格遵守 RFC1982 的单次增量上限。

快速总结:自建、自己管全部从服务器:用rndc retransfer,最简单安全。

不能碰从服务器:优先不往回改,继续 + 1 递增,Serial 大一点没关系。

实在必须回到小数字:走 RFC1982 两步环形翻转,但是要承担老旧 DNS 不兼容风险。

千万不要直接强行降低 Serial。

3楼
发表于 今天 13:53 

如果是我的自建 dns 服务器,ns1 ns2 都是指向我同一 ip,就没这个 Serial 问题了吧?

其它省 dns 缓存不影响客户解析吧?

自建 DNS:ns1、ns2 写同一个 IP,Serial 还有没有问题?

先说核心结论: ✅你自己的两台 NS(ns1/ns2)指向同一个 IP,消除了「主从同步」带来的 Serial 问题,但:

互联网上千千万万公共递归 DNS(各省运营商 DNS、阿里云公共 DNS、114、8.8.8.8)不受你控制,它们依然会缓存记录,Serial 管不到它们!

Serial 解决的是 主从服务器之间的区域传输 AXFR/IXFR;递归 DNS 缓存根本不走 AXFR,完全不看 SOA‑Serial!

先分清两类完全不同的角色,很多人在这里混淆:

你的权威 DNS 服务器(ns1/ns2,你搭建) Serial 只用于权威服务器之间同步 zone(AXFR/IXFR 区域传送)。

如果你 ns1、ns2 只是域名别名,实际同一台机器同一个 IP:本质上就只有一台权威服务器,没有 slave 从服务器,不会发生 AXFR 同步,Serial 不会造成主从不同步故障。

Serial 依然要合法存在(zone 必须要有 SOA 记录),只是没人拿它做同步对比了。

注意:这不是高可用最佳实践。ns1、ns2 同一个 IP,IP 挂掉,整个域名权威解析直接全部宕机,DNS 协议要求 NS 记录最好是多 IP 多机房,做容灾。

各省运营商 / 公共递归 DNS(客户端用的 DNS 服务器,不在你手里) 👉 递归 DNS 不会拉取你的完整 zone,不执行 AXFR,完全不理会 Serial 字段! 递归 DNS 只看每条记录自己的 TTL,从你的权威服务器拿到结果,缓存 TTL 秒数。

Serial 改多大改多小,对递归缓存完全无效。

Serial 只管「权威服务器之间拷贝数据」,完全不控制外网缓存过期。

场景拆解

场景 A:ns1.example.com、ns2.example.com → A 记录都指向 1.2.3.4(同一台服务器)

没有 slave 从 DNS,没有 AXFR 区域传送。

你 zone 里面的 Serial 写错、变大变小,不会出现 “从服务器不肯更新” 这个故障,这个坑消失。

但是:

SOA 记录依然必须存在,否则 zone 非法,权威 DNS 启动报错。

外网递归 DNS 缓存依旧按照 A 记录、TXT 记录本身的 TTL 缓存;修改解析后,外网要等 TTL 过期才刷新,Serial 帮不上忙。

单点风险:IP 故障,全部 NS 失效,域名解析直接挂。

场景 B:标准主从架构:ns1 主 (1.2.3.4),ns2 从 (5.6.7.8),两台独立机器

ns2 通过 AXFR/IXFR 从 ns1 同步 zone,这里 Serial 就非常关键,Serial 变小会导致 ns2 拒绝更新,老坑复现。

简单记忆:只有多台权威 DNS 之间做区域复制的时候,Serial 才起作用。递归 DNS 不读 Serial。

那其它省份运营商 DNS 缓存,会不会影响客户?

会影响,但根源不是 Serial,是解析记录的 TTL。举例子: 你的 A 记录 TTL=86400(24 小时)

用户所在省运营商 DNS 已经缓存了旧 IP;

哪怕你自建 DNS 服务器立刻改好了记录;

该运营商 DNS 在 TTL 到期之前,继续返回旧 IP 给省内用户;

Serial 无论怎么改,无法让全国递归 DNS 立刻刷新缓存。

怎么处理外网递归缓存:

变更前把 TTL 调低,比如改成 300(5 分钟),等待旧 TTL 全部过期;修改解析,之后再调回大 TTL。

SOA 里的 Minimum‑TTL(现在 RFC 叫 NXTTTL)只控制不存在的域名 (NXDOMAIN) 否定缓存,不控制正常 A 记录的缓存。

额外一个坑:NS 记录全部指向同一个 IP 的现实问题

DNS 标准设计 NS 记录就是为了多 IP 容灾。

example.com.  IN NS ns1.example.com.
example.com.  IN NS ns2.example.com.

ns1 IN A 1.2.3.4
ns2 IN A 1.2.3.4

很多递归服务器看到两条 NS,但是解析出来同一个 IP。

正常情况下可以工作;

但是当这个 IP 丢包、宕机,DNS 协议层面没有备用节点,解析直接失败;

部分递归服务器会做 NS 轮询,但都落到同一个 IP,没有任何容错效果。

生产自建权威 DNS 建议:尽量两台不同公网 IP、不同机房,一台主一台 slave,这时候就要小心 Serial。如果预算有限只能单 IP,那 ns1 ns2 写同一个 IP 可以跑,接受单点故障风险。

再厘清两个容易混淆的东西

对象-看不看 Serial-作用:

你的 Slave 权威 DNS 服务器    ✅看 Serial    AXFR/IXFR 同步 zone 数据    

全国运营商、公共递归 DNS    ❌完全不看 Serial    按记录自身 TTL 缓存解析结果    

总结:ns1、ns2 域名指向同一个 IP,等于只有一台实际权威服务器,没有从服务器 AXFR 同步,Serial “变小不更新从机” 这个故障就不存在。但是 SOA 记录不能删掉,Serial 字段还得合法填数字。

各省运营商递归 DNS 缓存不受 Serial 控制,依然受 TTL 制约,改完解析,外网用户还是要等 TTL 过期才会看到新记录。Serial 解决不了外网缓存问题。

NS 记录都指向同一个 IP 会引入单点故障风险,一旦服务器 IP 不可达,域名直接无法解析。

Serial 只负责多台权威 DNS 之间同步,和客户端、运营商 DNS 缓存无关。

您需要登录后才可以回帖 登录 | 立即注册
【本版规则】请勿发表违反国家法律的内容,否则会被冻结账号和删贴。
用户名: 立即注册
密码:
2020-2026 MaNongKu.com