Files
tamabox/outputs/edgeone-cloudflare-dual-cdn-guide.md
T
2026-09-08 10:10:44 +08:00

11 KiB
Raw Blame History

TamaBox 双 CDN 接入指南:境内腾讯 EdgeOne + 境外 Cloudflare

目标:中国大陆访客走腾讯 EdgeOne 节点加速,境外访客走 Cloudflare 边缘网络加速,共用同一域名与源站。 代码前置:internal/shared/ip.go 自 2026-09-03 起在 trust_proxy = true 时信任 EdgeOne 权威客户端头 EO-Client-IP(等效 CF-Connecting-IP)。单 EdgeOne 或双 CDN 部署均可直接用本文件配套。


0. 总体架构

                 ┌──────────────── DNS(DNSPod 智能解析)─────────────────┐
                 │   线路「境内」 → CNAME → EdgeOne 分配的 CNAME          │
                 │   线路「境外」 → CNAME → Cloudflare for SaaS CNAME     │
                 │   线路「默认」 → CNAME → Cloudflare(未匹配线路兜底)    │
                 └───────────────┬───────────────────┬────────────────────┘
                                 ▼                   ▼
                      EdgeOne(腾讯,大陆节点)   Cloudflare(全球边缘)
                                 │                   │
                                 └─────► 源站(仅放行两家回源网段)◄──────┘
                                        TamaBox (Flamego) + PG + Redis

核心思路:CDN 各自接入,DNS 按线路分发。两家 CDN 都不需要托管你的主域名 NS,主域名 NS 全程留在 DNSPod(腾讯云解析),靠「境内 / 境外 / 默认」三条线路把用户分给不同的 CNAME 目标。

1. 前置条件(逐项确认)

# 条件 说明
1 域名已 ICP 备案 EdgeOne 加速区域含「中国大陆 / 全球可用区」时的硬性要求,不可绕开
2 腾讯云账号已实名 开通 EdgeOne 需要
3 Cloudflare 账号 Free 套餐即可(见步骤 3 的 SaaS 说明)
4 一个闲置域名(或其子域)用于 Cloudflare 承载 zone Cloudflare for SaaS 需要一个已托管在 CF(NS 迁过去)的域名作为“承载 zone”,主域名不需要迁 NS。没有就考虑末尾的备选方案 C
5 源站公网可达 回源协议 / 端口按你的部署调整

2. 步骤 1:DNS 迁到 DNSPod 并建立分线路骨架

  1. 在 DNSPod(腾讯云解析)添加你的域名,按提示把注册商处的 NS 改成 DNSPod 提供的 xxx.dnspod.net 两条。
  2. 等解析生效后,先建立保底记录,避免切换期中断:
    • 线路「默认」:www → CNAME → EdgeOne(或先保持源站 A 记录,逐步切);
    • 建议把各记录 TTL 临时调小(如 60 秒),切换完成后再调回。
  3. ⚠️ 若根域(@)承载邮箱(存在 MX 记录),不能给 @ 配 CNAME(与 MX 冲突)。此时只对 www / 业务子域做 CDN 加速,@ 保持 A 记录直连或做 301 跳转。

3. 步骤 2:EdgeOne 接入(CNAME 模式)

  1. 控制台 → 添加站点 → 输入主域名 → 选购套餐 → 加速区域:中国大陆可用区(境外交给 Cloudflare)。
  2. 接入模式选 CNAME 接入(主域名 NS 在 DNSPod,不能用 NS 接入)。
  3. 归属权验证:按控制台提示在 DNSPod 添加 TXT 或做文件验证。
  4. 添加加速域名:在「域名服务 → 域名管理 → 添加域名」里填业务主机名(www 或 @)+ 源站 IP/域名。
  5. 平台分配一个 CNAME 地址(形如 xxx.edgeone.net),先记下来,步骤 5 统一填到 DNSPod。
  6. 证书:开启「站点加速 → HTTPS」自动证书(免费)。

4. 步骤 3:Cloudflare for SaaS(主域名不迁 NS 的关键)

Cloudflare Free/Pro/Business 套餐的普通接入要求把整个 zone 迁到 CF 的 NS,与分线路解析冲突。Cloudflare for SaaS(Free 套餐含 100 个自定义主机名免费)允许主域名不迁 NS、仅用 CNAME 挂到 CF:

  1. 用闲置域名(如 cf-host.example)在 Cloudflare 添加 zone,并把该域名的 NS 迁到 Cloudflare(承载 zone,仅此域名迁)。
  2. 承载 zone 内:SSL/TLS → Custom Hostnames(SSL for SaaS)→ Add Custom Hostname,填入你的主域名(如 www.example.com)。
  3. 按提示完成归属验证:CF 会给出一条验证 TXT(加到 DNSPod)+ 一个 CNAME 目标值(形如 xxx.1234.cdn.cloudflare.net),记下来用于步骤 5 的境外线路。
  4. 等待证书签发至状态 Active(通常数分钟到数小时)。之后 CF 自动管理该域名的证书与续期。

备选:若不想多养一个域名做承载 zone,可退回方案 C——EdgeOne 加速区域直接选「全球可用区」,一家覆盖全球,不做 Cloudflare(代价:境外节点质量与覆盖面不如 CF)。或评估 Cloudflare Business(约 $200/月)的官方 CNAME 接入。

5. 步骤 4:DNSPod 分线路记录(最终形态)

同一主机名、不同线路分别建行(全部 CNAME,避免 A/CNAME 冲突提示):

主机记录 线路 类型 记录值 说明
www 境内 CNAME xxx.edgeone.net(EO 分配) 大陆走 EdgeOne
www 境外 CNAME xxx.…cdn.cloudflare.net(SaaS 分配) 境外走 Cloudflare
www 默认 CNAME xxx.…cdn.cloudflare.net 未匹配线路(如部分境外 DNS)兜底

验证:境内 dig www.example.com(或 nslookup)应解析出 EdgeOne CNAME;用境外 DNS(如 dig @8.8.8.8)应解析出 Cloudflare CNAME。不同递归节点可能有缓存,等待 TTL 过期后复测。

6. 步骤 5:源站锁定(安全前提,不可跳过)

trust_proxy = true 意味着应用信任 CDN 写来的客户端头,前提是请求只能来自这两家 CDN:

  1. 从官方渠道取回源网段并配置防火墙 / 安全组,仅放行:
    • Cloudflare 官方 IP 段:https://www.cloudflare.com/ips/ (cloudflare.com/ips-v4、ips-v6)
    • EdgeOne 回源 IP 段:腾讯云 EdgeOne 文档「回源 IP 网段」页(会动态更新,建议做成定期同步或至少配置时核对)
  2. 放行你的运维入口(SSH 管理 IP)与回源端口(80/443),其余一律拒绝直连。
  3. 回归验证:跑一次仓库自带的 dev/security-selfcheck.sh,确认带伪造 CF-Connecting-IP 的直连请求已被防火墙拦下(应无法到达应用)。

7. 步骤 6:真实 IP 传递(EdgeOne 侧关键配置!)

EdgeOne 默认不携带 EO-Client-IP,必须在控制台开启,否则经 EdgeOne 的请求到源站后拿不到客户端真实 IP(自动封禁会误伤所有大陆访客):

  • 站点级:站点加速(全局)→ 网络优化 → 客户端 IP 头部配置 → 开启,头部名称务必填 EO-Client-IP(代码固定读这个名字,大小写敏感)。
  • 或域名级:规则引擎 → 创建规则(Host 匹配该域名)→ 操作:客户端 IP 头部 → 开启 → 名称填 EO-Client-IP``。

Cloudflare 侧无需额外配置:CF-Connecting-IP 默认就有且恒被 CF 覆盖为真实客户端 IP。

8. 步骤 7:防“借道伪造”剥离规则(双 CDN 特有安全约束)

两家并存时出现新的伪造面:攻击者借道 CDN-A 时携带 CDN-B 的权威头。例如客户端经 Cloudflare 访问时自行塞一个 EO-Client-IP: 任意IP,若 CF 透传该头到源站,代码会信任它 → 可绕过限流 / 自动封禁 / 单 IP 投票限制,或嫁祸他人。因此必须在两家 CDN 的回源请求上剥离对方权威头:

CDN 剥离动作 位置
Cloudflare 回源前删除请求头 EO-Client-IP Rules → Transform Rules → Modify Request Header(Free 套餐可用,规则数有限但只建一条即可)
EdgeOne 回源前删除请求头 CF-Connecting-IP 规则引擎 → 操作:修改回源请求头 → 删除 CF-Connecting-IP(或站点全局回源请求头设置)

X-Forwarded-For / X-Real-IP 不需要在此剥离:代码只在 TCP 对端落入 trusted_proxies 时才解析它们,两家 CDN 边缘 IP 不在清单内,天然不可信。

验证方法:分别经两家 CDN 发起带伪造头的请求(如 curl -H 'EO-Client-IP: 203.0.113.66' https://www.example.com/),在源站访问日志里确认最终到达的请求不包含伪造的对方头,且应用记录的客户端 IP 为你的真实出口 IP。

9. 步骤 8:应用配置(conf/app.ini)

[security]
trust_proxy = true
; trusted_proxies 仅用于“你自己的”反代/LB(如本机 nginx 127.0.0.1),
; 双 CDN 场景不需要也不应把两家 CDN 的全量网段填进来(代码直接信任 CF-Connecting-IP / EO-Client-IP)。
trusted_proxies =

[server]
; 若用防火墙按网段放行回源,可继续监听 :443;若希望更严,可只监听本机 + 本机回源代理。
listen =

行为(2026-09-03 起):trust_proxy = true 时 ResolveClientIP 依次信任 CF-Connecting-IP → EO-Client-IP → (仅当 TCP 对端在 trusted_proxies 内)解析 XFF/X-Real-IP → 最后回退 RemoteAddr。

10. 步骤 9:缓存与动态内容

TamaBox 是动态应用:

  • 两侧都不要缓存 HTML / 页面 / API 响应;只缓存静态资源。
    • EdgeOne:缓存规则命中 /static/* 与带版本号资源即可;
    • Cloudflare:Caching → Cache Rules 对 /static/* 开缓存,其余 Bypass。
  • 若将来启用 WebSocket 长连接:Cloudflare Free 支持;EdgeOne 需在站点配置里显式开启 WebSocket。
  • 注意两侧的 TLS 版本 / HTTP/3 行为差异属正常现象,与应用无关。

11. 上线切换与回滚

  1. 先切「默认」线路 → 观察 15~30 分钟(错误率、日志中的真实 IP 是否正确)。
  2. 再切「境内」线路(EdgeOne CNAME 生效)→ 用大陆网络(或大陆 DNS 递归查询)验证。
  3. 最后切「境外」线路到 Cloudflare SaaS CNAME → 境外访问验证 + 证书状态 Active。
  4. 回滚:把对应线路的 CNAME 改回原记录即可,秒级生效(DNS TTL 决定传播速度)。

12. 故障排查速查

现象 检查
大陆访问慢 / 未走 EO DNSPod「境内」线路是否已配 EO CNAME;nslookup 从大陆递归查询结果
境外访问失败 / 证书错误 SaaS Custom Hostname 状态是否 Active;境外线路 CNAME 是否拼错
自动封禁误封 / 限流全走同一个 IP EO「客户端 IP 头部」是否开启且名称是否为 EO-Client-IP;trust_proxy 是否 true
应用日志里出现伪造 IP 两家剥离规则是否生效;防火墙是否真的挡住了直连
根域无法配 CNAME 根域有 MX → 只加速 www/业务子域,@ 保持 A 记录

13. 相关代码与文档

  • 代码改动:internal/shared/ip.go(EO-Client-IP 信任分支)、internal/shared/ip_test.go(新增 4 条用例)、internal/conf/static.go 与 conf/app.sample.ini(注释同步)。
  • 单 CDN Cloudflare 加固参考:outputs/cloudflare-origin-lockdown-guide.md。
  • EdgeOne 客户端 IP 头部(腾讯官方文档,会更新):「携带客户端 IP 头部回源」。
  • Cloudflare for SaaS 官方文档:developers.cloudflare.com → SSL/TLS → SSL for SaaS。