
最近处理一个老朋友的网站故障时我发现一个以前用了很多年的套路——通过 DNS 委派把子域名交给 Cloudflare——现在不好使了。所谓委派就是在父区 DNS 里为子域名添加 NS 记录把它交给 Cloudflare 的权威服务器来解释这样子域名就能独立使用 Cloudflare 的 CDN、WAF 和边缘防护。这套方案在过去很长一段时间里是个人站长的标准操作不少技术社区的教程也把它列为“子域名接入 Cloudflare 的推荐姿势”。可最近我在两个完全不同的环境里复现了同样的失败要么 Cloudflare 控制台直接拒绝添加 NS 记录要么父区服务商悄悄把委派记录覆盖掉要么解析链路时好时坏反复出现 SERVFAIL。如果你最近也在折腾子域名和 Cloudflare 的接入或者手头的子域名突然解析不稳定建议把这篇看完省得像我一样来回试错。1. DNS委派是什么为什么以前大家都这么用1.1 委派在DNS体系里的真实含义DNS 的解析过程本质上是一个“逐级下放”的过程。根区只负责告诉你 .com 的权威服务器是谁.com 只负责告诉你 example.com 的权威服务器是谁example.com 的 NS 再负责告诉你 lab.example.com 的 A 记录是多少。所谓委派就是在父区例如 example.com里创建一条 NS 记录指向子区lab.example.com的权威服务器。这条 NS 记录一旦生效任何递归解析器查询 lab.example.com 下的记录时都会被引导到被委派的那台 NS 服务器去父区里关于这个子域的其他记录比如 A 记录、CNAME就不再参与解析了。我打个比方。整个 DNS 系统像一家公司根区是总部.com 是分公司example.com 是部门lab.example.com 是小组。委派相当于部门经理把小组的人事权完全交给另一个团队负责人。以后总部要了解这个小组的信息直接找那个新团队负责人不再经过部门经理。这套机制的厉害之处在于父区不需要知道子区里的任何具体记录只需要知道“谁能回答子区的问题”。这种解耦让大公司、云服务商、内容分发网络都能各自独立维护自己的域名空间。1.2 当时为什么流行“把子域名扔给Cloudflare”说白了需求就几类。第一类是想独立管理主域名放在注册商或某个低成本 DNS 服务商那里但子域名是一个长期的独立项目团队希望子域名的记录增删、证书配置、防护规则完全独立不跟主域混在一起。第二类是想用 Cloudflare 的免费 CDN 和 WAFCloudflare 免费套餐对个人站很友好但主域一旦完全接入Cloudflare 会管理整个域名有些人不想把主域的控制权交出去于是只把子域委派过去这样既享受加速和防护又保留主域的自由度。第三类是开发场景做多租户、边缘函数、灰度发布测试时需要一个干净的独立 DNS 区域频繁创建完整 Zone 太重委派一个子域很轻量。还有一个历史原因很多 DNS 服务商不支持在根域设置 CNAME但子域委派完全绕开了这个限制所以它成了不少人唯一能用的“软迁移”方案。在 2020 年前后我给客户配置这类场景不下几十次主域在阿里云或者腾讯云子域委派给 Cloudflare10 分钟就能完成整体体验顺滑得很。这也是为什么现在出了问题很多人第一反应是“是不是我操作错了”而不是“平台已经不让这么干了”。1.3 经典教程里的“标准姿势”那时候的标准做法是这样的先在 Cloudflare 添加子域名站点Cloudflare 会分配一对 NS比如 aria.ns.cloudflare.com 和 raven.ns.cloudflare.com。然后去父区 DNS 控制台添加 NS 记录名称填子域名内容填这对 NS。如果有必要再补上 glue 记录。等 DNS 缓存更新后子域名的权威解析就变成 Cloudflare 了。全程不需要迁移主域名不需要改变主域已有的 MX、TXT 这些记录风险极小。正因为这样这套方案沉淀了大量教程和脚本很多子域名收集工具甚至专门扫描目标域名的 NS 记录DNS 拓扑一目了然。但现在的现象完全变了。我最近在两个完全不同的环境里用同样的步骤操作得到的结果要么是报错要么是异常。这已经不是操作层面的问题而是平台策略和底层实现逻辑发生了变化。下面我把三个最有代表性的踩坑现场完整还原出来。2. 实测复现三个典型的失败场景2.1 场景一Cloudflare控制台直接拒绝添加NS记录第一个环境里我的主域名 example.com 托管在 Cloudflare 之外的一家 DNS 服务商我想把 lab.example.com 委派给 Cloudflare。Cloudflare 那边我已经建好了子域名的 Zone系统自动分配了 NS一切看起来很正常。然后我登录 Cloudflare 控制台进入 example.com 的 DNS 设置页面添加记录选择 NS 类型填写名称 lab内容填 Cloudflare 分配的那两个 NS 名称。点击保存以后页面上方弹出一条红色错误提示大意是不允许为已经由 Cloudflare 管理的子域添加 NS 类型记录。我一开始以为自己看错了毕竟以前这条路是通的。又试了几次换了浏览器、清了缓存结果一样。这个报错说明 Cloudflare 的平台逻辑里已经明确如果某个子域已经在 Cloudflare 内部作为一个独立 Zone 存在那它就不再接受你用 NS 记录去“委派”它。换句话说作用于同一个账户内的“父区 子区”组合Cloudflare 直接在源头切断了 NS 委派这条路。2.2 场景二API添加同样被安全策略拦截控制台不行我想到用 API 碰碰运气。Cloudflare 的 API 文档里创建 DNS 记录的接口是 POST /zones/{zone_id}/dns_recordsbody 大概是下面这样{ type: NS, name: lab, content: aria.ns.cloudflare.com, ttl: 3600 }我以为 API 渠道能绕过 UI 的限制结果请求发过去以后返回了 HTTP 400错误码是 1015消息内容是“You are being rate limited”。我第一反应是触发限流了可那段时间我的 API 请求频率极低完全不该被限流。后来我仔细检查发现这类报错其实经常和安全策略拦截混在一起只是被包装成了限流信息。真正的问题是Cloudflare 的 API 同样对该类型操作做了策略校验尤其当 NS 记录的目标指向 Cloudflare 自身分配的 NS 名称时会触发风控。在你反复尝试的时候它干脆用限流接口把你挡在外面避免你用各种姿势硬闯。2.3 场景三父区服务商悄悄覆盖了我的委派记录第三个环境更迷惑。另一个域名 demo.cn父区 DNS 托管在某国内注册商的控制台里我在这里添加 NS 记录把 lab.demo.cn 委派给 Cloudflare。添加的时候界面提示成功没有任何报错。我以为这次总该没问题了结果访问 lab.demo.cn 时解析极不稳定有时能拿到 Cloudflare 边缘 IP有时直接 SERVFAIL有时甚至解析到了父区里一个旧的 A 记录。用公共 DNS 查一下nslookup lab.demo.cn 8.8.8.8返回的是无答案、SERVFAIL。再直接对 Cloudflare 的权威 NS 查dig lab.demo.cn aria.ns.cloudflare.com结果却完全正常A 记录清晰可见。这说明 Cloudflare 这边没毛病问题出在整条解析链路的“路由”环节。我再用递归追踪dig NS lab.demo.cn trace结果让我彻底明白了父区权威服务器返回的 NS 列表根本不是我配置的那两条 Cloudflare NS而是变成了注册商自己的两条 NS。我配置的委派记录被父区平台静默覆盖了它只是在数据库里记了一笔并没有真正下发到权威 DNS 服务器上。这种“假支持”比直接报错更坑因为它表面上成功实际却没有生效定位问题要花掉大把时间。3. 根因排查到底是哪个环节在拦路3.1 Cloudflare的“Zone自我包含”逻辑第一个核心原因出在 Cloudflare 自身的平台设计上。Cloudflare 的产品逻辑里如果一个子域已经被添加为 Zone它就会认为这个子域的管理权已经完整归属到平台内部不需要也不允许外部再通过一条 NS 记录来进行委派。如果允许就会出现“同一个子域既是 Cloudflare 管理的 Zone又靠外部 NS 记录来指路”的循环矛盾这种矛盾很容易引发解析环也可能被利用来做域名劫持或钓鱼。更关键的是Cloudflare 在很多 Zone 上启用了隐藏 NS 机制。也就是说你看到的 aria.ns.cloudflare.com 并不是服务器内部对所有节点公开的权威 NS 名称Cloudflare 在边缘网络里使用了另一套更适合自身调度的表示方式。当你手动添加同样名称的 NS 记录时就会和隐藏 NS 体系冲突系统自然拒绝。这一点在控制台报错提示里并不会说得太明白只有反复实验才会摸到规律。3.2 父区服务商对自定义NS记录的“假支持”第二个拦路虎来自父区所在的 DNS 服务商。真正合规的 DNS 委派要求父区权威服务器上必须真实存在一条 NS 记录并且在必要的情况下配置对应的 glue 记录。但不少注册商和低端 DNS 托管平台后台的 NS 记录并没有真正写入权威 Zone 文件它们只是在数据库层做了一次展示。尤其当父区启用了 DNSSEC、泛解析或者 CNAME Flattening 功能时用户后台配置的 NS 记录很容易被系统规则覆盖或直接忽略。我后来翻了几个平台的帮助文档发现一个共同点它们普遍不承诺支持自定义 NS 记录向第三方委派只支持把整个域名的 NS 改成第三方。这就很尴尬了——你想要的“子域独立、主域不动”恰恰是它们最不擅长的地方。所以如果父区服务商本身不支持这种操作无论你在 Cloudflare 这边怎么努力都是白费力气。3.3 DNSSEC带来的连锁失效还有一个特别容易忽略的坑DNSSEC。如果父区启用了 DNSSEC委派就不仅仅是加一条 NS 记录还必须在父区配置 DS 记录也就是委派签名者记录指向子区域的密钥标签、算法编号和摘要值。如果只加 NS 不加 DS任何一个开启 DNSSEC 验证的递归解析器在走完签名链后都会发现“父区没有授权子区”的凭据直接返回 SERVFAIL。我在场景三里遇到 SERVFAIL很大概率就是这个原因。Cloudflare 在创建新 Zone 时默认开启了 DNSSEC页面会给你一串 DS 记录要求你到父区去添加。很多人只加了 NS忽略了 DS导致解析链路验证失败。尤其是用 8.8.8.8 或 1.1.1.1 这类强制 DNSSEC 校验的公共 DNS 时问题会立刻暴露而本地运营商 DNS 如果没开验证反而看起来一切正常这就会造成“时好时坏”的假象。3.4 泛解析、CNAME Flattening和缓存的三重干扰除了上面两类原因另一种隐蔽情况是泛解析。如果父区有 *.example.com 这样的泛解析记录递归解析器在查找 lab.example.com 的 NS 记录时有可能会提前命中父区的泛解析逻辑。按 RFC 规范泛解析 A 记录不应该影响 NS 查询但不少 DNS 实现在本地缓存阶段会做二次合并导致请求根本到不了 Cloudflare。结果就是同一个子域在不同地域、不同递归服务器上表现完全不同特别容易误判成“Cloudflare 不稳定”。CNAME Flattening 同样会捣乱。一些服务商为了加快解析速度会把子域的 CNAME 记录在权威服务器上直接展开成 A 记录这样你配置的指向 Cloudflare 的 CNAME 就变成了一个固定 IP失去了 CDN 调度的灵活性。再加上旧 NS 记录在递归服务器里的缓存可能长达 24 到 48 小时整个问题的表象就是乱象丛生。想快速定位就必须先把链路拆开逐段验证。4. 绕过委派四条经过验证的替代路线既然 URL 委派这条路被堵得这么死就别死磕换思路。我和团队在实际项目里验证了下面几条替代方案各有适用场景按推荐程度排个序。4.1 最简单的独立Zone托管方案如果你的需求只是“让子域名的流量走 Cloudflare 加速和防护”其实不一定非要 DNS 委派。直接在 Cloudflare 里把子域名添加成独立 Zone然后在父区为该子域添加一条普通 A 记录指向源站服务器 IP。Cloudflare 会对子域的源站 IP 做反向代理用户访问子域时请求先到 Cloudflare 边缘再回源到你的服务器。这个方案的关键点在于父区的 A 记录不能是 Cloudflare 的边缘 IP必须是源站的真实 IP。如果你手里只有源站的域名而没有固定 IP可以先把源站解析到某个固定 A 记录再让 Cloudflare 回源。很多人在这里踩坑以为把 A 记录填成 Cloudflare 边缘 IP 就能加速结果形成了解析回环子域直接打不开。正确做法是让父区只负责源站寻址CDN 的调度交给 Cloudflare 内部的记录。如果源站没有公网 IP或者你不想暴露源站真实 IP可以结合 Cloudflare Tunnel。在源站上运行 cloudflared通过隧道把本地服务映射到 Cloudflare 边缘。Tunnel 的好处是源站不需要公网 IP也不需要在防火墙上开端口。用 Docker 部署时把 Tunnel Token 通过环境变量传给容器注意 cloudflared 容器里默认的配置路径和 Ingress 规则要对应上否则很容易报 cloudflare tunnel error最常见的提示就是找不到主机名对应的 Ingress 规则。4.2 最接近委派体验的Cloudflare for SaaS如果子域名很多或者希望证书能够自动签发、续期那最接近原 DNS 委派体验的方案是 Cloudflare for SaaS也就是自定义主机名功能。它的本质是Cloudflare 只负责承载流量和证书父区依然掌控 DNS 权威通过一条 CNAME 记录把子域名引到 Cloudflare 的代理域名上再靠 SNI 来识别不同子域。操作流程大致这样先在 Cloudflare 里设置一个回退源域名比如 origin.example.com指向源站 IP然后在 SSL/TLS 的自定义主机名里添加 lab.example.com接着去父区给 lab.example.com 添加一条 CNAME指向 origin.example.com。之后 Cloudflare 会自动为这个自定义主机名签发边缘证书也会提醒你为源站准备回源证书。涉及回源证书时需要你生成 CSR也就是证书签名请求把私钥留在源站CSR 提交给证书颁发机构。如果你之前没接触过 CSR可以把它理解成一份“身份申请表”里面包含域名信息和公钥CA 拿到后会签发证书给你。这套方案的好处是父区的 CNAME 记录非常普通任何 DNS 服务商都支持不会像 NS 记录那样被特殊对待Cloudflare 这边能自动处理证书续期你不用盯着过期时间。缺点是需要做一次源站回源配置概念上比单纯加一条 NS 记录稍多但对有一定运维经验的人来说完全可控。4.3 主打轻量的CNAME接入套路如果你暂时不想碰自定义主机名最简单的方式就是在父区新增一条 CNAME 记录把子域名指向一个已经被 Cloudflare 代理的中间域名。这个中间域名可以是你自己在 Cloudflare 里管理的另一个域名也可以是服务商提供的固定别名。通过这条 CNAME子域名的流量会自动进入 Cloudflare 的边缘网络享受 CDN 缓存和基本防护。网上有一些工具和脚本会去测 Cloudflare 各个边缘节点的延迟也就是所谓的优选 IP 套路。实际业务场景里除非你的用户群体集中在某个特殊网络环境否则默认的 Cloudflare 节点选择和 CNAME 解析已经够用我不太建议为了追求所谓优选去手动绑定 IP那样反而可能绕过 Cloudflare 的智能调度安全性得不偿失。CNAME 接入的注意点是子域名在 Cloudflare 控制台上必须存在对应 Zone 或自定义主机名配置否则 CNAME 指向的代理域名没有匹配的 SNI 和后端路由请求会 404。我在帮朋友排查时就见过只加了 CNAME、忘了在 Cloudflare 添加对应站点的情况折腾一晚上最后发现就是少了一个站点记录。4.4 一劳永逸的整体迁移方案如果子域名委派这事对你很重要而父区平台又是那种对 NS 记录“假支持”的那最彻底的方案是把整个主域名迁移到 Cloudflare。迁移之后你本来就在 Cloudflare 内部根本不需要委派所有子域都天然和你同在一个 Zone 里记录管理、证书管理、WAF 规则都统一了。缺点是要做旧记录迁移、处理 DNSSEC 关闭和切换时间窗口但对绝大多数个人站和学习型项目来说这是最省心的长期方案。迁移顺序建议先在 Cloudflare 添加主域记录扫描完成后在旧区关闭 DNSSEC等待 TTL 过期然后把主域的 NS 改成 Cloudflare 提供的名称等全球生效后再在 Cloudflare 里开启 DNSSEC。整个过程最怕的是“先开后关”如果你先把 Cloudflare 的 DNSSEC 开了父区还没删旧 DS 记录可能出现几小时的解析中断。这类切换操作一定要安排在低峰期并且留够缓存过期时间。4.5 一组方案对比方案父区操作Cloudflare配置适合场景局限独立Zone A记录添加A记录指向源站新建独立Zone单个子域、源站有固定IP证书管理手动源站IP可能暴露Cloudflare for SaaS添加CNAME到回退源配置自定义主机名多子域、证书自动续期概念多需配置回源证书CNAME方式接入添加CNAME到代理域名已有Zone或域名快速启用CDN需要中间域名SNI匹配易错主域名整体迁移修改主域NS整个主域Zone长期管理、多子域切换有短暂风险5. 排查命令与问题速查表5.1 建立自己的诊断链路遇到故障别慌先把诊断链路建起来。我常用的命令组合如下# 查询父区持有的NS记录确认委派是否存在且内容正确 dig NS lab.example.com 父区权威NS # 直接查询Cloudflare的权威NS确认子区本身是否有记录 dig A lab.example.com aria.ns.cloudflare.com # 递归追踪完整解析链找出断点 dig A lab.example.com trace # 检查子域是否启用DNSSECDS记录是否缺失 dig DNSKEY lab.example.com short # 检查父区是否有泛解析干扰 dig A 任意不存在的名称.example.com short如果父区权威 NS 返回的 NS 列表不是 Cloudflare而是其他服务器说明委派记录根本没生效问题出在父区平台。如果父区 NS 正确但公共 DNS 还是 SERVFAIL那多半是 DNSSEC 链断裂去父区检查 DS 记录即可。5.2 常见故障现象速查现象可能原因解决方向Cloudflare控制台拒绝添加NS记录Cloudflare禁止为已管理的子域做委派改用自定义主机名或CNAME接入API添加NS被限流报错安全策略拦截非真实限流换用其他接入方式检查Zone归属子域时而正常时而SERVFAILNS记录未生效或DNSSEC链断裂检查DS记录确认父区是否支持委派父区NS记录被静默覆盖服务商不支持自定义NS委派换DNS服务商或整体迁移Cloudflare侧正常但公网不可达递归服务器缓存旧NS/glue记录降低TTL等待缓存失效解析结果指向旧A记录泛解析或CNAME Flattening干扰删除泛解析改用自定义主机名5.3 实操心得第一不要把希望押在 TTL 上。委派类故障里最耗时间的就是缓存有些老递归服务器会把 NS 记录缓存到 48 小时以上。你在父区改了 NS 之后用户侧很可能看到的还是老状态。建议调低父区 NS 记录的 TTL 到 300 秒再测试确认全球生效后再调回 300 到 600 秒。第二测试别只用本机。本地运营商 DNS 的递归行为和缓存策略各不相同容易掩盖真实问题。最靠谱的测试环境是把 8.8.8.8、1.1.1.1 和自定义的跟踪查询三者同时对比。如果三者的结果完全一致才能说明全链路正常。第三DNSSEC 一旦开启就别轻易关。排错时可以临时关闭确认问题不在 DS 链后立刻恢复。我遇到好几次“关了就能通、开了就断”的情况最后都是 DS 记录没有同步到父区。Cloudflare 控制台里会清楚显示你要添加的 DS 值但前提是你所在父区支持 DS 记录不支持的时候就得考虑换服务商。6. 最后再分享一点实际体会我个人的体会是Cloudflare 并不是反对“子域名独立管理”这个需求而是它的产品重心已经完全不同了。新版控制台里自定义主机名、Zero Trust、Tunnel 这些功能的权重越来越高官方明显希望你通过这些方案来管理子域而不是依赖外部 NS 记录的委派。认清这个方向之后很多折腾就变得没必要了。如果你现在也在为子域名接入 Cloudflare 发愁我的建议是先想清楚你到底需要什么如果只是流量加速那就用独立 Zone 配合源站 A 记录如果要多个子域自动证书那就上 Cloudflare for SaaS如果源站没有公网 IP那就用 Tunnel。最不推荐的就是继续在父区和 Cloudflare 之间反复测试 NS 委派浪费时间不说还可能因为解析异常影响线上业务。技术在演进平台在收紧我们做运维的也得跟着调整策略绕路不可怕可怕的是明知道路不通还在原地硬踩。