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。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM