
后端拿到的永远是 127.0.0.1 或 Nginx 本机 IP,不是因为代码写错了,而是 Nginx 根本没把真实 IP 传过来 —— 默认配置下它不会透传任何客户端信息。
nginx 必须显式配置 proxy_set_header 才能透传真实 IP
只靠后端读 X-Forwarded-For 是没用的,前提是 Nginx 得先把这个头塞进去。常见错误是只加了一行、漏了关键变量、或写在了错误作用域。
-
proxy_set_header X-Real-IP $remote_addr;—— 单层代理够用,但不兼容多级代理(比如 CDN + Nginx) -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 必须用这个,不是$remote_addr;$proxy_add_x_forwarded_for会自动拼接原始值和当前$remote_addr,避免覆盖 - 这两行必须放在
location块里,且在proxy_pass之前;如果写在http或server级但没匹配到实际转发路径,等于没写 - 别漏掉
proxy_set_header Host $host;,否则后端可能解析错域名或跳转出错
Python 后端解析 X-Forwarded-For 时容易误取最后一个 IP
很多示例代码直接取 .split(',')[-1].strip(),这在多级代理下会拿到 Nginx 自己的 IP,而不是用户真实 IP。
-
X-Forwarded-For格式是client_ip, proxy1_ip, proxy2_ip,最左边才是真实客户端 IP - 正确做法是
.split(',')[0].strip(),但前提是信任所有代理链 —— 所以必须配合 Nginx 的set_real_ip_from使用 - 如果用了 CDN 或 SLB(如阿里云 CLB),它们默认加
X-Forwarded-For,此时你的 Nginx 就成了第二跳代理,$proxy_add_x_forwarded_for会把它自己的 IP 追加到已有列表末尾,所以第一个仍是用户 IP - 不建议 fallback 到
request.remote_addr,它返回的是 TCP 连接发起方(即 Nginx),不是用户
set_real_ip_from 和 real_ip_header 是安全前提
光靠后端解析请求头不安全 —— 攻击者可伪造 X-Forwarded-For。Nginx 需要主动“信任并替换”远程地址,才能让 $remote_addr 变成真实 IP,后续日志、限流、白名单才可靠。
立即学习“Python免费学习笔记(深入)”;
- 在
http或server块中加:set_real_ip_from 127.0.0.1;(如果你的 Nginx 只接收本地流量)或具体可信代理网段,**绝不能写0.0.0.0/0** - 指定源字段:
real_ip_header X-Forwarded-For; - 开启递归解析:
real_ip_recursive on;—— 这样 Nginx 会从右往左剔除已知可信代理 IP,直到剩下一个不可信的,即用户真实 IP - 配完后,
$remote_addr就是真实 IP,access_log里也能直接用$remote_addr记录,不用再解析头
真正难的不是写对某一行配置,而是确认整个链路中每个环节(CDN / SLB / Nginx / 后端)各自加了什么头、删了什么头、信了哪些 IP。只要中间有一环没对齐,X-Forwarded-For 就会变成一串不可信的逗号分隔 IP,后端再怎么 split 也救不回来。


















