必须启用proxyfix中间件并正确配置trusted_proxies参数,否则request.remote_addr始终为代理ip;nginx需设置proxy_set_header x-forwarded-for $remote_addr;禁用未经校验的x-forwarded-for直接取值。

Flask里request.remote_addr总是127.0.0.1或10.x.x.x
这是因为Nginx反向代理把真实客户端IP藏在了HTTP头里,Flask默认只读TCP连接的远端地址——而那个地址是Nginx本机。不配置信任代理,request.remote_addr永远拿不到真实IP。
实操建议:
- 必须启用
ProxyFix中间件,并明确指定可信代理IP段(比如Nginx所在服务器的内网地址) - 不能只写
app.wsgi_app = ProxyFix(app.wsgi_app),缺trusted_hosts或trusted_proxies参数照样无效 - 如果Nginx和Flask部署在同一台机器,
trusted_proxies设为['127.0.0.1'];跨机器则填Nginx出口IP,例如['10.0.1.5'] - 确保Nginx配置中已设置
proxy_set_header X-Forwarded-For $remote_addr;(注意不是$proxy_add_x_forwarded_for,后者会拼接多层,容易被伪造)
为什么request.headers.get('X-Forwarded-For')有时取不到或不准
X-Forwarded-For本身可被客户端随意伪造,Flask不校验来源就直接用,等于开了个IP欺骗后门。而且它可能是逗号分隔的字符串(如"203.0.113.195, 198.51.100.1"),最左才是原始客户端IP——但前提是前面每一跳都可信。
实操建议:
- 绝不要绕过
ProxyFix直接解析X-Forwarded-For - 如果必须手动取,先确认请求确实来自可信代理(比如检查
request.remote_addr是否在你配置的trusted_proxies列表里) - 用
request.headers.get('X-Forwarded-For', '').split(',')[0].strip()取第一个IP,但仅限调试或日志,不用于鉴权、限流等安全场景
Flask 2.2+ 的ProxyFix参数变化:trusted_hosts vs trusted_proxies
旧版本用trusted_hosts,新版本改推trusted_proxies,二者语义不同:trusted_hosts匹配Host头,trusted_proxies才真正控制哪些IP发来的X-Forwarded-*头可信。用错就白配。
实操建议:
- Flask ≥ 2.2:用
trusted_proxies,支持IP地址、CIDR网段(如['127.0.0.1', '10.0.0.0/8']) - Flask trusted_hosts,但实际效果弱,建议升级
- 示例代码:
from werkzeug.middleware.proxy_fix import ProxyFix<br>app.wsgi_app = ProxyFix(<br> app.wsgi_app,<br> trusted_proxies=['127.0.0.1'],<br> x_for=1,<br> x_proto=1<br>)
Nginx配置漏掉proxy_set_header X-Real-IP会怎样
X-Real-IP不是必需头,ProxyFix也不读它。但有些老代码或监控工具会依赖这个字段,如果Nginx没透传,它们就全拿到127.0.0.1。更麻烦的是,如果Nginx用了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;,而上游又没清空原始头,可能造成IP链污染。
实操建议:
- 推荐Nginx配置三连:
proxy_set_header X-Forwarded-For $remote_addr;<br>proxy_set_header X-Forwarded-Proto $scheme;<br>proxy_set_header X-Real-IP $remote_addr;
- 避免用
$proxy_add_x_forwarded_for——除非你确定前端只有Nginx一层代理且完全可控 - 上线前用
curl -H "X-Forwarded-For: 1.2.3.4" http://yoursite/测试,看Flask是否仍返回真实IP(应忽略该伪造头)
真实环境里,IP不准往往不是单一配置问题,而是Nginx头设置、Flask中间件参数、代理层级、甚至CDN是否透传共同作用的结果。最容易被忽略的,是以为配了ProxyFix就万事大吉,却没验证trusted_proxies是否真匹配Nginx的出站IP。










