【整理】获取用户真实 ip 地址的 nginx 相关配置

简介:

nginx 为实现反向代理的需求增加了一个 ngx_http_proxy_module 模块。其中 proxy_set_header 指令就是该模块需要读取的配置。  

      HTTP header 中的  Host   含义为所请求的目的主机名。当 nginx 作为反向代理使用,而后端真实 web 服务器设置有类似   防盗链功能   ,或者根据 HTTP header 中的 Host 字段来进行   路由     过滤   功能的话,若作为反向代理的 nginx 不重写请求头中的 Host 字段,将会导致请求失败。  

       HTTP header 中的    X_Forward_For    表示该条 http 请求是由谁发起的。如果反向代理服务器不重写该请求头的话,那么后端真实 web 服务器在处理时会认为所有的请求都来自反向代理服务器。如果后端 web 服务器有防攻击策略的话,那么反向代理服务器对应的 ip 地址就会被封掉。因此,在配置用作反向代理的 nginx 时,一般会增加以下两条配置修改 http 的请求头:  
?
1
2
proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;
      这里,$http_host 和 $remote_addr 都是 nginx 的导出变量,可以在配置文件中直接使用。如果 Host 没有出现在 HTTP header 中,则 $http_host 的值为空,而 $host 和 $http_host 同样表示请求头中的 Host 字段,但若 Host 字段不存在,则以实际处理的虚拟主机 server 的 server_name 替代。因此一般而言,会用 $host 代替 $http_host 变量(如下),从而避免 http 请求中丢失 Host 头部的情况下 Host 不被重写的失误。  
?
1
proxy_set_header Host $host;
      服务器集群之间的通信,是可以信任的。我们要做的就是在离用户最近的前端代理上,强制设定 X-Forward-For 的值,后端所有机器不作任何设置,直接信任并使用前端机器传递过来的 X-Forward-For 值即可。  
   
即在最前端的 Nginx 上设置:  
?
1
2
3
4
location  ~  ^ /static {
     proxy_pass  ....;
     proxy_set_header X-Forward-For $remote_addr ;
}
      记住,$remote_addr 是 nginx 的内置变量,代表了客户端真实(网络传输层)IP 。通过该设置,强行将 X-Forward-For 设置为客户端 ip ,使客户端无法通过本文所述方式“伪造 IP”。  
      当 nginx 作为反向代理服务器时,X-Forward-For 可以用于把发送者 ip 、代理机器 ip 都记录下来(用逗号分隔)。  

经过反向代理后,由于在客户端和 web 服务器之间增加了中间层,因此 web 服务器无法直接拿到客户端的 ip,在 web 服务器上通过 $remote_addr 变量拿到的将是反向代理服务器的 ip 地址
      当你使用了 nginx 反向代理后,在 web 端使用类似 request.getRemoteAddr() 的 API(本质上就是获取 $remote_addr),取得的实际上是 nginx 的地址,即 $remote_addr 变量中封装的是 nginx 的地址,当然是没法获得用户的真实 ip 的,然而 nginx 本身是可以获得用户的真实 ip 的,也就是说 nginx 使用 $remote_addr 变量可以获得用户的真实 ip ,如果我们想要在 web 端获得用户的真实 ip ,就必须在 nginx 这里作一个赋值操作,如下:  
?
1
proxy_set_header  X-real-ip $remote_addr;
      其中这个 X-real-ip 是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实 ip 就被放在 X-real-ip 这个变量里了,然后,在 web 端可以通过类似如下 API 获取客户端 ip:  
?
1
request.getAttribute( "X-real-ip" )

 X-real-ip 的用途是为了后端 web 服务器可以获取用户的真实 ip ,   那么还要    X-Forwarded-For 干啥?  
      追溯历史,这个 X-Forwarded-For 变量,是 squid 开发的,用于识别请求通过了哪些 HTTP 代理或负载平衡器,记录相应 IP 地址列表的非 rfc 标准,如果设置了 X-Forwarded-For ,那么每次经过 proxy 转发请求后都会有记录,格式就是  
?
1
client1, proxy1, proxy2, ...
      以逗号隔开各个地址。由于是非 rfc 标准,所以默认是没有的,需要强制添加。在默认情况下经过 proxy 转发的请求,在后端 web 服务器看来远程地址都是 proxy 的 ip 地址。也就是说在默认情况下我们使用 request.getAttribute("X-Forwarded-For") 获取不到用户的 ip ,如果我们想要通过这个变量获得用户的 ip ,我们需要自己在 nginx 添加如下配置:  
?
1
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      上述配置的意思是增加一个 $proxy_add_x_forwarded_for 到 X-Forwarded-For 里去,注意是增加,而不是覆盖。当然由于默认的 X-Forwarded-For 值是空的,所以我们总感觉 X-Forwarded-For 的值就等于 $proxy_add_x_forwarded_for 的值。  

      实际上,当你通过搭建不同 ip 的两台 nginx 构成多级代理时,并且都使用了这段配置,那你会发现在 web 服务器端通过类似 request.getAttribute("X-Forwarded-For") 的 API 获得的将会是客户端 ip 和第一台 nginx 的 ip 。  


试验:【以 http 方式通过 nginx 访问 cowboy】  

浏览器侧抓包  
 

cowboy 上抓包  
 
目录
相关文章
|
19天前
|
负载均衡 应用服务中间件 API
Nginx:location配置模块的用法(一)
Nginx:location配置模块的用法(一)
100 2
|
12天前
|
应用服务中间件 nginx Docker
本地通过域名访问虚拟机上nginx的服务、搭建域名访问环境一(反向代理配置)
这篇文章介绍了如何通过域名在本地访问虚拟机上的nginx服务,包括创建nginx容器、修改配置文件、修改本地host文件以及进行访问测试的详细步骤。文章提供了具体的Docker命令来创建并配置nginx容器,展示了配置文件的修改示例,说明了如何在本地系统的hosts文件中添加虚拟机IP和自定义域名,以及如何通过浏览器进行测试访问。
本地通过域名访问虚拟机上nginx的服务、搭建域名访问环境一(反向代理配置)
|
8天前
|
应用服务中间件 Linux nginx
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
|
9天前
|
Ubuntu 应用服务中间件 Linux
在Linux中,如何配置Web服务器(如Apache或Nginx)?
在Linux中,如何配置Web服务器(如Apache或Nginx)?
|
9天前
|
缓存 负载均衡 应用服务中间件
【揭秘】nginx代理配置全攻略:从零到精通,一文带你玩转高效网络代理的秘密武器!
【8月更文挑战第22天】nginx是一款高性能的HTTP与反向代理服务器,支持代理服务、负载均衡及缓存等功能,有助于提升网站响应速度和安全性。首先需确保已安装nginx,可通过包管理器进行安装。安装后启动并确认nginx运行状态。接着编辑配置文件(通常位于`/etc/nginx/nginx.conf`),设置代理转发规则,例如指定目标服务器地址和请求头信息。配置完成后测试有效性并重新加载nginx以应用更改。可以通过部署简易HTTP服务器验证代理功能是否正常工作。此外,还可以通过扩展配置文件实现更复杂的代理需求,如基于路径的代理和SSL加密等。
40 2
|
16天前
|
Web App开发 应用服务中间件 网络安全
如何在 Apache 和 Nginx 上配置 OCSP Stapling
如何在 Apache 和 Nginx 上配置 OCSP Stapling
34 8
|
16天前
|
jenkins 应用服务中间件 持续交付
如何配置 Nginx 作为 Jenkins 的反向代理并启用 SSL 加密
如何配置 Nginx 作为 Jenkins 的反向代理并启用 SSL 加密
36 8
|
10天前
|
缓存 负载均衡 应用服务中间件
如何配置 NGINX 反向代理
【8月更文挑战第21天】
43 0
如何配置 NGINX 反向代理
|
16天前
|
存储 Ubuntu 应用服务中间件
如何在 Ubuntu VPS 上配置 Nginx 的日志记录和日志轮转
如何在 Ubuntu VPS 上配置 Nginx 的日志记录和日志轮转
13 4
|
15天前
|
负载均衡 应用服务中间件 网络安全
NGINX配置详解
NGINX配置详解