Cloudflare报526 Invalid SSL certificate:源站证书与Nginx回源TLS排查

网站套了 CDN/WAF 后突然返回 526 Invalid SSL certificate,先别急着重签证书。526 的核心不是"浏览器不信任",而是边缘节点无法验证源站证书。

先分清:526 到底发生在哪一段

经过 CDN 的 HTTPS 有两段连接:访客到边缘节点、边缘节点到源站。浏览器看到的是边缘证书;526 关注第二段。地址栏证书正常,不代表源站证书正常。

第一步:确认当前是不是 Full (strict)

Full (strict) 会校验源站证书:证书必须未过期,由公开信任 CA 或 Cloudflare Origin CA 签发,且 CN 或 SAN 匹配请求主机名。

第二步:从源站视角建立 TLS 握手

准备源站真实 IP 或回源地址,不要直接测试经过 CDN 的域名。用 openssl s_client 指定源站地址,并以 -servername 发送 SNI:

复制代码
源站IP=203.0.113.10
域名=origin.example.com
openssl s_client -connect ${源站IP}:443 \
  -servername ${域名} -showcerts -verify_return_error

# 只看主题、签发者和校验结论
openssl s_client -connect ${源站IP}:443 \
  -servername ${域名} -showcerts 2>/dev/null \
  | grep -E 'subject=|issuer=|Verify return code'

连接 IP 却不带 SNI,可能拿到默认虚拟主机证书。排查多站点 Nginx 时,SNI 是必填项。

第三步:检查有效期、SAN 和证书链

先把源站返回的叶子证书保存下来,检查三个基本条件:

复制代码
openssl s_client -connect 203.0.113.10:443 \
  -servername origin.example.com -showcerts </dev/null 2>/dev/null \
  | awk '/BEGIN CERTIFICATE/{n++} n==1{print} /END CERTIFICATE/{if(n==1)exit}' \
  > /tmp/leaf.pem

openssl x509 -in /tmp/leaf.pem -noout \
  -subject -issuer -dates -ext subjectAltName
openssl x509 -in /tmp/leaf.pem -checkend 604800
  • 有效期 :当前时间必须位于 notBefore 与 notAfter 之间,刚续签但尚未切换也会继续报旧证书。
  • SAN:请求的主机名必须出现在 Subject Alternative Name,不能只看 Common Name。
  • 链:源站要发送叶子证书和必要的中间证书,让验证方能构建到受信任根的路径。

Nginx 证书文件:leaf 在前,中间证书在后

ssl_certificate 应按"服务器证书在前、中间证书在后"的顺序拼接。只部署 leaf,严格的边缘验证可能直接拒绝。

复制代码
# fullchain.pem:第一段是 leaf,后面是 intermediate
cat server.crt intermediate.crt > fullchain.pem

server {
    listen 443 ssl;
    server_name origin.example.com;
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/server.key;
}

这里有个常见坑:文件名叫 fullchain.pem 不代表内容真的完整。不要相信文件名,直接用 -showcerts 看线上实际发出了几段证书。

用 curl 和校验结果确认源站 HTTP 层

TLS 校验通过后,再看 HTTP 响应。测试源站时可用 --resolve,让请求保持目标域名的 Host 与 SNI,同时连接到源站 IP:

复制代码
curl -Iv --resolve origin.example.com:443:203.0.113.10 \
  https://origin.example.com/

# 只关心证书链校验,测试环境不要长期跳过校验
curl -v --resolve origin.example.com:443:203.0.113.10 \
  https://origin.example.com/

如果只用 -k 才能访问,说明客户端校验被绕过,不等于源站证书合格。生产验收不要使用 -k。

故障对照表:看到 526 先查哪一项

现象 常见原因 处理方向
源站连接被拒绝 443 未监听、防火墙拦截、回源端口错误 查 ss、firewalld、安全组和回源端口
源站返回过期证书 续签完成但 Nginx 未 reload,或边缘回源到旧节点 查线上日期、节点和 reload 时间
SAN 不包含请求域名 多站点 SNI 配置错误,返回默认站点证书 显式指定 -servername,核对 server_name
Verify return code 非 0 中间证书缺失、顺序错误或不受信任 改用正确 fullchain 并重新验收
源站直连正常,CDN 仍 526 CDN 回源 IP、端口或 SNI 与手工测试不同 核对回源配置和边缘侧要求

修改 Nginx 后,按这个顺序验收

证书文件替换后,先检查私钥与证书是否匹配,再做 Nginx 语法检查:

复制代码
# RSA 示例;ECC 证书使用对应的公钥摘要方式核对
openssl x509 -in /etc/nginx/ssl/fullchain.pem -pubkey -noout \
  | openssl pkey -pubin -outform pem -pubout \
  | sha256sum
openssl pkey -in /etc/nginx/ssl/server.key -pubout \
  | sha256sum

nginx -t
systemctl reload nginx

# reload 后重新从线上读取,而不是只检查磁盘文件
openssl s_client -connect 203.0.113.10:443 \
  -servername origin.example.com -showcerts \
  -verify_return_error </dev/null

多源站必须逐台执行上述验收。

上线前检查清单

  • 确认 526 对应的是边缘到源站的 TLS,而不是访客到边缘的证书。
  • 记录当前加密模式,Full (strict) 的源站校验要求已满足。
  • 使用源站地址 + 目标域名 SNI 获取线上真实证书。
  • 核对有效期、SAN、签发者和完整中间证书链。
  • Nginx 的 ssl_certificate 使用 leaf 在前的 fullchain 文件。
  • nginx -t 通过后再 reload,并重新建立线上握手。
  • 多源站、CDN、WAF 或负载均衡逐个验证,不能只测默认节点。
  • 外部入口最后再测,确认边缘证书和源站回源状态正常。
相关推荐
Initialize-le1 小时前
Nginx 504 超时、499 一堆?网关排查法
运维·nginx
郭老二8 小时前
【docker】docker compose使用,已nginx为例
nginx·docker·容器
zzu123zsw9 小时前
从 proxy_pass 末尾斜杠到 WebAssembly 预压缩:深挖 Nginx 生产环境四大高频踩坑点
运维·nginx·wasm·webassembly·devops·运维排错
郝亚军10 小时前
RK3562 中有 mosquitto、nginx 了,还需要 http,ftp,tftp 等协议吗?
运维·nginx·http
@嵌入式扫地僧13 小时前
Linux 中 TLS 线程局部存储如何避免多线程数据竞争
tls·多线程同步·数据竞争·线程局部存储·linux 多线程
Lsetea14 小时前
OpenSSL报certificate revoked:error 23与CRL吊销层级排查
linux·https·ssl证书·openssl·crl
HelloWorld工程师15 小时前
不改动任何历史配置,也能让 SSL 证书自动续期
linux·服务器·网络协议·https·ssl
Lsetea16 小时前
curl走HTTPS代理报SSL证书错误:proxy-cacert与cacert双层信任排查
linux·https·ssl证书·curl·代理服务器
2501_9378609419 小时前
HTTP/HTTPS 学习笔记(中):报头、Cookie、状态码与请求构造
学习·http·https
Peter-Code19 小时前
Nginx 常用操作整理(前端)
服务器·前端·nginx