同一个网站(域名或源站)同时接入或切换使用多个 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),确保关键响应头(如 CORSAccess-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请求时,默认传递的 HTTPHost头部通常是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;
}
}