项目中Nginx多级代理是如何获取客户端的真实IP地址

 更新时间:2022年05月27日 09:57:26   作者:morris131  
最近在研究nginx中如何获取真实客户端IP的方法,所以下面这篇文章主要给大家介绍了关于项目中Nginx多级代理是如何获取客户端的真实IP地址的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

多级代理中获取客户端真实IP

日志的格式

nginx中常用日志格式配置如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
access_log  /var/log/nginx/access.log  main;

其中的main为日志格式的别名,在使用的时候直接使用别名即可。

例子:

10.0.3.137 - - [09/Oct/2020:09:41:02 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" "10.1.9.98"
变量含义例子
$remote_addr客户端的ip地址(直连的IP,代理服务器,显示代理服务ip)10.0.3.137
$remote_user用于记录远程客户端的用户名称-
$time_local用于记录访问时间和时区08/Oct/2020:02:37:25 -0400
$request用于记录请求的url、请求方法,协议的版本GET / HTTP/1.1
$status响应状态码200
$body_bytes_sent给客户端发送的文件主体内容字节0
$http_referer可以记录用户是从哪个链接访问过来的-
$http_user_agent用户所使用的代理(一般为浏览器)Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
$http_x_forwarded_for可以记录客户端IP和所有经过的代理服务器的IP10.1.9.98

日积月累下,日志文件会越来越大,日志文件太大严重影响服务器效率,所以需要定时对日志文件进行切割。

由于这里是演示,所以切割方式是按分钟来切割,正常生产上使用一般是按天来进行分割:

#!/bin/bash
#日志文件存放目录
LOGS_PATH=/usr/local/nginx/logs
#备份文件名称
YESTERDAY=$(date -d "yesterday" +%Y%m%d%H%M)
#重命名日志文件
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
mv ${LOGS_PATH}/error.log ${LOGS_PATH}/error_${YESTERDAY}.log
## 向 Nginx 主进程发送 USR1 信号。USR1 信号是重新打开日志文件
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)

然后添加定时任务:

# crontab -e
*/1 * * * * /bin/bash /usr/local/nginx/logs/nginx_log.sh

获取客户端真实IP

服务器资源分配情况如下:

  • 10.1.9.98:充当客户端
  • 10.0.3.137:一级代理
  • 10.0.4.105:二级代理
  • 10.0.4.129:三级代理
  • 10.0.4.120:服务器端,为了方便,这里使用一个nginx充当服务器端,正常情况下一般是一个web服务器,如tomcat。

各个服务初始配置如下:

10.0.3.137的配置:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format main '$remote_addr - $http_x_forwarded_for - $http_x_real_ip';
    access_log  logs/access.log  main;
    server {
        listen  80;

        location / {
                # proxy_set_header X-Real-IP $remote_addr;
                # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://10.0.4.105;
        }
    }

}

10.0.4.105的配置,其他配置与10.0.3.137的一致:

...
        location / {
                # proxy_set_header X-Real-IP $remote_addr;
                # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://10.0.4.129;
        }
...

10.0.4.129的配置,其他配置与10.0.3.137的一致:

...
        location / {
                # proxy_set_header X-Real-IP $remote_addr;
                # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://10.0.4.120;
        }
...

10.0.4.120的配置,其他配置与10.0.3.137的一致

...
        location / {
                root html;
                index index.html;
        }
...

下面的记录为access.log中打印的结果:

操作10.0.3.13710.0.4.10510.0.4.12910.0.4.120
10.1.9.98访问curl http://10.0.3.13710.1.9.98 - - - -10.0.3.137 - - - -10.0.4.105 - - - -10.0.4.129 - - - -
10.0.3.137开启X-Forwarded-For10.1.9.98 - - - -10.0.3.137 - 10.1.9.98 - -10.0.4.105 - 10.1.9.98 - -10.0.4.129 - 10.1.9.98 - -
10.0.4.105开启X-Forwarded-For10.1.9.98 - - - -10.0.3.137 - 10.1.9.98 - -10.0.4.105 - 10.1.9.98, 10.0.3.137 - -10.0.4.129 - 10.1.9.98, 10.0.3.137 - -
10.0.4.129开启X-Forwarded-For10.1.9.98 - - - -10.0.3.137 - 10.1.9.98 - -10.0.4.105 - 10.1.9.98, 10.0.3.137 - -10.0.4.129 - 10.1.9.98, 10.0.3.137, 10.0.4.105 - -
10.1.9.98伪造头部访问curl http://10.0.3.137 -H ‘X-Forwarded-For: 1.1.1.1’10.1.9.98 - 1.1.1.1 - -10.0.3.137 - 1.1.1.1, 10.1.9.98 - -10.0.4.105 - 1.1.1.1, 10.1.9.98, 10.0.3.137 - -10.0.4.129 - 1.1.1.1, 10.1.9.98, 10.0.3.137, 10.0.4.105 - -
10.0.3.137开启X-Real-IP10.1.9.98 - - - -10.0.3.137 - 10.1.9.98 - 10.1.9.9810.0.4.105 - 10.1.9.98, 10.0.3.137 - 10.1.9.9810.0.4.129 - 10.1.9.98, 10.0.3.137, 10.0.4.105 - 10.1.9.98
10.0.4.105开启X-Real-IP10.1.9.98 - - - -10.0.3.137 - 10.1.9.98 - 10.1.9.9810.0.4.105 - 10.1.9.98, 10.0.3.137 - 10.0.3.13710.0.4.129 - 10.1.9.98, 10.0.3.137, 10.0.4.105 - 10.0.3.137
10.0.4.129开启X-Real-IP10.1.9.98 - - - -10.0.3.137 - 10.1.9.98 - 10.1.9.9810.0.4.105 - 10.1.9.98, 10.0.3.137 - 10.0.3.13710.0.4.129 - 10.1.9.98, 10.0.3.137, 10.0.4.105 - 10.0.4.105
10.1.9.98伪造头部访问 curl http://10.0.3.137 -H ‘X-Real-IP: 8.8.8.8’10.1.9.98 - - - 8.8.8.810.0.3.137 - 10.1.9.98 - 10.1.9.9810.0.4.105 - 10.1.9.98, 10.0.3.137 - 10.0.3.13710.0.4.129 - 10.1.9.98, 10.0.3.137, 10.0.4.105 - 10.0.4.105

总结:

  • X-Forwarded-For是一个追加的过程,后面的代理会把前面代理的IP追加到X-Forwarded-For尾部,用逗号进行分隔。
  • 应用服务器(10.0.4.120)无法从X-Forwarded-For中获取到与它直连的代理服务器的IP(10.0.4.129),此时我们可以使用r e m o t e a d d r ( 远 程 i p , 表 示 直 连 的 那 台 代 理 ) 。 当 服 务 器 无 法 过 remote_addr(远程ip,表示直连的那台代理)。当服务器无法过remote addr(远程ip,表示直连的那台代理)。当服务器无法过http_x_forwarded_for获得上级代理或者客户端的ip时(可能没有经过代理),应该使用$remote_addr。
  • 在代理过程中至少有一个代理设置了X-Forwarded-For,否则后面的代理或者应用服务器无法获得相关信息。
  • X-Forwarded-For中虽然包含了真实的客户端IP,一般是第一个IP,但是如果客户端伪造了请求头,那么真实的客户端IP就不是第一个了。
  • HTTP中header里面的X-Real-IP只是一个变量,后面的设置会覆盖前面的设置,所以只需要在第一个代理服务器上设置proxy_set_header X-Real-IP $remote_addr即可,然后在应用端直接引用$http_x_real_ip就行。

在java中,如果请求没有经过nginx代理,可以使用如下方法获取客户端的真实IP:

# 类似nginx中的$remote_addr
request.getRemoteHost();

如果请求经过了nginx代理,可以从请求头中获取(前提是必须正确配置nginx才能获取到):

request.getHeader("x-real-ip");

如果是用的其他Apache,Squid等反向代理软件,同样是从请求头中获取真实IP,只是属性名不一样而已。

到此这篇关于项目中Nginx多级代理是如何获取客户端的真实IP地址的文章就介绍到这了,更多相关Nginx多级代理获取客户端真实IP内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • CentOS 中Nginx的安装方法

    CentOS 中Nginx的安装方法

    最近研究LNMP,首先要在linux下配置nginx服务器,废话少说,下面给大家分享下在CentOS 中Nginx的安装方法
    2017-08-08
  • 如何用nginx配置wordpress的方法示例

    如何用nginx配置wordpress的方法示例

    这篇文章主要介绍了如何用nginx配置wordpress的方法示例,详细的介绍了配置步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 详解Nginx 虚拟主机配置的三种方式(基于端口)

    详解Nginx 虚拟主机配置的三种方式(基于端口)

    Nginx配置虚拟主机支持3种方式主要有基于IP的虚拟主机配置,基于端口的虚拟主机配置,基于域名的虚拟主机配置。本篇文章主要介绍了基于端口的实现,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • 使用Nginx做静态文件服务器,如何进行权限验证

    使用Nginx做静态文件服务器,如何进行权限验证

    这篇文章主要介绍了使用Nginx做静态文件服务器,如何进行权限验证问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • angular6+springboot实现前后分离nginx配置

    angular6+springboot实现前后分离nginx配置

    这篇文章主要介绍了angular6+springboot实现前后分离nginx配置详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • nginx http模块数据存储结构小结

    nginx http模块数据存储结构小结

    这篇文章主要介绍了nginx http模块数据存储结构小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • nginx配置限制同一个ip的访问频率方法

    nginx配置限制同一个ip的访问频率方法

    今天小编就为大家分享一篇nginx配置限制同一个ip的访问频率方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Nginx静态压缩和代码压缩提高访问速度详解

    Nginx静态压缩和代码压缩提高访问速度详解

    Nginx提供静态压缩功能,对于比较大的文件,可以自动默认查找.gz后缀的压缩包,下面这篇文章主要给大家介绍了关于Nginx静态压缩和代码压缩提高访问速度的相关资料,需要的朋友可以参考下
    2022-05-05
  • Nginx 中文域名配置详解及实现

    Nginx 中文域名配置详解及实现

    这篇文章主要介绍了Nginx中 文域名配置详解及实现的相关资料,Nginx虚拟主机上绑定一个带中文域名但是不能跳转,这里给大家说下如何实现,需要的朋友可以参考下
    2016-12-12
  • centos6.4下nginx1.12.1安装教程

    centos6.4下nginx1.12.1安装教程

    这篇文章主要为大家详细介绍了centos6.4下nginx1.12.1安装教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07

最新评论