bigywater.tech
Flask · 135

信任代理头配置

ProxyFix 的 x_for 到底该写几?nginx 的 X-Forwarded-For 用覆盖还是追加?直接取 XFF 第一个元素行不行?这篇用一个写了假 X-Forwarded-For 的请求,把五种配置下 Flask 认定的客户端地址逐个对照(防御向,只验证配置的效果)。

x_for
ProxyFix 信任的代理层数,从右往左数,必须等于实际的代理层数
203.0.113.9
客户端自己写的假地址,在多信任一层或直连时被 Flask 当真
$remote_addr
nginx 覆盖 X-Forwarded-For 的写法,丢弃客户端写的内容

五种配置的对照

实测 · 本机执行输出
  [A] nginx 用 $remote_addr 覆盖 XFF,ProxyFix(x_for=1)
      服务端收到的 XFF 头 = '127.0.0.1'
      request.remote_addr = 127.0.0.1 | access_route = ['127.0.0.1'] | 取第一个元素 = 127.0.0.1
  [B] nginx 用 $proxy_add_x_forwarded_for 追加,ProxyFix(x_for=1)
      服务端收到的 XFF 头 = '203.0.113.9, 127.0.0.1'
      request.remote_addr = 127.0.0.1 | access_route = ['203.0.113.9', '127.0.0.1'] | 取第一个元素 = 203.0.113.9
  [C] nginx 追加,但 ProxyFix(x_for=2)(多信任了一层)
      服务端收到的 XFF 头 = '203.0.113.9, 127.0.0.1'
      request.remote_addr = 203.0.113.9 | access_route = ['203.0.113.9', '127.0.0.1'] | 取第一个元素 = 203.0.113.9
  [D] nginx 追加,没有 ProxyFix,取 XFF 第一个元素(常见的写法)
      服务端收到的 XFF 头 = '203.0.113.9, 127.0.0.1'
      request.remote_addr = 127.0.0.1 | access_route = ['203.0.113.9', '127.0.0.1'] | 取第一个元素 = 203.0.113.9
  [E] nginx 覆盖,没有 ProxyFix(只看 remote_addr)
      服务端收到的 XFF 头 = '127.0.0.1'
      request.remote_addr = 127.0.0.1 | access_route = ['127.0.0.1'] | 取第一个元素 = 127.0.0.1

上一篇:HTTPS 与反向代理;下一篇:Flask 同步请求模型。

客户端、nginx、gunicorn 都在本机,真实客户端地址与代理看到的地址都是 127.0.0.1,所以用请求里写的假地址 203.0.113.9 来区分「被信任」与「没被信任」的取值。

直连时的风险

实测 · 本机执行输出
  直连(没有 nginx),ProxyFix(x_for=1),请求头 XFF = 203.0.113.9 → remote_addr = 203.0.113.9

这一部分是第一个实验的补充:没有 nginx,直接连 gunicorn。

分步演示

信任代理头配置
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。nginx 1.31.6(自己的配置、非默认端口)、gunicorn(--forwarded-allow-ips 不信任回环)
    • 没有验证:两层及以上代理(CDN 加 nginx)的真实链路、Forwarded 标准头(RFC 7239)与 X-Real-IP、云负载均衡器的 XFF 追加行为、IPv6 地址、第 129 篇限流 key 在 ProxyFix 之后的实际取值
    京ICP备2026067502号-1京公网安备11010502063487号