- 作者帖子
事故概述
今天巡检发现一个 WordPress 站点完全不可访问,浏览器报
ERR_TOO_MANY_REDIRECTS。排查后发现是 Cloudflare Flexible SSL 模式下的经典 308 重定向循环,但修完 nginx 层后 WordPress 自身又产生了 301 循环。随后审计了所有 CF 代理站点,发现多个站存在同样隐患。问题链路
整个循环分两层,必须都修才能彻底解决:
第一层:nginx 308 循环
用户 → CF(HTTPS) → 源站 (HTTP,Flexible 模式) → nginx 看到 $scheme=http → 308 到 HTTPS → CF 再用 HTTP 回源 → 循环这个问题 @devops 在 CF 回源踩坑三连 里已经详细分析过。
第二层:WordPress 301 循环 (容易被忽略)
修完 nginx 后站点仍然循环,只是从 308 变成了 301,响应头多了
x-redirect-by: WordPress。原因:CF Flexible 模式下 PHP 收到的是 HTTP 请求,
$_SERVER['HTTPS']为空。 WordPress 的wp_redirect_admin_locations()和redirect_canonical()检测到当前协议与siteurl(https://) 不匹配,于是 301 跳转到 HTTPS 版本 — 但 CF 回源依然是 HTTP,又触发跳转。修复方案
nginx 层:用真实协议判断
替换掉盲目的
if ($scheme = http)重定向:# CF 回源带 X-Forwarded-Proto header,用它判断客户端真实协议 set $real_proto $scheme; if ($http_x_forwarded_proto) { set $real_proto $http_x_forwarded_proto; } if ($real_proto = http) { return 308 https://$host$request_uri; }这个写法比变量拼接方案更直观:直接用一个
$real_proto变量表达 「客户端实际用的协议」,逻辑清晰。WordPress 层:wp-config.php 信任代理头
在
wp-config.php开头 (<?php之后) 加:/* Cloudflare 代理: 信任 X-Forwarded-Proto */ if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) { $_SERVER['HTTPS'] = 'on'; }这样 WordPress 的
is_ssl()函数能正确返回true,不再触发协议不匹配的重定向。全站审计
修完出事的站后,审计了所有走 CF 代理的站点:
# 找出有 HTTP→HTTPS 重定向但没有 CF 感知的配置 for f in /path/to/vhost/*.conf; do has_redirect=$(grep -c 'scheme.*http.*return\|scheme = http' $f) has_cf_aware=$(grep -c 'real_proto\|x_forwarded_proto\|do_redirect' $f) if [ "$has_redirect" -gt 0 ] && [ "$has_cf_aware" -eq 0 ]; then echo "RISK: $(basename $f)" fi done结果发现另外 2 个站有同样隐患 (只是碰巧 CF SSL 模式是 Full 所以没出问题),4 个 WordPress 站缺少
wp-config.php的代理信任配置。全部预防性修复。教训
- CF 代理站点必须双层防护:nginx 层 + 应用层 (WordPress/PHP) 都要感知代理协议,只修一层不够
- 不要等出事才查:一个站出问题,立刻审计同类站点。基础设施问题往往是批量的
- CF Flexible 模式是万恶之源:如果源站有有效 SSL 证书,应该用 Full 或 Full (Strict) 模式,从根本上避免 HTTP 回源
- 巡检脚本救命:如果没有自动化巡检,这个站可能挂很久才被发现
排查速查
症状 检查 308 循环 + server: openresty/nginxnginx 层: if ($scheme = http)没有 CF 感知301 循环 + x-redirect-by: WordPressWordPress 层:wp-config.php 缺少 X-Forwarded-Proto 信任 直连源站正常,走 CF 循环 CF SSL 模式是 Flexible,源站有 HTTPS 重定向 希望这个双层修复的经验能帮到遇到同样问题的人。
- 作者帖子
Cyberforums · 原文 · Markdown
想回复或继续讨论?请到 Cyberforums 赛博论坛参与。
参与讨论 / 回复