同一个网站(域名或源站)同时接入或切换使用多个 CDN(例如 Cloudflare + AWS CloudFront,或 DNSPod 调度多 CDN)时,通常用于高可用容灾、跨国/跨运营商线路优化、成本平衡。

由于不同 CDN 厂商的技术架构、缓存策略和安全规则存在差异,配置不当极易引发缓存混乱、无限重定向、证书报错或安全漏洞。

以下是使用不同 CDN 时需要重点注意的核心细节:

1. 缓存策略与刷新(Cache Policy & Purging)

  • 缓存键(Cache Key)一致性:确保各 CDN 对 查询参数(Query Strings)、请求头(如 Accept-Encoding, User-Agent)、Cookie 的处理逻辑一致。例如,如果 CDN A 默认忽略 URL 参数而 CDN B 保留,会导致不同节点返回不一样的页面。
  • 统一 Cache-Control Header:尽量由源站输出明确的 Cache-Control / Expires 响应头,控制各 CDN 的缓存行为,而不是各自在 CDN 控制台上配置冲突的强制缓存规则。
  • 多平台同步刷新:更新静态资源时,如果使用 URL 刷新(Purge),必须通过 API 或 CI/CD 工具同步调用所有 CDN 厂商的刷新接口。若无法做到实时同步,建议使用 版本号/Hash 文件名(例如 app.a8f9d.js)来彻底避免缓存同步问题。

2. TLS/SSL 证书与 HTTPS 握手

  • SNI 与源站证书验证:CDN 节点向源站拉取数据(回源)时,需要校验源站证书。建议源站配置受信任的公网证书,并在各 CDN 上将回源 Host 头(Host Header)统一设置为域名本身。
  • 回源加密模式一致:
  • 防止出现 CDN A 使用 HTTP -> 源站,而 CDN B 使用 HTTPS -> 源站 的情况。
  • 若使用 Cloudflare,务必注意其 Flexible / Full / Strict 模式。若设置为 Flexible,Cloudflare 会用 HTTP 回源,这可能与其它使用 HTTPS 回源的 CDN 冲突,造成源站重定向死循环(ERR_TOO_MANY_REDIRECTS)。

3. 源站防刷与回源 IP 白名单

  • 回源 IP 范围不同:每个 CDN 都有自己独立的回源 IP 池。如果源站在防火墙(如 iptables / Nginx)设置了 IP 白名单,必须将所有接入 CDN 的回源 IP 段全部加入白名单,否则部分 CDN 节点的请求会被源站拒绝(502/504 错误)。
  • 回源鉴权 Header(Custom Header):为了防止黑客绕过 CDN 直连源站 IP,可以在各 CDN 配置统一的自定义 HTTP Header(例如 X-CDN-Auth-Secret: your_token),源站仅放行带有效 Header 的请求。

4. 域名解析与 DNS 调度(DNS & Routing)

  • CNAME 扁平化与 Apex 域名:主域名(如 example.com)在传统 DNS 中无法直接配置 CNAME。如果使用 DNS 轮询或按地域调度多 CDN,DNS 服务商需支持 CNAME Flattening 或 ALIAS / ANAME 记录。
  • 分线路解析(GeoDNS / ISP DNS):按国家或运营商(如国内电信/联通/移动,国外 Cloudflare)分配不同 CDN CNAME 时,需注意 DNS 缓存 TTL 不宜过长(建议 60s - 300s),以便在某家 CDN 故障时快速切换。
  • 健康检查与自动 Failover:DNS 服务商应配置自动健康检查。当某一 CDN 节点大量抛出 5xx 错误时,DNS 应能自动剔除该 CNAME 解析。

5. 安全防护与 WAF 策略(Security & WAF)

  • 规则冲突与误杀:不同 CDN 的 WAF 引擎(如 ModSecurity 规则 vs 自研引擎)敏感度不同。在一个 CDN 上正常放行的请求,在另一个 CDN 上可能被拦截。建议在上线初期将 WAF 设为 Log/Observe 模式进行观察。
  • 真实客户端 IP 获取:各 CDN 传递真实访客 IP 的 Header 可能不同:
  • Cloudflare:CF-Connecting-IP
  • CloudFront / 常见 CDN:X-Forwarded-For
  • 某些国内 CDN:X-Real-IP

源站应用层(或 Nginx realip 模块)需要正确解析这些 Header,否则日志中的 IP 会变成 CDN 节点的 IP,影响风控与统计。

6. HTTP 协议支持与 Header 传递

  • HTTP/2 & HTTP/3 (QUIC):不同 CDN 对 HTTP/3 的支持情况不同。客户端到 CDN 的协议差异不影响回源,但可能影响前端性能测试指标。
  • 响应头覆盖/清洗:某些 CDN 会默认剥离或添加特定的 Header(例如 Server, Etag, Vary)。需要检查所有 CDN 的 HTTP Header 修改规则(Transform Rules),确保关键响应头(如 CORS Access-Control-Allow-Origin)在所有 CDN 上表现一致。

总结检查清单(Checklist)

关注维度核心检查项
缓存URL 参数处理规则、Cache-Control 是否一致;CI/CD 刷新 API 是否覆盖全部 CDN。
网络源站防火墙白名单已包含所有 CDN 的回源 IP 列表。
域名与 SSL回源 Host 头统一;源站 SSL 证书有效;关闭 Flexible 模式避免重定向死循环。
安全与日志WAF 规则同步;源站按不同 CDN 传参正确解析访客真实 IP(X-Forwarded-For 等)。
调度DNS 配置了低 TTL,且具备健康检查与 Failover 自动切换能力。

这种架构被称为多 CDN 冗余 / 分流架构(例如:https://www.sample.com 接入 CDN A,back.sample.com 接入 CDN B 并作为 CDN B 访问源站的入口,或者利用 DNS 调度)。

在将 back.sample.com 配置为专供另一个 CDN 回源的入口时,需要特别注意访问隔离、SSL 证书、Host 头覆盖以及缓存一致性。以下是具体的实施注意要点与标准步骤:

1. 核心风险:防止源站被绕过与裸露(Security)

如果 back.sample.com 只是解析到源站 IP,那么黑客可以通过查找 DNS 记录获取 back.sample.com,从而直接绕过 CDN A / WAF 攻击你的源站。

  • 回源鉴权 Header(最推荐):

    在 CDN B 的控制台中设置一个固定的自定义 Header(如 X-CDN-B-Auth: <Secret-Token>)。源站 Web 服务器(Nginx/Caddy/Apache)配置校验:如果请求目标是 back.sample.com 但缺少该 Header,直接返回 403 或 444 拒绝访问。

  • 回源 IP 白名单:

    在源站防火墙只允许 CDN B 的 IP 段访问 back.sample.com。

2. HTTPS 证书与 SNI 配置(SSL / TLS)

CDN B 在向 back.sample.com 拉取数据时,会发起 TLS 握手并校验源站证书:

  • 证书覆盖范围:源站必须安装支持 back.sample.com 的 SSL/TLS 证书。
  • 最省事的方式是源站直接使用涵盖 *.sample.com 的通配符证书(Wildcard SSL),或者在同一证书中添加这两个 SAN 域名(https://www.sample.com + back.sample.com)。
  • 防止证书过期导致的 526 / 502 错误:确保源站证书由受信任的 CA 签发(如 Let's Encrypt / ZeroSSL),并设置了自动续期(如 Certbot / acme.sh)。

3. 回源 Host 头(Host Header)重写

这是最容易导致页面加载异常或重定向循环的地方。

  • 保持 HTTP Host 头一致:

    CDN B 在向源站 back.sample.com 请求时,默认传递的 HTTP Host 头部通常是 back.sample.com。

  • 问题:如果你的源站后端程序(如 WordPress、Node.js、Laravel)绑定了固定域名 https://www.sample.com,当收到 Host: back.sample.com 的请求时,程序可能会自动发起 301/302 重定向跳转到 https://www.sample.com,导致 CDN B 陷入无限重定向。
  • 解决办法:在 CDN B 的“回源设置”中,将 回源 Host(Origin Host Header) 显式重写/指定为 https://www.sample.com;或者在源站配置中允许 back.sample.com 作为合法站点绑定的域名。

4. 客户端真实 IP 获取(Real IP Parsing)

源站如果同时接收 CDN A(经过 https://www.sample.com)和 CDN B(经过 back.sample.com)的请求,解析真实 IP 的逻辑需要兼容两边:

  • 不同的 Header 名称:
  • 如果 CDN A 是 Cloudflare,它会发送 CF-Connecting-IP。
  • 如果 CDN B 是 AWS CloudFront 或其他 CDN,它通常发送 X-Forwarded-For 或 X-Real-IP。
  • 源站 Nginx 示例:

    在 Nginx 的 set_real_ip_from 配置中,必须将 CDN A 和 CDN B 的所有 IP 段都加进去,并依次指定提取 IP 的 Header,否则访问日志和风控程序会拿不到真实用户 IP。

5. 跨域与 CORS(Cross-Origin Resource Sharing)

如果网站包含静态资源(字体、API 接口、AJAX 异步请求):

  • 如果业务涉及在 CDN A 上运行的代码去请求 CDN B 上的资源,需注意源站或 CDN B 输出的 CORS 响应头(如 Access-Control-Allow-Origin)是否包含了正确的域名(或设置为动态匹配),防止由于域名不同引发浏览器跨域拦截。

6. 搜索引擎收录(SEO & Robots)

如果不希望搜索引擎直接抓取到 back.sample.com 造成重复内容扣分:

  • 在源站针对 back.sample.com 虚拟主机添加 HTTP 响应头:

HTTP

X-Robots-Tag: noindex, nofollow

或者在源站如果匹配到请求 Host 是 back.sample.com 且直接被搜索引擎爬虫访问时,直接禁止。

推荐的实施架构配置参考(以 Nginx 为例)

Nginx

server {
    listen 443 ssl http2;
    server_name www.sample.com back.sample.com;

    # 源站证书(建议使用 *.sample.com 通配符证书)
    ssl_certificate /path/to/wildcard_sample.crt;
    ssl_certificate_key /path/to/wildcard_sample.key;

    # 针对 back.sample.com 回源入口的安全校验(可选)
    if ($host = "back.sample.com") {
        # 校验来自 CDN B 的自定义密钥,非 CDN B 访问直接断开连接
        set $cdn_auth 0;
        if ($http_x_cdn_b_auth = "Your-Secret-Token-12345") {
            set $cdn_auth 1;
        }
        if ($cdn_auth = 0) {
            return 444; # 或 return 403;
        }
    }

    location / {
        # 业务逻辑或转发给后端应用 (如 127.0.0.1:8080)
        proxy_pass http://127.0.0.1:8080;
        
        # 统一将 Host 传给后端应用,避免后端因域名变化引发 301
        proxy_set_header Host www.sample.com;
        proxy_set_header X-Real-IP $remote_addr;
    }
}