---
canonical: https://meta.cyberforums.com/t/cloudflare-308-522-429/1834
webpage: https://wpcy.com/community/t/1834-cloudflare-308-522-429
language: zh-Hans
---

# Cloudflare + 反向代理回源踩坑三连：308循环 / 522黑洞 / 429限流

> 文派叶子支持论坛的只读副本，本页不能回复。
> 讨论原文：https://meta.cyberforums.com/t/cloudflare-308-522-429/1834
> 网页版：https://wpcy.com/community/t/1834-cloudflare-308-522-429

## 1 · devops

- 发布时间：2026年3月1日 23:09

背景
给多个站点接入 Cloudflare 加速，架构是 CF → 边缘反代服务器(nginx) → 源站。过程中连续踩了三个坑，都跟 CF 的回源机制有关，记录下来方便排查。
坑一：CF Flexible + 源站 308 = 重定向循环
现象：站点开启 CF Proxied 后浏览器报 &#12300;ERR_TOO_MANY_REDIRECTS&#12301;。
原因：CF SSL 设置为 Flexible 模式时，CF 用 HTTP 80 回源。但源站 nginx 对所有 HTTP 请求做了 308 跳 HTTPS：
if ($scheme = http) {
    return 308 https://$host$request_uri;
}

CF 收到 308 后跟随跳转，再次用 HTTP 连源站 → 又收到 308 → 死循环。
修复：让源站识别 CF 流量，跳过重定向。CF 回源时会带 X-Forwarded-Proto header，利用这个做条件判断：
# 变量组合：只对「HTTP 且非 CF」的请求做 308
set $do_redirect "";
if ($scheme = http) {
    set $do_redirect "H";
}
if ($http_x_forwarded_proto = "") {
    set $do_redirect "${do_redirect}N";
}
if ($do_redirect = "HN") {
    return 308 https://$host$request_uri;
}

逻辑：$scheme=http（H）+ 没有 X-Forwarded-Proto（N）= 直接访问才跳转。CF 回源带了这个 header，不会触发 308。

nginx 知识点：nginx 的 if 不支持 AND/OR 逻辑运算符，需要用 set 变量拼接字符串来模拟组合条件，这是 nginx 社区常用的 pattern。

备选方案：在源站安装 CF Origin Certificate，SSL 模式改为 Full，CF 直接用 HTTPS 回源。但需要管理证书，不如改 nginx 条件简单。
坑二：CF for SaaS fallback origin 指向黑洞 IP → 522
现象：域名 DNS 已指向 CF，Proxied 已开，但访问返回 522（Connection timed out）。
原因：使用 CF for SaaS（SSL for SaaS）时，fallback origin 的 A 记录指向了 192.0.2.1。这是 RFC 5737 定义的文档保留地址（TEST-NET-1），不会路由到任何真实服务器，等同于黑洞。CF 尝试回源到这个 IP，自然超时。
修复：把 fallback origin 的 A 记录改为源站的真实 IP。

知识点：RFC 5737 定义了三个文档专用地址段：192.0.2.0/24（TEST-NET-1）、198.51.100.0/24（TEST-NET-2）、203.0.113.0/24（TEST-NET-3）。如果在 DNS 记录里看到这些 IP，基本可以确定是占位符没改。

坑三：反代服务器没传真实 IP → 后端 429 限流
现象：站点通过 CF 访问时，部分静态资源（CSS/JS）返回 429 Too Many Requests。直接访问源站正常。
原因：CF → 反代服务器这段，反代的 nginx 配置了 set_real_ip_from + real_ip_header CF-Connecting-IP，看起来没问题。但 Ubuntu/Debian 默认安装的 nginx 没有编译 ngx_http_realip_module 模块，这些指令静默失效。
结果：$remote_addr 仍然是 CF 边缘节点的 IP，传给后端的 X-Real-IP 也是 CF 的 IP。后端应用（这里是 Discourse）把所有用户当成同一个 IP，触发 rate limit。
验证模块是否存在：
nginx -V 2>&1 | grep -o 'real_ip'
# 有输出说明模块已编译，无输出说明缺失

修复：不依赖 realip 模块，直接用 CF 的 header 变量：
proxy_set_header X-Real-IP $http_cf_connecting_ip;
proxy_set_header X-Forwarded-For $http_cf_connecting_ip;

$http_cf_connecting_ip 是 nginx 自动从请求头 CF-Connecting-IP 提取的变量，不需要任何额外模块。

安全提示：如果反代服务器不是只接受 CF 流量，CF-Connecting-IP header 可以被客户端伪造。建议配合防火墙只允许 CF IP 段 访问反代的 80/443 端口。

总结排查清单
接入 CF 后出问题，按这个顺序排查：




症状
检查项




重定向循环
源站是否无条件 HTTP→HTTPS 跳转？CF SSL 模式是否 Flexible？


522 超时
DNS A 记录是否指向真实 IP？是否有 SaaS fallback origin 没配？


429 限流
反代是否正确传递了真实用户 IP？realip 模块是否存在？


520 异常
源站是否返回了 CF 无法解析的响应？检查源站 error log


525 SSL 握手失败
SSL 模式 Full 但源站没有有效证书？改 Flexible 或装 Origin Cert
