Cloudflare 的 DNS 面板里每条 A / AAAA / CNAME 旁边都有个小橙云图标。橙色 = 走 Cloudflare 边缘代理;灰色 = 纯 DNS、流量直连源站。很多人没意识到这个图标改了多少东西——它不只是 CDN 开关。橙云会重写 SSL 链、把源站 IP 藏起来、把每个请求过一遍 WAF、DNS 返回的是 Cloudflare 的 IP。从橙切灰、或者灰切橙,是所有 Cloudflare 前置场景下”我什么都没改它就坏了”排名第一的原因。症状从 SSL 警告突然冒出来、到 WebSocket 不停断、到 SSL 签发商拒绝发证、到第二天源站被直接打爆,应有尽有。
常见原因
每条都是”云切错”——分清楚你在哪种场景,就知道往哪边切。
1. 源站签 SSL 时需要灰云
Let’s Encrypt 的 HTTP-01 challenge 打 http://yourdomain.com/.well-known/acme-challenge/...。橙云的话 Cloudflare 边缘先应答——它送自己的响应、不是源站的 challenge 文件。CA 验不过,签发就挂在 pending。
怎么判断:平台(Vercel / Render / Fly / 自建)SSL 状态卡 pending 几小时。Cloudflare DNS 里 apex 或 www 的 A 记录是橙云。
2. WebSocket 被边缘截断
Cloudflare 免费版和 Pro 通过橙云代理支持 WebSocket,但有 100 秒 idle 超时、大部分套餐只走 HTTP。长连接应用(Phoenix Channel / Socket.IO / 实时协作),橙云上每 100 秒就掉一次。
怎么判断:连接每 100 秒左右重连一次,错误码 1006 或 going away。直连源站能挂几小时不动。
3. apex CNAME flattening 把流量带进 Cloudflare 边缘了
你把 yourdomain.com 设成 app.platform.com 的 CNAME。DNS 原生不允许 apex CNAME,所以 Cloudflare “flatten” 它——但只有橙云才 flatten。灰云时 CNAME 原样返回,很多解析器对 apex 查询会拒绝。
怎么判断:灰云 + apex CNAME = apex 间歇性 NXDOMAIN。橙云能用,但返回的是 Cloudflare IP,不是平台 IP。
4. 源站只靠 Cloudflare 隐藏 IP 才安全
你几周前开了橙云。后来因为某事切到了灰云(签证书、调试、厂商指引)。DNS 现在直接返回源站 IP,之前找不到源站的攻击者立刻能直打了。
怎么判断:源站负载飙升,日志里直接来源命中、不是 Cloudflare IP 段(缺少 cf-connecting-ip header)。
5. SSL Full vs Flexible 不匹配在切换时暴露
橙云的时候,Cloudflare 的 SSL 模式(Flexible / Full / Full-Strict)决定它怎么跟源站说话。源站把 HTTP 跳到 HTTPS、Cloudflare 是 Flexible 模式,就死循环重定向。源站是自签名、Cloudflare 是 Full-Strict,就报 526。
怎么判断:ERR_TOO_MANY_REDIRECTS(Flexible + 源站跳 HTTPS)、526 Invalid SSL certificate(Full-Strict + 源站自签名)。
6. Page Rules / Workers 只在橙云时跑
Page Rules、Workers、Transform Rules、Cache Rules——灰云记录这些都不跑。你为”DNS 调试”切了灰云就忘了,边缘逻辑就静默失效。
怎么判断:Worker 注入的 header 没了。Cloudflare 缓存命中率掉到 0。浏览器 DevTools 里没有 cf-ray header。
开始前
- 打开 Cloudflare DNS 面板,记下每条记录(apex、www、相关子域)当前的云颜色。
- 看 Cloudflare 仪表盘里的 SSL/TLS 模式:Flexible / Full / Full-Strict / Strict-Origin。
- 看清楚每个子域是哪个平台在跑(源站、Vercel、Fly…)——不同平台需要不同的云状态。
- 手边留着源站直连 IP,必要时用
curl --resolve测试。
需要收集的信息
dig yourdomain.com +short输出——Cloudflare IP(一般 104.x 或 172.67.x)还是源站 IP。curl -I https://yourdomain.com输出——看cf-ray:、server: cloudflare。- Cloudflare SSL/TLS 标签页的 SSL 模式设置。
- DNS 记录列表带云图标的截图。
- 最近变更日志:谁切的、什么时候、为什么。
一步步修
按你的场景选模式。
第 1 步:每条记录想清楚目标状态
简单规则:
- apex A 指向平台 IP(Vercel / Netlify):发完证书可以开橙云,但平台可能不支持被 Cloudflare 代理。看平台文档。Vercel 和 Netlify 一般偏好灰云。
- apex 是 CNAME 指向
<platform>.com:橙云能 flatten,但源站平台可能拒绝 Host header 里的 Cloudflare IP。按平台具体文档测。 - 自建源站(自己的 VM / 容器):橙云推荐,吃 DDoS 防护 + 缓存。SSL 模式 Full-Strict,配真证书。
- 邮件记录(MX / SPF / DKIM):永远不代理。邮件服务器不说 HTTP。永远灰云。(Cloudflare 本来也不让你橙云化 MX。)
- WebSocket 重的子域:免费版 / Pro 需要超过 100 秒就灰云,或者升级套餐。
第 2 步:签 SSL 期间切灰云
1. Cloudflare DNS 面板
2. 点 apex(或 www)记录旁边的橙云
3. 变灰
4. 等 30 秒左右让 Cloudflare 边缘的 DNS 传播
5. 在平台重新触发 SSL 签发
6. 等 "issued"
7. 灰云切回橙云(如果你需要 Cloudflare 在前面)
签发完可以再开橙云。平台的证书还在源站;Cloudflare 在外面再加一层边缘证书。
第 3 步:把 Cloudflare 到源站的 SSL 模式调对
Cloudflare 仪表盘 → SSL/TLS → Overview:
| 源站状态 | 必须的 Cloudflare 模式 |
|---|---|
| 源站有 Let’s Encrypt / 公共 CA 证书 | Full (strict) |
| 源站只有自签名 | Full |
| 源站只听 HTTP :80 | Flexible(生产别用) |
| 源站装了 Cloudflare Origin Cert | Full (strict) |
Flexible 让 Cloudflare 到源站走明文 HTTP,向用户报告 HTTPS——看着安全但其实不是,源站也跳 HTTPS 的话直接死循环。
第 4 步:WebSocket 需求长连接的话,选灰云或升级套餐
要长连接:
- 方案 A:把 WebSocket 流量挪到专门子域(
ws.yourdomain.com),那条记录灰云。apex HTTP 流量留橙云。 - 方案 B:升级 Cloudflare Business 或 Enterprise,去掉 100 秒上限。
- 方案 C:用 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-v4/)——前提是你打算切回橙云。 - 永久灰云的话,把源站当成完全暴露处理:真正的防火墙、fail2ban、常规 DDoS 准备。
验证
curl -I https://yourdomain.com在橙云时有cf-ray:header、灰云时没有。dig yourdomain.com +short在橙云时返回 Cloudflare IP 段(104.x / 172.67.x),灰云时返回源站 IP。- 浏览器 DevTools 里 SSL 证书链:橙云签给你的域名、issuer 类似 “Cloudflare Inc ECC CA-3”;灰云直接是 Let’s Encrypt 或源站 CA 签的。
- 需要长连接时,超过 100 秒 WebSocket 不掉(灰云或升级了套餐)。
- 仪表盘里橙云记录的 Workers / Page Rules / Cache Rules 看到非零流量。
长期预防
- 把云图标当作生产开关,需要同伴 review,不要随手切。
- DNS-as-code 仓库里写清楚每条记录的目标状态(Terraform
cloudflare_recordproxied = true/false)——PR diff 能挡住误切。 - 用 Cloudflare 审计日志对任何 DNS 变更告警,每周 review。
- 每次临时切灰云都立刻挂一个”切回来”的任务、带 deadline。
- 标准化 SSL 模式为 Full (strict),所有源站发 Cloudflare Origin Cert——彻底消除 Flexible / Full 的模糊地带。
常见坑
- 为签证书切灰、忘了切回橙——静默失去 CDN、WAF、源站隐藏。
- SSL 模式调 Flexible,因为”浏览器里看着行”——CF 到源站走明文 HTTP,任何 auth header 都暴露。
- 试图把 MX 记录橙云化(Cloudflare 直接拒绝),结果被错误信息搞糊涂。
- apex CNAME 配灰云,间歇命中那些不支持 apex CNAME 的解析器就挂——要 flatten 必须橙云。
- 忘了橙云时 Cloudflare 在边缘终结 TLS、源站证书不匹配对浏览器不可见、但会弄坏 Full-Strict 模式。
FAQ
Q:为什么浏览器看到的 Let’s Encrypt 证书 issuer 是 “Cloudflare Origin CA”?
不是的——浏览器看到的是 Cloudflare 的边缘证书,Cloudflare 给你的域名签的。源站的 Let’s Encrypt 证书存在于 Cloudflare 跟源站之间(或者不存在,Flexible 模式)。橙云下浏览器永远看不到源站证书。
Q:apex 橙、www 灰可以吗?反过来呢?
可以。每条记录都有自己的云状态。注意两边互相重定向(root ↔ www)时,要清楚是哪边在 Cloudflare 前面。
Q:WebSocket 在橙云下挺正常,100 秒上限消失了?
可能是连接自动重连了(Socket.IO 自带),或者升级了套餐,或者你的 socket 本来就短。上限是针对一条无数据的 idle TCP 连接、不是逻辑会话。
Q:报 526 是什么?
Cloudflare 到源站的 SSL 握手在 Full (strict) 模式下失败。源站证书过期了、自签名、或者主机名不对。修源站证书,或者 SSL 模式降到 Full(不 strict,接受自签名)。
延伸阅读:绑了自定义域名但 SSL 没发、SSL 混合内容警告、HTTPS 没强制、A 记录跟 CNAME 分不清。
标签: #排查 #cloudflare #DNS #proxy #排查