Nginx反向代理&记录用户IP地址企业案例

反向代理机器节点:
lb01 10.0.0.30    #lb01是反向代理服务器(包括负载均衡的功能)
www01 10.0.0.40 
www02 10.0.0.50

【演示反向代理功能】

 图片解读:

  • 使用客户端机器www01,访问负载均衡lb01(反向代理),看到了www01,www02页面信息
  • 在www01服务器上检测客户端信息,发现请求是10.0.0.30发来的,这不是lb01吗
  • 但是我们请求明明是www01发出的

这就是反向代理的含义,用户请求发送给了反向代理,反向代理再次发出一个请求

【如何解决这个问题呢,扑捉到真实的客户端的IP,而非代理服务器呢?】

X-Forwarded-For

 在反向代理请求后端节点服务器的请求头中添加获取客户端IP的字段信息,然后在后端节点可以通过程序或者相关配置接收X-Forwarded-For传过来的真实用户的IP信息。

【lb01反向代理节点配置如下】

部分nginx.conf代码如下,注意重点修改的部分

    upstream www_pools {
        server 10.0.0.40;
        server 10.0.0.50;

}

    server {
        listen       80;
        server_name  www.junwu.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://www_pools;
            proxy_set_header Host $host;
           #添加此处代码,代理服务器向后端发送HHTP请求时,请求头中添加该参数信息,用于后端服务器程序、日志等接受真实用户的IP,而非是代理服务器的IP
            proxy_set_header X-Forwarded-For $remote_addr;
}

重新加载lb01的nginx

[root@lb01 ~]# nginx -s reload

特别注意,不仅要在代理服务器配置,添加获取真实IP的字段,还要在节点服务器中添加配置,接受用户真实的IP,配置日志格式等操作。

【修改节点服务器www01的nginx.conf】

部分代码修改如下,关注重点修改的部分

http {
    include       mime.types;
    default_type  application/octet-stream;
#重点在于此处,添加结尾的参数$http_x_forwarded_for,即可在日志中获取客户端的真实IP
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
#还有此处的日志格式配置,一定一定要在后面添加main参数,才能在日志中展现客户端IP
    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  www.bbq.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        }
    server {
        listen       80;
        server_name  www.mxj.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

测试效果一

检查10.0.0.40节点的日志信息
[root@www01 ~]# tail -f /opt/nginx-1.25.1/logs/access.log 
10.0.0.30 - - [25/Jun/2023:10:56:31 -0400] "GET / HTTP/1.0" 200 46 "-" "curl/7.29.0"
10.0.0.30 - - [25/Jun/2023:10:56:33 -0400] "GET / HTTP/1.0" 200 46 "-" "curl/7.29.0"
10.0.0.30 - - [25/Jun/2023:10:56:52 -0400] "GET / HTTP/1.0" 200 46 "-" "curl/7.29.0" "10.0.0.40"
10.0.0.30 - - [25/Jun/2023:10:57:01 -0400] "GET / HTTP/1.0" 200 46 "-" "curl/7.29.0" "10.0.0.40"
#日志解析
10.0.0.30显示的是远程访客的地址,也就是lb01负载均衡发来的请求
“10.0.0.40”是通过X-Forwarded-For参数获取到的真实客户端的ip

测试效果二

我们在另外一台节点服务器10.0.0.50上访问负载均衡器
[root@www02 ~]# curl www.junwu.com
这是网站www.bbq50.com
[root@www02 ~]# curl www.junwu.com
<meta charset=utf8>
这是网站www.bbq40.com
[root@www02 ~]# curl www.junwu.com
这是网站www.bbq50.com
##然后在另一台www01节点服务器上查看日志
10.0.0.30 - - [25/Jun/2023:11:02:50 -0400] "GET / HTTP/1.0" 200 46 "-" "curl/7.29.0" "10.0.0.50"
最终通过日志,发现检测到了真实发请求的,其实是www02机器,ip为10.0.0.50

总结

  • nginx的access.log日志,其日志格式里$remote_addr变量,表示远程客户端的IP地址(可能是代理IP地址)
  • $http_x_forwarded_for变量,是接收了在反向代理中配置的proxy_set_header X-Forwarded-For $remote_addr,获取了用户真实的IP(躲在代理IP后)

当然这里的X-Forwarded-For并不是万能的,所谓道高一尺魔高一丈,对于代理的形式还有很多种。

 

posted @ 2023-06-25 23:08  Junwu’sblog  阅读(504)  评论(0编辑  收藏  举报