Nginx中realip獲取

我們都知道,在Nginx中,想獲取來源的IP,我們可以通過$remote_addr 來獲取,但是很多時候,請求會經過多箇中間代理或CDN,從而導致我們根本無法準確的獲取客戶端的真實IP, 爲解決這種問題,Nginx提供了realip模塊來實現客戶端IP的獲取,詳細信息參見:ngx_http_realip_module

此模塊提供了三個指令:set_real_ip_from, real_ip_header,real_ip_recursive,其功能如下:

  • set_real_ip_from:指定IP的來源信息,用於排除中間代理IP,可以填寫IP或網段。
  • real_ip_header:指定從Header的哪個屬性裏面取IP信息,常用的是 X-Forwarded-For
  • real_ip_recursive:是否遞歸的排除中間代理IP信息,默認值爲off,如果值設置爲off,則只會排除直接上層代理的IP信息,如果值爲on,則會從右至左依次排除用戶配置的中間IP,直到遇到第一個非指定的IP,將此IP設置爲真實IP。

雖然只有三個指令,但是其功能都是比較晦澀難懂的,下面我通過一個實驗,來揭示此模塊的功能及用法:

實現環境:

  • 訪問源IP:10.38.160.252

  • 代理一:10.38.165.227(四層代理,非Nginx),其後端指向代理二的三臺機器

  • 代理二:

    • 10.38.160.94
    • 10.38.160.101
    • 10.38.160.96
  • 代理三:10.38.160.174

  • 代理四:10.232.51.224

  • 目的:10.232.51.224: 8090

連接過程示意圖:
在這裏插入圖片描述
Nginx關鍵配置內容:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr
  • remote_addr:遠程地址,如果未經處理,此值爲與Nginx直接連接的上層的IP地址

  • proxy_add_x_forwarded_for:其值爲 從上一代理獲取到的 X-Forwarded-For 值 追加上 remote_addr 的值,中間使用,分割

能獲取到客戶端真實IP的條件如下:

  1. 所有七層代理(代理2-3) 需要配置如下配置,以使其可以完整記錄經過各個代理時的真實IP信息
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  1. 末端代理(代理4)需要配置如下配置,過濾掉中間配置
set_real_ip_from 10.38.160.94; // 過濾代理2
set_real_ip_from 10.38.160.101; // 過濾代理2
set_real_ip_from 10.38.160.96; // 過濾代理2

set_real_ip_from 10.38.160.174; // 過濾代理3

real_ip_header X-Forwarded-For; // 指定從哪個header裏面取real ip
real_ip_recursive on; // 是否遞歸查找
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr; // 通過上面配置,最終Realip會被存儲在$remote_addr中

通過如上的配置,我們就可以實現對真實IP的獲取,真實IP就存儲在 X-Real-IP 中

問題:

  1. 如果條件1不滿足呢?

如果所有都沒有配置X-Forwarded-For,那將無法獲取到真實IP,只能獲取到代理3的IP,如果部分節點設置了,只能獲取到第一個設置的節點的上一個節點的IP信息,如從代理3開始設置了,那獲取到的 realip 只能獲取到代理2的IP信息

  1. 如果 real_ip_recursive爲off或不設置呢?

如果 real_ip_recursive未設置或值不爲on,那麼即使set_real_ip_from設置了很多,也只會去除上個節點的IP信息,如我在代理4設置瞭如下信息:

set_real_ip_from 10.38.160.94;
set_real_ip_from 10.38.160.101;
set_real_ip_from 10.38.160.96;
set_real_ip_from 10.38.160.174;
real_ip_header X-Forwarded-For;
real_ip_recursive off;
proxy_set_header X-Real-IP $remote_addr;

那麼,獲取到的真實IP只會是代理2中的任意一個,即:10.38.160.94、10.38.160.101 或 10.38.160.96,即使set_real_ip_from設置了這三個IP,但是還是不會繼續往上遞歸去除,只會對上個節點起作用

  1. 如果set_real_ip_from沒有設置,或設置不完全呢?

set_real_ip_from的功能是從X-Forwarded-For中去除掉中間層IP信息,如果中間IP設置不全,則會導致某個未設置的中間IP被當成客戶端真實IP

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章