一、模块作用与使用前提
-
作用:解析 TCP 会话第一行的 PROXY 协议头,将客户端 IP/端口写回 NGINX 的内部变量,使后续
ngx_mail_proxy_module
、认证模块、日志模块都能获取真实来源。 -
前提:监听指令中必须启用
proxy_protocol
,例如:listen 110 proxy_protocol; # POP3 listen 143 proxy_protocol; # IMAP listen 25 proxy_protocol; # SMTP
二、核心指令:set_real_ip_from
set_real_ip_from address | CIDR | unix:;
-
address / CIDR:信任的上游代理 IP 或网段,只有来自这些地址的连接才会使用 PROXY 头信息。
-
unix::表示所有 UNIX 域套接字都被信任(仅当前端通过
listen unix:... proxy_protocol
时生效)。 -
示例:
mail { server { listen 110 proxy_protocol; listen 143 proxy_protocol; listen 25 proxy_protocol; # 仅信任前端 LB 的 IP 段 set_real_ip_from 192.168.1.0/24; set_real_ip_from 10.0.0.5; set_real_ip_from 2001:db8::/32; } }
三、工作流程
- TCP 握手后,NGINX 在
listen … proxy_protocol
模式下,先读取一行 PROXY 协议头(如PROXY TCP4 203.0.113.5 198.51.100.10 54321 110
)。 - 信任检查:检查源连接的上游代理 IP(此例中为
198.51.100.10
)是否在set_real_ip_from
列表中; - 替换变量:如果信任,则将内部变量
$remote_addr
设置为203.0.113.5
,$remote_port
设置为54321
; - 继续后续流程:邮件协议解析、认证、转发、日志等都以新地址为准。
四、常见场景与最佳实践
-
与 L4 负载均衡器配合
- 在 NGINX 前置 F5、HAProxy、云厂商内网 LB 等配置 PROXY 协议;
- 后端 NGINX 用
listen … proxy_protocol
+set_real_ip_from lb_ip
恢复客户端 IP。
-
保证安全性
- 严格控制
set_real_ip_from
范围,只信任可信网络或单一 LB 实例,避免客户端伪造 PROXY 头。 - 若中间有多级代理,可列出所有跳数的 IP。
- 严格控制
-
IPv6 环境支持
- 既可写单个地址
2001:db8::1
,也可写网段2001:db8::/48
。
- 既可写单个地址
-
UNIX 域套接字
- 当邮件代理链路通过
unix:/var/run/nginx.sock proxy_protocol;
时,加入set_real_ip_from unix:;
。
- 当邮件代理链路通过
五、排障与验证
-
日志验证
- 打开
mail_log
/error_log
,在转发到后端前后分别记录$remote_addr
,确认地址已被替换。
- 打开
-
抓包检查
- 用
tcpdump
抓取 110/143/25 端口,观察首行是否有PROXY …
。
- 用
-
拒绝伪造
- 若要测试拒绝功能,可尝试从非信任 IP 连入,NGINX 应忽略 PROXY 头并仅记录真实连接源。
六、小结
通过简单的 listen … proxy_protocol
与 set_real_ip_from
配置,ngx_mail_realip_module
就能让 NGINX 在邮件代理中完美恢复客户端真实 IP/端口,无缝集成到后续的认证、日志、限流、反垃圾等模块中,为高可用、高安全的邮件网关保驾护航。