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

使用Nginx获取客户端真实IP(real_ip_header)

使用 Nginx 获取客户端真实 IP

在使用 Nginx 作为反向代理或负载均衡器时,我们常常需要获取客户端的真实 IP 地址。然而,默认情况下,Nginx 的 $remote_addr 变量记录的 IP 地址可能是上游代理或负载均衡器的 IP,而非实际客户端的 IP。为了确保我们能够正确获取和记录客户端的真实 IP,本文将介绍如何配置 Nginx,并进行调试。

一、配置 Nginx 获取客户端真实 IP

1、基本配置说明

首先,我们需要确保 Nginx 能够正确解析来自上游代理或负载均衡器的 X-Forwarded-For 头部信息。通过配置 real_ip_headerset_real_ip_from,Nginx 可以将 $remote_addr 更新为客户端的真实 IP。

示例配置

http {include       mime.types;default_type  application/octet-stream;server_tokens off;# 设置真实 IP 的头部信息real_ip_header X-Forwarded-For;# 指定可信任的上游代理 IP 范围,这里以 172.0.0.0/8 为例(就是你负载均衡的ip网段)set_real_ip_from 172.0.0.0/8;# 其他配置...
}
  • real_ip_header X-Forwarded-For;:指定从哪个头部获取客户端的真实 IP 地址。常见的头部包括 X-Forwarded-ForX-Real-IP 等。
  • set_real_ip_from 172.0.0.0/8;:指定哪些 IP 地址段的请求可以被信任。如果请求来自这些地址段,那么 Nginx 会根据 real_ip_header 的配置更新 $remote_addr

在 Nginx 中,set_real_ip_from 指令用于定义哪些 IP 地址或 IP 地址段是被信任的。根据请求来源 IP 地址是否在 set_real_ip_from 指定的范围内,Nginx 的行为会有所不同,具体区别如下:

2、set_real_ip_from详解

1. 请求来源 IP 在 set_real_ip_from 范围内

如果请求来源的 IP 地址在 set_real_ip_from 指定的范围内,Nginx 会信任该请求,并使用 real_ip_header 指定的头部(如 X-Forwarded-For)中的值作为客户端的真实 IP 地址。

行为:
  • Nginx 使用 X-Forwarded-For 头中的第一个(最左边的)IP 地址作为 $remote_addr(即客户端的真实 IP 地址)。
  • 这种情况通常出现在负载均衡器或反向代理服务器前端,它们会添加 X-Forwarded-For 头来指示真实的客户端 IP。
2. 请求来源 IP 不在 set_real_ip_from 范围内

如果请求来源的 IP 地址不在 set_real_ip_from 指定的范围内,Nginx 不会信任这个请求中的 X-Forwarded-For 头部中的 IP 地址。

行为:
  • Nginx 直接使用请求来源的 IP 地址(即 $remote_addr)作为客户端的 IP 地址。
  • 这意味着 Nginx 会将负载均衡器或代理服务器的 IP 地址视为客户端的 IP,而不会考虑 X-Forwarded-For 头中的值。
场景分析:
  • 在范围内: 如果你有一个负载均衡器,所有请求都会先经过它再到达 Nginx。负载均衡器会在请求头中加入 X-Forwarded-For 以记录客户端的真实 IP。如果你将负载均衡器的 IP 地址配置在 set_real_ip_from 中,Nginx 会读取并信任 X-Forwarded-For 中的客户端真实 IP。

  • 不在范围内: 如果请求不是通过你信任的负载均衡器发来的(可能是直接访问 Nginx,或者来自不可信的代理服务器),Nginx 会认为这个请求中的 X-Forwarded-For 不可信,于是使用实际请求来源 IP(负载均衡器或代理的 IP 地址)作为客户端 IP。

3、log_format 配置(参考)

配置日志格式时,可以直接使用 $remote_addr 变量。Nginx 在解析 real_ip_header 后,会自动将 $remote_addr 替换为解析后的真实 IP 地址。

日志格式配置

log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
  • $remote_addr:在配置了 real_ip_header 之后,这个变量将代表客户端的真实 IP 地址。

二、调试与测试

为了确保配置正确,我们可以使用一个简单的调试日志来测试 X-Forwarded-For 头部的内容。

  1. 添加调试日志

    可以通过下面的配置,将 X-Forwarded-For 头部记录到一个专门的调试日志文件中。

    调试日志配置

    log_format debug '$http_x_forwarded_for';
    access_log /path/to/log/debug.log debug;
    

    通过这一配置,你可以在调试过程中直接查看 X-Forwarded-For 头部的内容,以确认它是否包含客户端的真实 IP 地址。

  2. 检查调试日志

    配置完成后,重启 Nginx,并通过访问应用生成一些日志。然后,查看调试日志 /path/to/log/debug.log 以验证 X-Forwarded-For 头部的值。

    tail -f /path/to/log/debug.log
    

    如果 X-Forwarded-For 头部中包含了客户端的真实 IP 地址,那么说明配置正确,Nginx 能够正确获取并记录客户端的真实 IP。

三、Lua 中使用客户端真实 IP(参考)

在实际应用中,如果你使用了 OpenResty 或 Nginx 的 Lua 模块,可以在 Lua 代码中使用 ngx.var.remote_addr 来获取解析后的真实 IP。

示例代码

access_by_lua "
local uid = ngx.var.cookie_bb_id
if not uid thenuid = ngx.md5(ngx.now() .. ngx.var.remote_addr .. ngx.var.http_user_agent)ngx.header['Set-Cookie'] = 'bb_id=' .. uid .. '; path=/; Expires=' .. ngx.cookie_time(ngx.time() + 3650*86400) .. '; Secure; SameSite=None'
end
";

在上面的 Lua 代码中,ngx.var.remote_addr 会获取到解析后的客户端真实 IP。这在用户跟踪或日志记录中非常有用。

四、总结

通过正确配置 real_ip_headerset_real_ip_from,我们可以确保 Nginx 能够通过 $remote_addr 获取并记录客户端的真实 IP 地址。在配置完成后,通过调试日志可以验证配置是否生效。如果你在 Lua 中需要获取真实 IP,可以直接使用 ngx.var.remote_addr

这篇博客介绍了如何配置、调试并验证 Nginx 的真实 IP 获取配置,希望能对你有所帮助。如果你在实际操作中遇到其他问题,欢迎进一步探讨!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 第三章 数组 课后训练(4)
  • mysql学习教程,从入门到精通,MySQL创建数据库教程(5)
  • C++ | Leetcode C++题解之第391题完美矩形
  • 【drools】kie:官方仓库clone 遇到问题解决
  • Select模型
  • VMware Workstation v17.6 中文注册精简版
  • 使用mysqldump命令时提示ERROR 1064 (42000)
  • LeetCode 2860.让所有学生保持开心的分组方法数:排序+遍历
  • 分享——有趣的题目
  • 一文教你学会java代码审计
  • 网络编程学习:TCP/IP协议
  • 数据库系统 第35节 数据库加密
  • HarmonyOS开发实战( Beta5版)Swiper高性能开发指南
  • 传统CV算法——图像基本操作与形态学操作
  • 【机器学习】.fit_transform()跟.transform()的区别
  • Android优雅地处理按钮重复点击
  • CEF与代理
  • CentOS 7 修改主机名
  • Create React App 使用
  • js 实现textarea输入字数提示
  • JS函数式编程 数组部分风格 ES6版
  • Just for fun——迅速写完快速排序
  • Linux中的硬链接与软链接
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • tweak 支持第三方库
  • 对JS继承的一点思考
  • 服务器之间,相同帐号,实现免密钥登录
  • 规范化安全开发 KOA 手脚架
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 设计模式(12)迭代器模式(讲解+应用)
  • 使用API自动生成工具优化前端工作流
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 听说你叫Java(二)–Servlet请求
  • 学习ES6 变量的解构赋值
  • 怎么将电脑中的声音录制成WAV格式
  • 积累各种好的链接
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • ​水经微图Web1.5.0版即将上线
  • ​一些不规范的GTID使用场景
  • #android不同版本废弃api,新api。
  • #define 用法
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (20050108)又读《平凡的世界》
  • (java)关于Thread的挂起和恢复
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (原)Matlab的svmtrain和svmclassify
  • .NET Micro Framework 4.2 beta 源码探析
  • .net 获取某一天 在当月是 第几周 函数
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .NET程序员迈向卓越的必由之路
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc