双 CDN 分流配置失败复盘:阿里云 DNS 与 Cloudflare Free 的边界
摘要
本次问题的目标是让同一个静态资源子域名在国内访问时走阿里云 CDN,在海外访问时走 Cloudflare CDN,同时保持权威 DNS 仍由阿里云托管。实际验证后确认:在 Cloudflare Free 套餐下,这条架构路径不可行。
根因不在 SSL/TLS 模式、页面规则或重定向规则,而在 Cloudflare 的接入模式限制:Cloudflare Free/Pro 默认支持的是 Full setup,也就是需要把域名的权威 Nameserver 切到 Cloudflare;不切 NS、只用外部 DNS CNAME 到 Cloudflare 代理节点的 Partial/CNAME setup,是 Business/Enterprise 才支持的能力。
背景与目标
初始目标可以抽象为下面的链路:
国内用户
-> 阿里云 DNS 分线路解析
-> 阿里云 CDN
-> OSS 或对象存储源站
海外用户
-> 阿里云 DNS 分线路解析
-> Cloudflare CDN
-> OSS 或对象存储源站
这个目标背后的约束是:
- 域名注册和权威 DNS 继续留在阿里云。
- 国内访问继续使用阿里云 CDN,以满足备案、调度和访问质量要求。
- 海外访问希望使用 Cloudflare 的边缘网络改善访问质量。
- 源站已经配置 HTTPS,并使用可被浏览器信任的证书。
- 不希望升级付费套餐。
从 DNS 层面看,这个设想很自然:阿里云 DNS 支持分线路解析,因此看起来只要给同一个主机名配置两条 CNAME 即可。
img.example.com 中国内地线路 CNAME aliyun-cdn.example-cname.com
img.example.com 境外线路 CNAME cloudflare-target.example
但 CDN 反向代理不是普通 DNS 解析。海外线路如果要真正进入 Cloudflare 代理层,需要 Cloudflare 认可这个主机名、给它签发边缘证书,并允许外部权威 DNS 通过 CNAME 把流量接入 Cloudflare。问题就出在这里。
实际踩坑过程
1. 不能直接添加子域名
最初尝试在 Cloudflare 中直接添加 img.example.com。Cloudflare 提示应添加根域名,而不是子域名。
这是符合 Cloudflare 常规接入模型的。普通 Zone 接入通常以根域名为单位,例如添加 example.com,再在 Zone 内管理 img.example.com、www.example.com 等子域名。
2. 添加根域名后 Zone 一直处于 Pending 状态
随后添加根域名 example.com,但没有把阿里云上的 Nameserver 修改为 Cloudflare 提供的 Nameserver。这样做的结果是:Cloudflare 控制台中的 Zone 一直显示未激活或 Nameserver 无效。
当时的误判是:只要在 Cloudflare 控制台里添加一条 img 的 CNAME 记录,并打开橙色云代理,再回到阿里云 DNS 将海外线路 CNAME 到 Cloudflare,就能绕过 NS 接管。
后续验证表明,这个判断不成立。Cloudflare 控制台里能创建 DNS 记录,并不代表该 Free Zone 已经具备外部 CNAME 接入能力。
3. Universal SSL 没有为子域名签发证书
Cloudflare SSL/TLS 模式设置为 Full 或 Full (strict) 后,预期 Cloudflare 会给 img.example.com 自动签发边缘证书。但由于 Zone 未激活,Universal SSL 并没有按预期完成证书部署。
这里容易混淆两件事:
- 源站证书:Cloudflare 回源访问 OSS 或对象存储时验证的证书。
- 边缘证书:浏览器访问 Cloudflare 边缘节点时看到的证书。
源站已有可信证书,只能解决 Cloudflare 到源站这一段;浏览器到 Cloudflare 这一段仍然需要 Cloudflare 边缘证书。如果 Cloudflare 没有为这个主机名部署边缘证书,HTTPS 访问仍会失败。
4. 自定义证书上传按钮是灰色的
尝试改为上传自己的证书到 Cloudflare 边缘,但控制台中的上传自定义证书按钮不可用。
这不是证书格式问题,而是套餐能力问题。Cloudflare 的自定义边缘证书能力不属于 Free/Pro 的可用范围。对于 Free 套餐,不能通过上传自有证书来绕开 Universal SSL 未签发的问题。
5. 页面规则和重定向规则不能解决根因
期间还尝试通过页面规则或重定向规则配置 Always Use HTTPS、HTTP 到 HTTPS 跳转等规则。Cloudflare 控制台提示规则可能不适用于当前流量,或者 URL 校验不通过。
即使规则能够保存,也不能解决根因。HTTPS 重定向规则运行在 Cloudflare 代理请求处理链路中,而当前问题是这个主机名并没有在 Cloudflare Free 下完成正式的可用接入:边缘证书没有就绪,外部 CNAME 接入也不是 Free 套 餐支持的模式。
换句话说,规则是流量进入 Cloudflare 之后的处理逻辑;本次失败发生在流量能否被 Cloudflare 正式接入并完成 TLS 终止之前。
根因分析
本次踩坑可以归结为一个核心误区:
把 Cloudflare 控制台中“可以创建 DNS 记录并打开橙色云”,误认为“可以在不切换 NS 的情况下,用阿里云 DNS CNAME 到 Cloudflare Free 代理层”。
官方文档中的接入模型更清楚:
- Cloudflare DNS setup 分为 Full setup、Partial/CNAME setup 等模式。
- Full setup 要求将域名 Nameserver 切到 Cloudflare。
- Partial/CNAME setup 才是“不切换权威 DNS,只通过 CNAME 将指定主机名接入 Cloudflare”的模式。
- Partial/CNAME setup 的可用套餐是 Business/Enterprise,不是 Free/Pro。
因此,下面这条链路在 Cloudflare Free 下不是一个受支持的生产架构:
阿里云权威 DNS
-> 境外线路 CNAME
-> Cloudflare Free 代理主机名
-> 源站
Cloudflare Free 可 以很好地用于下面这种 Full setup:
用户
-> Cloudflare 权威 DNS
-> Cloudflare 代理
-> 源站
但它不能在不接管 Nameserver 的情况下,作为一个被第三方权威 DNS 任意 CNAME 过来的反向代理 CDN 使用。
最终结论
在免费条件下,以下三个目标不能同时满足:
- 权威 DNS 继续留在阿里云。
- 国内走阿里云 CDN,海外走 Cloudflare CDN。
- Cloudflare 使用 Free 套餐,并作为海外 CNAME 接入的反向代理 CDN。
如果坚持 Cloudflare Free,那么更现实的选择是把根域名或相关域名的 Nameserver 切到 Cloudflare,接受所有线路都由 Cloudflare 做权威解析和代理策略的事实。
如果坚持阿里云 DNS 继续作为权威 DNS,并且只把海外流量 CNAME 到 Cloudflare,那么需要使用 Cloudflare Business/Enterprise 的 Partial/CNAME setup,或者改用其他支持 CNAME 接入的 CDN 服务。
可选替代方案
方案一:升级 Cloudflare 并使用 Partial/CNAME setup
这是最贴近原始目标的方案。
国内:阿里云 DNS -> 阿里云 CDN -> 源站
海外:阿里云 DNS -> Cloudflare CNAME setup -> 源站
优点是架构清晰,DNS 权威仍可保留在阿里云,国内和海外 CDN 可以分开调度。缺点是需要 Cloudflare Business/Enterprise,不是免费方案。
方案二:将 Nameserver 切到 Cloudflare
如果接受 Cloudflare 作为权威 DNS,可以使用 Cloudflare Free 的常规 Full setup。
优点是 Cloudflare 接入、Universal SSL、代理规则都会进入标准路径。缺点是国内访问质量、备案相关调度、与阿里云 CDN 的组合方式都需要重新设计,不能再简单依赖阿里云 DNS 分线路。
方案三:使用阿里云 CDN 的全球或海外加速
如果主要目标是让海外用户可访问,而不是必须使用 Cloudflare,可以直接评估阿里云 CDN 的全球加速或海外加速能力。
优点是控制面统一,证书、回源、缓存和日志都在阿里云体系内。缺点是海外质量、价格和节点覆盖需要单独评估。
方案四:国内 CDN 加海外直连源站
低预算情况下,可以保留国内线路走阿里云 CDN,海外线路直接解析到源站。
国内:阿里云 DNS -> 阿里云 CDN -> 源站
海外:阿里云 DNS -> 源站
这个方案技术上简单,但海外用户没有 CDN 加速和边缘防护。源站也必须直接暴露给海外访问,并处理安全组、防火墙、证书、带宽和攻击风险。
方案五:换用支持 CNAME 接入的海外 CDN
如果核心诉求是不切 NS、只让海外线路 CNAME 到某个 CDN,可以选择支持该模式且套餐成本可接受的海外 CDN。
评估时应提前确认:
- 是否支持第三方权威 DNS 下的 CNAME 接入。
- 是否自动签发边缘证书。
- 是否允许上传自定义边缘证书。
- 是否支持只接入单个子域名。
- 是否对中国大陆访问、备案、流量和带宽有额外限制。
排查经验
这次问题的主要教训是:排查 CDN 和 HTTPS 问题时,不要先陷入按钮和规则,而要先确认接入模式是否成立。
建议以后按下面顺序判断:
- 先确认谁是权威 DNS。
- 再确认 CDN 是否支持当前接入模式。
- 再确认边缘证书由谁签发、是否已部署。
- 再确认 CDN 到源站的 SSL/TLS 模式。
- 最后再处理页面规则、重定向、缓存和访问控制。
对于 Cloudflare,尤其要区分:
- Full setup:Cloudflare 接管 Nameserver。
- Partial/CNAME setup:不切 NS,通过 CNAME 接入 Cloudflare。
- 橙色云代理:只在 Cloudflare 支持并完成接入的前提下才有意义。
- Universal SSL:解决浏览器到 Cloudflare 的边缘证书问题。
- 源站证书:解 决 Cloudflare 到源站的 HTTPS 问题。