系统相关
首页 > 系统相关> > nginx反向代理实现获取用户真实ip

nginx反向代理实现获取用户真实ip

作者:互联网

   我们访问互联网上的服务时,大多数时,客户端并不是直接访问到服务端的,而是客户端首先请求到反向代理,反向代理再转发到服务端实现服务访问,通过反向代理实现路由/负载均衡等策略。这样在服务端拿到的客户端IP将是反向代理IP,而不是真实客户端IP,因此需要想办法来获取到真实客户端IP

# 客户端访问服务端的数据流走向
Client(172.25.0.1) --> ADSL( 192.168.0.1) --> cdn(10.0.0.1) --> SLB(反向代理)11.0.0.1 --> server(nginx)12.0.0.1

   可以看出,服务端根本获取不到真实的客户端ip,只能获取到上一层服务的ip,那么nginx怎样才能获取到真实的ip呢?

   1.用一台服务器模拟实现获取本机ip

      源码编译,添加一个模块,获取real ip

 [root@base1 ~]# tar zxf nginx-1.14.2.tar.gz 
 [root@base1 ~]# yum install -y gcc pcre-devel zlib-devel                                     # 这是编译nginx的依赖包
 [root@base1 ~]# cd nginx-1.14.2
 [root@base1 nginx-1.14.2]# make 
 [root@base1 nginx-1.14.2]# ./configure --prefix=/usr/local/nginx --with-http_realip_module   # 添加了一个获取realip的模块
 [root@base1 nginx-1.14.2]# make && make install
 [root@base1 nginx-1.14.2]# nginx -V                                                          # 查看编译参数

      

 [root@base1 nginx-1.14.2]# cd /usr/local/nginx/conf/
 [root@base1 conf]# vim nginx.conf
 # 添加虚拟主机
     server {
         listen 80;
         server_name base1.westos.org;
 
         location / {
             return 200;
         }
     }

   

 [root@base1 conf]# nginx                     #开启nginx服务
 [root@base1 conf]# nginx -s reload
 [root@base1 conf]# vim /etc/hosts            #添加域名
 172.25.78.11   base1    base1.westos.org
[root@base1 conf]# curl -I base1.westos.org #测试

     

     # 当检测成功时,让回应real ip

 [root@base1 conf]# vim nginx.conf
     server {
         listen 80;
         server_name base1.westos.org;
 
         location / {
          return 200 "client real ip: $remote_addr\n";   # $remote_addr 代表客户端真实IP
         }
     }

    

 

 [root@base1 conf]# nginx -s reload       #平滑重启nginx
[root@base1 conf]# curl base1.westos.org #测试

     

    # 从X-Forwarded-For中获取到真实客户端IP

[root@base1 conf]# vim nginx.conf
    server {
     listen 80;
     server_name base1.westos.org;            # 添加域名
     set_real_ip_from 172.25.78.11;           # 真实服务器上一级代理的IP地址或者IP段,可以写多行
     real_ip_header    X-Forwarded-For;       # 告知Nginx真实客户端IP从哪个请求头获取
     real_ip_recursive off;                   # 是否递归解析,off表示默认从最后一个地址开始解析

     location / {
        return 200 "client real ip: $remote_addr\n";
     }
   }

[root@base1 conf]# nginx -s reload
[root@base1 conf]# curl -H "X-Forwarded-For:1.1.1.1,172.25.78.11" base1.westos.org #给X-Forwarded-For中添加ip,从而获取ip 172.25.78.11

    # 修改配置文件里的参数real_ip_recursive 为on

[root@base1 conf]# vim nginx.conf
  real_ip_recursive on;                                                              # 从前往后依次递归获取ip
[root@base1 conf]# nginx -s reload
[root@base1 conf]# curl -H "X-Forwarded-For:1.1.1.1,172.25.78.11" base1.westos.org #测试

    

 

   以上操作仅仅实现了获取本机ip和使用X-Forwarded-For的功能,现在我们来模拟实际生产中在有反向代理的阻碍下获取真实客户端ip,这里我们用一个反向代理来模拟

base1 : 后端服务器
base2 : nginx反向代理服务器

   # 配置反向代理服务器

[root@base2 ~]# yum install -y  gcc pcre-devel zlib-devel
[root@base2 ~]# tar zxf nginx-1.14.2.tar.gz 
[root@base2 ~]# cd nginx-1.14.2
[root@base2 nginx-1.14.2]# vim auto/cc/gcc 
171 # debug
172 #CFLAGS="$CFLAGS -g"
[root@base2 nginx-1.14.2]# ./configure --prefix=/usr/local/nginx/   --with-http_realip_module
[root@base2 nginx-1.14.2]# make && make install
[root@base2 nginx-1.14.2]# cd /usr/local/nginx/conf/
    server {
    listen 80;
    location / {
        proxy_set_header X-Real-IP $remote_addr;                       # 存放用户的真实ip
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   # 每经过一个反向代理,就会把反向代理IP存放在X-Forwarded-For里
        proxy_pass http://172.25.78.11:80;
    }
}
[root@base2 conf]# ln -s /usr/local/nginx/sbin/nginx /sbin
[root@base2 conf]# nginx
[root@base2 conf]# nginx -s reload

    # 配置服务端

[root@base1 conf]# vim nginx.conf
    server {
        listen 80;
        server_name base1.westos.org;         #域名
        set_real_ip_from 172.25.78.0/24;
        real_ip_header    X-Forwarded-For;
        real_ip_recursive on;  

        location / {
            root  /web;                       # 指定发布目录
            index index.html index.htm;
        }
    }
[root@base1 conf]# nginx -s reload
[root@base1 conf]# mkdir /web
[root@base1 conf]# vim /web/index.html 
 www.westos.org

   # 客户端测试

[root@foundation78 Desktop]# vim /etc/hosts
172.25.78.11 base1  base1.westos.org
[root@foundation78 Desktop]# curl base1.westos.org
  www.westos.org

  # 服务端查看日志

[root@base1 conf]# cat /usr/local/nginx/logs/access.log    # 通过日志可以直接查看到客户端真实ip

     

总结:

          1.使用realip模块后,$remote_addr输出结果为真实客户端IP,可以使用$realip_remote_addr获取最后一个反向代理的IP;
          2.real_ip_headerX-Forwarded-For:告知Nginx真实客户端IP从哪个请求头获取;
          3.set_real_ip_from 172.25.78.0/24:告知Nginx哪些是反向代理IP,即排除后剩下的就是真实客户端IP
          4.real_ip_recursive on:是否递归解析,当real_ip_recursive配置为off时,Nginx会把real_ip_header指定的请求头中的最后一个IP作为真实客户端IP;
          当real_ip_recursive配置为on时,Nginx会递归解析real_ip_header指定的请求头,最后一个不匹配set_real_ip_from的IP作为真实客户端IP。 

 

标签:real,nginx,ip,base1,反向,conf,root
来源: https://www.cnblogs.com/mzhaox/p/11214747.html