Cloudflare 橙云灰云搞反,站点立刻挂 —— 排查与修复

Cloudflare DNS 那个橙/灰云图标决定流量走边缘还是直连源站。切错会弄断 SSL 签发、WebSocket、源站隐藏。这篇教你怎么选对。

最快修法: 进 Cloudflare 仪表盘里的对应 zone,打开 DNS 然后 Records,看每条 A / AAAA / CNAME 旁边的云图标。橙色(“Proxied”)= 流量过 Cloudflare 边缘;灰色(“DNS only”)= 直连源站。如果站点”莫名其妙就挂了”,基本可以肯定是你(或者某个厂商的操作指引)把某条记录切错了云。HTTP-01 的 SSL challenge 卡在 pending,就把 apex / www 记录切灰、等证书签出来、再切回橙。其他场景,照下面那张表把云状态对上。

这个图标干的事远不止一个 CDN 开关。橙云会重写对外的 TLS 链、用 Cloudflare anycast IP 把源站 IP 藏起来、把每个请求过一遍 WAF,并且套用你的 Page Rules、Workers、Cache Rules。灰云把这些全关掉,DNS 直接返回你真实的源站 IP。在橙灰之间来回切,是所有 Cloudflare 前置场景里”我什么都没改它就坏了”排名第一的原因。症状从 SSL 警告突然冒出来、到 WebSocket 每 100 秒断一次、到 CA 拒绝发证、到第二天源站被直接打爆,应有尽有。

Cloudflare 现在(截至 2026 年 6 月)对这个开关的正式叫法是 Proxy status:“Proxied”(橙)vs “DNS only”(灰)。旧文档和本文其余部分都用橙/灰云的说法,意思一样。

常见原因

每条都是”云切错”——分清你在哪种场景,就知道往哪边切。

1. 源站签 SSL 时需要灰云

Let’s Encrypt 的 HTTP-01 challenge 打 http://yourdomain.com/.well-known/acme-challenge/...。橙云时 Cloudflare 边缘先应答、送的是它自己的响应、不是源站的 challenge 文件,CA 验不过,签发就卡在 pending。(DNS-01 challenge 不受 proxy 状态影响,所以越来越多托管平台改用它。)

怎么判断:平台(Vercel / Render / Fly / 自建)SSL 状态卡 “SSL pending” / “Issuing” 好几个小时。Cloudflare DNS 面板里 apex 或 www 的 A / CNAME 记录是橙色(Proxied)。

2. WebSocket 被边缘截断

Cloudflare 所有套餐(含 Free 和 Pro)都通过橙云代理 WebSocket,但只要两个方向 100 秒都没数据它就会关掉这条连接(截至 2026 年 6 月)。长连接应用(Phoenix Channel / Socket.IO / 实时协作)一旦闲下来,橙云上大约每 100 秒掉一次。直连(灰云)源站的话,只要源站允许就能一直挂着。

怎么判断:连接大约每 100 秒掉一次,close code 是 10061001(“going away”)。同样的 socket 打灰云 / 直连源站能挂几小时不动。

3. apex CNAME 返回的 IP 随云状态而变

你把 yourdomain.com 设成 app.platform.com 的 CNAME。DNS 不允许 apex 上有 CNAME,所以 Cloudflare 会flatten(拍平)它——这里纠正一个常见误区:Cloudflare 对 apex CNAME 默认在所有套餐上都 flatten,不管这条记录是橙还是灰。区别在于返回什么 IP:橙云返回 Cloudflare 的 anycast IP(104.x / 172.67.x);灰云返回 app.platform.com 此刻解析出的平台真实 IP。

怎么判断dig yourdomain.com +short 橙云时返回 Cloudflare 段、灰云时返回平台自己的 IP。这里真正的故障一般出在平台那一侧——很多托管平台会拒绝 Host header 经由 Cloudflare IP 进来的请求,或者要求它自己的 CNAME 目标不被代理。(真正的 apex CNAME NXDOMAIN 只在 apex CNAME 托管在不做 flatten 的非 Cloudflare 解析器上时才会出现。)

4. 源站只靠 Cloudflare 隐藏 IP 才安全

你几周前开了橙云,后来因为某事切到了灰云(签证书、调试、厂商指引)。DNS 现在直接返回源站 IP,之前找不到源站的攻击者立刻能直打了。

怎么判断:源站负载飙升;访问日志里出现不来自 Cloudflare 已公布 IP 段的直接命中,且这些请求缺少 cf-connecting-ip header。

5. SSL Full vs Flexible 不匹配在切换时暴露

橙云时,Cloudflare 的 SSL/TLS 加密模式(Flexible / Full / Full (strict))决定它怎么跟源站对话。源站把 HTTP 跳到 HTTPS、Cloudflare 又是 Flexible,就死循环重定向。源站证书是自签名或过期、Cloudflare 又是 Full (strict),就报 526。

怎么判断ERR_TOO_MANY_REDIRECTS(Flexible + 源站跳 HTTPS);Error 525(到源站的握手失败——源站没监听 TLS,或协议/加密套件不匹配);Error 526(握手成功但 Full (strict) 下 Cloudflare 拒绝了源站证书)。

6. Page Rules / Workers 只在橙云时跑

Page Rules、Workers、Transform Rules、Cache Rules——灰云记录这些一概不跑。你为”DNS 调试”切了灰云就忘了,边缘逻辑就静默失效。

怎么判断:Worker 注入的 header 没了;Cloudflare 缓存命中率掉到 0;浏览器 DevTools 里没有 cf-ray 响应 header。

开始前

  • 在 Cloudflare 仪表盘打开 DNS 然后 Records,记下相关每条记录(apex、www、相关子域)当前的 Proxy status(橙/灰)。
  • SSL/TLS 然后 Overview 里看加密模式:Off / Flexible / Full / Full (strict),或者较新的 Automatic SSL/TLS(见第 3 步)。
  • 看清每个子域是哪个平台在跑(源站、Vercel、Fly…)——不同平台需要不同的云状态。
  • 手边留着源站直连 IP,必要时用 curl --resolve 测试。

需要收集的信息

  • dig yourdomain.com +short——Cloudflare IP(一般 104.x 或 172.67.x)还是源站 IP。
  • curl -sI https://yourdomain.com——看 cf-ray:server: cloudflare
  • SSL/TLS 然后 Overview 标签页的加密模式设置。
  • DNS 记录列表带云图标的截图。
  • 最近变更日志:谁切的、什么时候、为什么。

一步步修

按你的场景选模式。

第 1 步:每条记录想清楚目标状态

记录推荐云状态原因
自建源站(VM / 容器)橙云(Proxied)吃 DDoS 防护 + 缓存 + WAF;模式设 Full (strict),配真证书
托管平台上的 apex / www(Vercel、Netlify)一般灰云(看平台文档)很多托管平台自己终结 TLS,会拒绝被 Cloudflare 代理的 Host header
apex CNAME 指向 <platform>.com按平台指引Cloudflare 两种状态都 flatten;橙返 CF IP、灰返平台 IP
WebSocket 重的子域灰云,或 Business 及以上套餐Free/Pro 橙云 100 秒就关掉空闲 socket
邮件记录(MX / SPF / DKIM / DMARC)永远灰云邮件服务器不说 HTTP;Cloudflare 本来也不让你橙云化 MX

第 2 步:签 SSL 期间切灰云

1. Cloudflare 仪表盘 -> DNS -> Records
2. 点 apex(或 www)记录旁边的橙云
3. 变灰("DNS only")
4. 等 30 秒左右让改动在 Cloudflare 边缘生效
5. 在平台重新触发 SSL 签发
6. 等 "Issued" / "Active" 状态
7. 需要 Cloudflare 在前面的话,把灰云切回橙云

签发完可以再开橙云。平台的证书还在源站;Cloudflare 在外面再加一层边缘证书。如果你的平台支持 DNS-01 challenge,可以全程保持橙云、完全省掉这套来回切的操作。

第 3 步:把 Cloudflare 到源站的 SSL/TLS 加密模式调对

SSL/TLS 然后 Overview。截至 2026 年 6 月,很多 zone 现在默认走 Automatic SSL/TLS——它会探测源站,从 1% 流量起逐步放量到所选模式;证书过期时它也不会把你降级。如果你要手动设模式,照这张表:

源站状态必须的 Cloudflare 模式
源站有公共 CA 证书(Let’s Encrypt 等)Full (strict)
源站装了 Cloudflare Origin CA 证书Full (strict)
源站只有自签名证书Full
源站只听 HTTP :80Flexible(生产别用)

Full 走 HTTPS 但校验源站证书,所以自签名或过期证书也能过。Full (strict) 额外要求证书可信、未过期、主机名对得上——正是这个”严”会触发 526。Flexible 让 Cloudflare 到源站这一跳走明文 HTTP、却向用户报告 HTTPS:看着安全其实不是,而且源站也跳 HTTPS 时会报 ERR_TOO_MANY_REDIRECTS。免费的 Cloudflare Origin CA 证书(有效期最长 15 年、被 Cloudflare 边缘信任)是满足 Full (strict) 最省事的办法。

第 4 步:WebSocket 要长连接,选灰云或升级套餐

要长连接:

  • 方案 A: 客户端加一个 每 30-60 秒一次的心跳(ping/pong),让连接永远不会空闲到 100 秒。这是最省钱的修法,还能留在橙云。
  • 方案 B: 把 WebSocket 流量挪到专门子域(ws.yourdomain.com),那条记录灰云;apex 的 HTTP 流量留橙云。
  • 方案 C: 升级 Cloudflare Business 或 Enterprise,空闲超时更高 / 可配。
  • 方案 D: 用 Cloudflare Spectrum(Enterprise),不带 WebSocket HTTP 封套的全 TCP 代理。

第 5 步:临时切灰云调试,一定要设个切回来的提醒

常见坑:调试切了灰云,忘了,过几周。设个提醒:

echo "CHECK CLOUDFLARE: 是不是把 apex 切回橙云了?" | at now + 2 hours

或者 Slack / Linear / 日历任务。忘了切回橙云 = 静默失去 WAF、DDoS 防护、Workers、缓存。

第 6 步:灰云的话审计源站 IP 暴露

如果你确实要灰云,审一下暴露面:

dig yourdomain.com +short
# 直接返回源站 IP -- 谁都能拿到

缓解:

  • 把源站防火墙限制成只接受 Cloudflare 已公布的 IP 段(见 https://www.cloudflare.com/ips/)——前提是你打算切回橙云。
  • 如果这条记录会一直灰云,就把源站当成完全暴露处理:真正的防火墙、fail2ban、常规 DDoS 准备。

怎么确认修好了

  • curl -sI https://yourdomain.com 在你期望橙云时有 cf-ray: header、期望灰云时没有。
  • dig yourdomain.com +short 橙云返回 Cloudflare 段(104.x / 172.67.x),灰云返回源站 IP。
  • 浏览器 DevTools 里看证书链:橙云时是 Cloudflare 签的边缘证书(issuer 类似 “Cloudflare Inc ECC CA-3” / “WE1”),灰云时直接是源站 CA(比如 Let’s Encrypt)。
  • 加了心跳、切灰云或升级套餐之后,WebSocket 连接能撑过 100 秒。
  • 橙云记录在仪表盘里能看到 Workers / Page Rules / Cache Rules 的非零请求量。

长期预防

  • 把云图标当作生产开关,需要同伴 review,别随手切。
  • 在 DNS-as-code 仓库里固化每条记录的目标状态(Terraform cloudflare_recordproxied = true/false),让 PR diff 能挡住误切。
  • 用 Cloudflare 审计日志盯 DNS 变更,每周 review。
  • 每次临时切灰云都立刻挂一个带 deadline 的”切回来”任务。
  • 统一用 Full (strict) + 每个源站装 Cloudflare Origin CA 证书——彻底消除 Flexible / Full 的模糊地带。

常见坑

  • 为签证书切灰、忘了切回橙——静默失去 CDN、WAF、源站隐藏。
  • 因为”浏览器里看着行”就选 Flexible——CF 到源站走明文 HTTP,任何 auth header 都明文传。
  • 试图把 MX 记录橙云化;Cloudflare 直接拒绝,结果被报错搞糊涂。
  • 以为 Cloudflare 上灰云的 apex CNAME 会返回 NXDOMAIN——其实不会,Cloudflare 两种状态都 flatten apex,真正的问题通常是平台拒绝 Cloudflare 的 IP 或 Host header。
  • 忘了橙云在边缘终结客户端 TLS,所以源站证书不匹配在浏览器里看不出来,但会让 Full (strict) 报 526。

FAQ

Q:为什么浏览器里我的 Let’s Encrypt 证书 issuer 显示成 “Cloudflare”?

因为浏览器看到的是 Cloudflare 的边缘证书,是 Cloudflare 给你域名签的。源站的 Let’s Encrypt 证书在 Cloudflare 到源站那一跳上(Flexible 模式下则根本不存在)。橙云下浏览器永远看不到源站证书。

Q:apex 橙、www 灰可以吗?反过来呢?

可以。每条记录都有自己的 proxy 状态。注意 root↔www 之间的重定向要清楚是哪边在 Cloudflare 前面,免得死循环或者把源站暴露出去。

Q:WebSocket 在橙云下挺正常,100 秒上限消失了?

没消失——截至 2026 年 6 月,Free 和 Pro 上 100 秒空闲就关闭依然有效。你的能撑住是因为连接其实没空闲(Socket.IO 和多数客户端会定期发 ping)、你用了更高套餐、或者你的 socket 本来就短。这个上限是针对一条无数据的空闲 TCP 连接、不是逻辑会话。

Q:Error 525 和 Error 526 有什么区别?

525 是 Cloudflare 到源站的 TLS 握手直接失败——源站没监听 TLS,或协议/加密套件不匹配。526 是握手成功了,但 Full (strict) 下 Cloudflare 拒绝了源站证书:过期、自签名、不可信,或主机名不对。修源站证书(装个 Cloudflare Origin CA 证书最省事),或者临时降到 Full 来确认就是证书问题。

Q:proxy 状态会影响我的 SSL 证书签发吗?

只对 HTTP-01 challenge 有影响——它走 HTTP,会被橙云边缘截走。签发期间把记录切灰,或者改用与 proxy 状态无关的 DNS-01 challenge。

延伸阅读:绑了自定义域名但 SSL 没发SSL 混合内容警告HTTPS 没强制A 记录跟 CNAME 分不清

标签: #排查 #cloudflare #DNS #proxy #排查