Nginx 正确接收 PROXY Protocol 透传客户端信息需三步:一、listen 后加 proxy_protocol 开启解析;二、用 set_real_ip_from 指定可信代理网段;三、HTTP 块配 real_ip_header proxy_protocol,日志与转发用 $proxy_protocol_addr。

要在 Nginx 中正确接收负载均衡器(如 AWS NLB、阿里云 SLB、HAProxy)通过 PROXY Protocol 透传的原始客户端信息,核心是三步:开启协议解析、声明可信来源、启用地址替换。缺一不可,否则 $remote_addr 仍显示代理 IP。
必须在 listen 指令后加 proxy_protocol
这是整个机制的开关。Nginx 只有在监听端口明确启用该参数,才会尝试读取连接建立后的第一个数据包是否为合法 PROXY 头(v1 文本格式或 v2 二进制格式)。不加此参数,后续所有配置都无效。
- HTTP 块中写法:
listen 80 proxy_protocol;或listen 443 ssl http2 proxy_protocol; - Stream 块中写法:
listen 3306 proxy_protocol;(适用于 MySQL、Redis 等 TCP 服务) - 注意:同一端口不能混用 —— 既收 PROXY 又收普通 TCP 流量会导致连接被直接拒绝
用 set_real_ip_from 明确信任代理网段
PROXY 头可被伪造,Nginx 默认不信任任何来源。你必须用 set_real_ip_from 显式列出负载均衡器出口 IP 或 CIDR 段,只有来自这些地址的连接,才允许解析并覆盖 $remote_addr。
- 示例(AWS NLB 私有子网):
set_real_ip_from 10.100.20.0/24; - 支持多行,可同时写多个段:
set_real_ip_from 192.168.5.10;、set_real_ip_from 2001:db8::/32; - 若负载均衡器与 Nginx 部署在同一台机器(如本地 HAProxy),可用
set_real_ip_from unix:
确保 real_ip_header 和变量使用一致
在 HTTP 块中,需配合 real_ip_header proxy_protocol; 告诉 Nginx 从 PROXY 头提取真实地址;在 Stream 块中则无需此指令,因 proxy_protocol 已隐含该行为。
- 日志中记录真实 IP:
log_format main '$proxy_protocol_addr - ...'; - 转发给上游时透传:
proxy_set_header X-Real-IP $proxy_protocol_addr; - 限流/黑白名单应基于
$realip_remote_addr(stream)或$proxy_protocol_addr(http),而非$remote_addr
只要上游 LB 正确发送了 PROXY 头(例如 HAProxy backend 配置 send-proxy,NLB 开启 Proxy Protocol v2),且 Nginx 的 listen、set_real_ip_from、变量引用三者匹配,就能稳定拿到源 IP、端口等四元组信息。不复杂但容易忽略细节。


















