给网站套 CDN 本来是为了提速,结果配置一保存,页面直接变成一行冷冰冰的 502 Bad Gateway。速度没提上来,业务先断了。
这种情况在阿里云 CDN 上很常见,而且绝大多数不是 CDN 的锅,是回源这一跳没对上。
CDN 的工作方式本质上是反向代理:用户的请求先到边缘节点,节点没有缓存就代替用户去源站取。只要它拿不到源站的有效响应,就会返回 502。所以 502 的断点只可能在四个位置:回源协议与端口、回源 SNI 与 HOST、源站证书、源站防火墙。
先别急着一个个试。动手前先看清状态码,能省掉一半弯路:
| 状态码 | 典型含义 | 优先怀疑 |
|---|---|---|
| 502 Bad Gateway | 回源连不上、TLS 握手失败 | 协议、端口、SNI、证书 |
| 504 Gateway Timeout | 连上了,但源站没在限定时间内返回 | 源站性能、防火墙静默丢包、回源超时设置 |
| 403 Forbidden | 源站收到了,但主动拒绝 | 防盗链、IP 限制、WAF 拦截回源 |
下面这套流程按「从易到难、从外到内」排列,六步走完基本能定位到具体那个配置项。

第一步:绕开 CDN,先分清是谁的问题
排查的第一步不是看 CDN 控制台,是把 CDN 摘出去。
最省事的办法是改本地 hosts,把域名直接指到源站真实 IP。如果你有服务器权限,用 curl 的 --resolve 参数更干净,不用动系统文件:
curl -I https://www.example.com --resolve www.example.com:443:1.2.3.4
把 www.example.com 换成你的加速域名,1.2.3.4 换成源站真实 IP。这条命令的意思是:域名照常解析用于 SNI 和 Host 头,但连接强制打到指定 IP。
这里有个细节值得说:别只用 curl -I。-I 发的是 HEAD 请求,部分站点或 WAF 会直接拒绝 HEAD,返回 405 或 403,容易让你误判成「源站也挂了」。想看得更准,用这条:
curl -o /dev/null -s -w "code:%{http_code} connect:%{time_connect} first:%{time_starttransfer} total:%{time_total}\n" https://www.example.com --resolve www.example.com:443:1.2.3.4
它一次给你四个数字:状态码、TCP 建连耗时、首字节耗时、总耗时。后面排查 504 的时候,time_connect 和 time_starttransfer 的差值能直接告诉你卡在「连不上」还是「源站算得慢」。
判断标准很简单:
- 直连源站也 502 → 源站自己病了(Web 服务没起、PHP 进程崩了、后端全挂)。先去修服务器,CDN 侧一个字都不用改。
- 直连源站正常,只有走 CDN 才 502 → 问题在回源配置,继续往下。
第二步:回源协议和端口,必须和源站实际监听一致
这是新手踩得最多的坑,而且一踩就是全站 502。
CDN 回源时,协议和端口必须与源站真正在监听的那一套完全对齐。两个典型错法:
协议不匹配。源站只监听 80、压根没配 SSL 证书,你在 CDN 控制台把回源协议设成 HTTPS,节点会老老实实发一个 TLS 握手过去。源站那边是明文 HTTP 服务,接不住 ClientHello,握手直接失败,502。
端口不一致。源站实际在 8080 上跑服务,回源端口填的默认 80,TCP 都建不起来。
这里要专门纠正一个常见误解:「协议跟随」不是万能档。
协议跟随跟的是客户端的协议,不是源站的能力。客户端用 HTTP 访问,CDN 就以 HTTP 回源;客户端用 HTTPS 访问,CDN 就以 HTTPS 回源。你的站全站上了 HTTPS,那所有客户端都是 HTTPS——「跟随」等于「永远 HTTPS 回源」,和直接选 HTTPS 结果一模一样。
所以源站没配证书的情况下,把回源协议从 HTTPS 改成「跟随」是无效操作,照样 502。要么给源站装证书,要么老老实实选 HTTP。
确认方法是在源站上看它到底监听什么:
ss -lntp | grep -E ':(80|443|8080)'
输出里出现哪个端口、绑在哪个进程上,一目了然。别凭印象,很多「我记得开了 443」最后都发现是 Nginx 配置里那个 server 块没启用。
第三步:回源 SNI 与回源 HOST,两个东西别混为一谈
这一步是整篇文章最值得记住的地方,因为这两个配置项名字很像、通常填同一个值,但作用在完全不同的层。

回源 SNI 管的是「哪张证书」。它工作在 TLS 握手阶段。当一个 IP 上挂了多个 HTTPS 站点,源站靠 ClientHello 里的 SNI 字段判断该出示哪张证书。CDN 回源时不带 SNI 或带错了,源站拿不出对应证书,握手失败,502。
回源 HOST 管的是「哪个站点」。它工作在 HTTP 层,就是请求头里的 Host。Nginx 靠 server_name 匹配虚拟主机,HOST 不对就会落到默认站点,看到的是别的站的页面,或者直接 404、403、502。
配置路径:CDN 控制台 → 域名管理 → 选中域名 → 回源配置,把「回源 SNI」打开,填源站实际提供服务的域名(通常与证书 Common Name 一致);同时把「回源 HOST」也设成同一个源站域名。
这里有个官方文档提了一句、但很容易被忽略的收尾:回源时 CDN 会校验 SNI 与源站证书的 Common Name 是否一致。如果你的源站用的是统一接入层证书(比如负载均衡那层发了张泛域名证书),SNI 和 Common Name 天然对不上,那就需要把证书的 Common Name 加进控制台的 Common Name 白名单。
不配这一步,会出现一种很气人的现象:SNI 明明填对了、证书明明有效,还是 502。查半天查不出原因,就是卡在这。
想手工确认源站对某个 SNI 返回什么证书:
openssl s_client -connect 1.2.3.4:443 -servername www.example.com < /dev/null 2>&1 | openssl x509 -noout -subject -dates
第四步:源站证书是不是已经失效了
如果回源协议确实是 HTTPS,接下来查源站证书本身。四种情况 CDN 都会拒绝连接:
- 过期——最常见,尤其中间忘了续。
- 被吊销——CA 侧已作废。
- 域名不匹配——证书签的是
a.com,你回源用的是b.com。 - 自签名或内部 CA 签发——CDN 的信任库只认公有 CA,这类证书一律不通过。
一条命令看全:
curl -Iv https://www.example.com --resolve www.example.com:443:1.2.3.4 2>&1 | grep -E "expire|subject|issuer|SSL certificate"
处理方式两条路:换一张受信任的公网 CA 证书(推荐,顺手把全站 HTTPS 也修了);或者把回源协议降级为 HTTP(治标,但源站到 CDN 这一段就变明文了,不建议长期这样)。
第五步:源站的安全策略,可能把 CDN 当成了攻击
这一步特别隐蔽。源站本身没问题、配置全对,但安全组、iptables、云锁、安全狗或者 WAF 把 CDN 回源节点的 IP 判成了恶意访问,直接拦掉。表现出来就是 502、503 甚至 403 混着来。
很多教程到这一步会说「去控制台把 CDN 回源 IP 段加进白名单」。方向没错,但有三件事必须先知道,否则你会在控制台里找不到入口:
第一,回源 IP 是动态的。它指的是 L2 回源节点的 IP,随调度变化、定期更新。白名单一旦过期,同样的问题会再来一次。
第二,这个 IP 列表不是人人都能拿。要通过 DescribeL2VipsByDomain 接口取,而这个接口要求日峰值带宽 ≥ 1Gbps 并单独申请权限。中小站点的号根本调不动——所以那些「照着教程去控制台下载回源 IP 段」的步骤,很多人第一步就卡住了。早年的「人工申请 IP 段」通道也已经停止受理。
第三,官方自己也不建议只靠 IP 白名单。因为 IP 在变,白名单天生追不上。
更实际的做法是不依赖 IP 做判断。阿里云 CDN 回源时会带一个 ali-cdn-real-ip 请求头(携带真实客户端 IP,比 X-Forwarded-For 更难伪造),源站可以按这个头来识别合法回源。配合 Referer 防盗链和 URL 鉴权,安全性比死守 IP 段更稳。
Nginx 侧可以这么配(放在对应 server 块里):
# 只允许携带 CDN 回源头标识的请求访问敏感路径
location ~ ^/(admin|api/internal)/ {
set $is_cdn 0;
if ($http_ali_cdn_real_ip) { set $is_cdn 1; }
if ($is_cdn = 0) { return 403; }
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
注意这只是辅助判断,请求头可以伪造,真正的访问控制还得靠鉴权。如果你源站前面还有一层 WAF,两边的回源白名单都要放行,只放开一边照样断。
第六步:区域性和跨境链路
前面五步都排干净了,但仍有部分地区用户报 502,那要看链路。用阿里云的网络拨测工具按地区打点,如果 502 集中在特定区域(尤其是海外访问国内源站),基本可以判定是链路层面的问题。
这种情况的处理方式和前面几步不同——不是改配置能解决的,得从架构上动手:加双源站做冗余、上全球加速、或者干脆把静态资源托管到对象存储。
另外补一句判断技巧:先看 X-Cache 再决定查哪儿。X-Cache: HIT 说明请求命中了缓存,异常响应很可能来自一份旧的缓存;X-Cache: MISS 说明 CDN 已经回源了,这时候还异常,问题一定在回源链路或源站本身。
六步之后:改完配置,怎么确认真的好了
这一步原本文档里只写了「记得多测试」,但实际操作里有个大坑:改了回源配置,节点上已经缓存的异常响应不会自动失效。
也就是说,你把 HOST 改对了、SNI 填好了,访问还是 502——因为节点返回的是改之前缓存下来的那个 502。这时候你会以为没修好,继续瞎改,越改越乱。

正确顺序是:先刷新缓存,再验证。改过回源 HOST 建议做目录刷新(整站可能都受影响);只改了协议或证书,URL 刷新就够。
然后看三个字段:
curl -I https://www.example.com/
- 状态码——200 就是通了。
- X-Cache——
HIT或MISS,用来判断这次到底走没走回源。 - Via——确认请求确实经过了 CDN 节点。
这里有个流传很广的错误说法,必须澄清一下:Via 里的 M 不代表回源失败。
阿里云 CDN 的 Via 头分两段:前半段是二级节点(L2)的状态,
H表示已命中;后半段是一级节点(L1,也就是边缘节点)的状态,M表示边缘节点上没有缓存、需要向 L2 回源。M是冷请求的正常表现,几乎每个首次访问的资源都是 M。把它当成「回源失败」去排查,只会白折腾一轮。
判断缓存到底命中没有,看 X-Cache,别只看 Via。
还有两个容易漏掉的收尾
一是源站强制跳转 HTTPS 造成的回源死循环。源站在宝塔里开了「强制 HTTPS」,而 CDN 用 HTTP 回源——CDN 发 HTTP 过去,源站 301 跳 HTTPS,CDN 再跟,循环起来。表现是 ERR_TOO_MANY_REDIRECTS。要么关掉源站的强制跳转,要么把回源协议也设成 HTTPS。这条和 502 不是同一个错,但经常一起出现,容易混。
二是 5xx 的缓存时间。默认情况下 CDN 对 5xx 只缓存 1 秒,影响不大。但如果你之前在控制台给 5xx 配过较长的「状态码过期时间」,异常响应会一直挂在那儿。改完配置还是报错的话,顺手检查一下这个设置,把 5xx 的缓存时间改成 0。
写在最后
把这六步走完,90% 的 502 都能定位到具体那个配置项。真到要向阿里云提工单的地步,别只写「我的网站 502 了」——把 F12 里完整的 Response Headers 贴上去,尤其是 X-Cache、Via、X-Swift-Error 这几个字段,工程师看一眼就知道卡在哪一跳,比来回问三轮快得多。
最后说个常被忽略的边界:CDN 解决的是「快」,不解决「扛」。缓存能挡住重复请求,但挡不住 CC 攻击那种每次都不一样、每次都穿透到源站的请求。如果你的站经常被刷,只靠 CDN 的缓存层是撑不住的,得在回源前面加一道真正的防护。
这块我们之前写过不少:WAF 回源异常的 502/504 排查可以从另一侧对照着看;CDN 自带的 WAF 够不够用讲的是要不要再加一层;如果你源站 IP 已经暴露、防火墙白名单那套玩不转,源站暴露了怎么办这篇更对症。主机吧这边常用的组合是 CDN 加速 + 百度云防护 WAF 或 速度网络高防 IP,加速和防护各管一段,别指望一个产品把两件事都办了。
参考资料:阿里云 CDN 官方文档《回源排障指南》《获取 CDN 回源节点 IP 地址》《配置回源 SNI 与回源 HOST》,2026 年 9 月版。文中命令中的域名与 IP 均为占位示例,请替换为你的实际值。
