当前位置: 首页 > article >正文

用 NGINX 还原真实客户端 IP ngx_mail_realip_module

一、模块作用与使用前提

  • 作用:解析 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;}
    }
    

三、工作流程

  1. TCP 握手后,NGINX 在 listen … proxy_protocol 模式下,先读取一行 PROXY 协议头(如 PROXY TCP4 203.0.113.5 198.51.100.10 54321 110)。
  2. 信任检查:检查源连接的上游代理 IP(此例中为 198.51.100.10)是否在 set_real_ip_from 列表中;
  3. 替换变量:如果信任,则将内部变量 $remote_addr 设置为 203.0.113.5$remote_port 设置为 54321
  4. 继续后续流程:邮件协议解析、认证、转发、日志等都以新地址为准。

四、常见场景与最佳实践

  1. 与 L4 负载均衡器配合

    • 在 NGINX 前置 F5、HAProxy、云厂商内网 LB 等配置 PROXY 协议;
    • 后端 NGINX 用 listen … proxy_protocol + set_real_ip_from lb_ip 恢复客户端 IP。
  2. 保证安全性

    • 严格控制 set_real_ip_from 范围,只信任可信网络或单一 LB 实例,避免客户端伪造 PROXY 头。
    • 若中间有多级代理,可列出所有跳数的 IP。
  3. IPv6 环境支持

    • 既可写单个地址 2001:db8::1,也可写网段 2001:db8::/48
  4. UNIX 域套接字

    • 当邮件代理链路通过 unix:/var/run/nginx.sock proxy_protocol; 时,加入 set_real_ip_from unix:;

五、排障与验证

  1. 日志验证

    • 打开 mail_logerror_log,在转发到后端前后分别记录 $remote_addr,确认地址已被替换。
  2. 抓包检查

    • tcpdump 抓取 110/143/25 端口,观察首行是否有 PROXY …
  3. 拒绝伪造

    • 若要测试拒绝功能,可尝试从非信任 IP 连入,NGINX 应忽略 PROXY 头并仅记录真实连接源。

六、小结

通过简单的 listen … proxy_protocolset_real_ip_from 配置,ngx_mail_realip_module 就能让 NGINX 在邮件代理中完美恢复客户端真实 IP/端口,无缝集成到后续的认证、日志、限流、反垃圾等模块中,为高可用、高安全的邮件网关保驾护航。

http://www.lryc.cn/news/2391857.html

相关文章:

  • Mysql中索引B+树、最左前缀匹配
  • Python训练营打卡 Day38
  • 【机器学习基础】机器学习入门核心算法:K均值(K-Means)
  • Python Day37
  • RabbitMQ集群与负载均衡实战指南
  • 怎么开机自动启动vscode项目
  • Unity 中 Update、FixedUpdate 和 LateUpdate 的区别及使用场景
  • linux安装ffmpeg7.0.2全过程
  • Java中的设计模式实战:单例、工厂、策略模式的最佳实践
  • DexGarmentLab 论文翻译
  • Elasticsearch性能优化全解析
  • 2025.05.28【Parallel】Parallel绘图:拟时序分析专用图
  • tc3975开发板上有ft2232这块的电路,我想知道这个开发板有哪些升级方式,重点关注是怎样通过ft2232实现的烧录升级的
  • 自动驾驶与智能交通:构建未来出行的智能引擎
  • Kotlin Multiplatform与Flutter深度对比:跨平台开发方案的实战选择
  • ELectron 中 BrowserView 如何进行实时定位和尺寸调整
  • 深兰科技董事长陈海波率队考察南京,加速AI大模型区域落地应用
  • 《深度关系-从建立关系到彼此信任》
  • IT选型指南:电信行业需要怎样的服务器?
  • 【ConvLSTM第二期】模拟视频帧的时序建模(Python代码实现)
  • [VMM]分享一个用SystemC编写的页表管理程序
  • 将docker数据目录迁移到 home目录下
  • 【论文解读】DETR: 用Transformer实现真正的End2End目标检测
  • Pytest 是什么
  • ElasticSearch简介及常用操作指南
  • 缓存常见问题:缓存穿透、缓存雪崩以及缓存击穿
  • 纤维组织效应偏斜如何影响您的高速设计
  • 【深度学习】sglang 的部署参数详解
  • SDL2常用函数:SDL_RendererSDL_CreateRendererSDL_RenderCopySDL_RenderPresent
  • [git]忽略.gitignore文件