cdn 的 x-forwarded-for 不可靠,限流必须基于可信 cdn 头(如 x-real-ip/cf-connecting-ip),且需 nginx 配置 set_real_ip_from 与 real_ip_recursive,并在 python 应用中统一提取逻辑、对齐日志与限流 ip。

CDN 的 X-Forwarded-For 不可靠,别直接拿它做限流依据
真实 IP 在经过 CDN 后基本就丢了,X-Forwarded-For 可被客户端伪造,很多 CDN(比如 Cloudflare)会把真实源 IP 放在 Cf-Connecting-IP 或 X-Real-IP 里,但前提是你的服务器反向代理(如 Nginx)配置了信任 CDN 的出口 IP 段,否则这些头会被忽略。
- 用 Nginx 时,必须在
set_real_ip_from中显式加入 CDN 提供的可信 IP 段(例如 Cloudflare 的173.245.48.0/20等) - Django / Flask 应用里,别用
request.remote_addr——它返回的是 Nginx 的地址;要依赖request.headers.get('X-Real-IP')或类似字段,且确保中间件已启用真实 IP 解析 - 没配
real_ip_recursive on时,多层代理下X-Forwarded-For最左或最右的 IP 可能是上一跳 CDN,不是用户
Python 限流器(如 slowapi 或 limits)默认不认 CDN 头
这些库默认基于 request.client.host 或 request.environ['REMOTE_ADDR'] 做 key,结果所有流量都算成同一个 IP(即 CDN 回源 IP),完全失效。
- 在 FastAPI 中用
slowapi,得重写get_remote_address函数,从request.headers.get('X-Real-IP')取值,并加空值 fallback - Flask +
limits需传入自定义key_func,不能依赖内置get_ipaddr - 如果 CDN 开启了“IP 透传”但用了非标准 header(比如
X-Originating-IP),你的 key 函数就得适配这个字段名
CDN 自身防护和 Python 后端防护是两层事,别互相替代
Cloudflare 的 WAF 或阿里云 DDoS 高防能挡 SYN Flood、CC 攻击前几层,但绕过 CDN 直连源站的请求(比如通过泄露的源站 IP)、或构造合法但高频的 API 调用(如爆破登录接口),它们管不了——这部分必须由 Python 应用自己控速、验签、熔断。
- CDN 的“JS 挑战”对自动化脚本几乎无效,真要防爬,得在 Python 层加行为分析(比如请求间隔熵、User-Agent 频次分布)
- 后端限流粒度要比 CDN 更细:CDN 通常只能按 IP 或域名限,而 Python 可按
user_id、api_key、甚至请求 body 的某个字段限 - 别关掉 CDN 的速率限制指望 Python 全扛——高并发下 Python 进程早被打满,根本来不及执行限流逻辑
nginx + python 链路中,日志 IP 和限流 IP 必须一致
如果 Nginx 日志里记录的是 $remote_addr(CDN IP),而 Python 限流用的是 X-Real-IP,排查攻击时就对不上号:你看到日志里全是 104.28.x.x,但限流器在拦 203.124.x.x,根本没法关联分析。
立即学习“Python免费学习笔记(深入)”;
- Nginx access log 格式里,把
$http_x_real_ip或$http_cf_connecting_ip加进去,和 Python 限流用的字段严格对齐 - 加个简单校验:Python 启动时打印出收到的典型请求头,确认
X-Real-IP确实存在且格式合法(避免空格、逗号分隔等脏数据) - 有些 CDN(如腾讯云 CDN)在 HTTPS 回源时可能不传某些头,得进控制台确认“回源请求头”开关是否打开










