ingress nginx傳遞用戶真實ip問題

背景

業務應用經常有需要用到用戶真實ip的場景,比如:異地登錄的風險預警、訪問用戶分佈統計等功能等。當有這種需求的時候,在業務上容器過程中,如果用到ingress就要注意配置了。通常,用戶ip的傳遞依靠的是X-Forwarded-*參數。但是默認情況下,ingress是沒有開啓的。

ingress的文檔還比較詳細,這裏介紹一下可能用到的這3個參數:
在這裏插入圖片描述

注:在文檔頂欄的搜索框搜索forward字樣就可以找到這3個參數

1. use-forwarded-headers

  • 如果Nginx在其他7層代理或負載均衡後面,當期望Nginx將X-Forwarded-*的頭信息傳遞給後端服務時,則需要將此參數設爲true
  • 如果設爲false(默認爲false),Nginx會忽略掉X-Forwarded-*的頭信息。false設置適用於Nginx直接對外或前面只有3層負載均衡的場景

由於ingress的主配置是從configmap中獲取的,更新參數則需要修改名爲nginx-configuration的configmap的配置:在data配置塊下添加use-forwarded-headers: "true"

修改後,ingress nginx會自動加載更新nginx.conf主配置文件。下圖爲更新前後配置文件變化對比:
在這裏插入圖片描述

注:左邊爲開啓use-forwarded-headers後ingress nginx主配置文件,右邊爲開啓前

2. forwarded-for-header

用來設置識別客戶端來源真實ip的字段,默認是X-Forwarded-For。如果想修改爲自定義的字段名,則可以在configmap的data配置塊下添加:forwarded-for-header: "THE_NAME_YOU_WANT"。通常情況下,我們使用默認的字段名就滿足需求,所以不用對這個字段進行額外配置。

3. compute-full-forwarded-for

如果只是開啓了use-forwarded-headers: "true"的話,會發現還是沒能獲取到客戶端來源的真實ip,原因是當前X-Forwarded-For變量是從remote_addr獲取的值,每次取到的都是最近一層代理的ip。爲了解決這個問題,就要配置compute-full-forwarded-for字段了,即在configmap的data配置塊添加:compute-full-forwarded-for: "true"。其作用就是,將客戶端用戶訪問所經過的代理ip按逗號連接的列表形式記錄下來。

待ingress nginx加載configmap並更新主配置文件後,對比更新前後變化如下:
在這裏插入圖片描述
在這裏插入圖片描述

注:左邊是未開啓compute-full-forwarded-for配置的ingress nginx主配置文件,右邊是開啓了的

舉例說明

如果從客戶端ip0發起一個HTTP請求到達服務器之前,經過了三個代理proxy1、proxy2、proxy3,對應的ip分別爲ip1、ip2、ip3,那麼服務端最後得到的X-Forwarded-For值爲:ip0,ip1,ip2。列表中並沒有ip3,ip3可以在服務端通過remote_addr來獲得。這樣應用程序通過獲取X-Forwarded-For字段的第一個ip,就可以得到客戶端用戶真實ip了。

注意項

值得注意的是,並不是所有的場景都能通過X-Forwarded-For來獲取用戶正式ip。
比如,當服務器前端使用了CDN的時候,X-Forwarded-For方式獲取到的可能就是CDN的來源ip了,
這種情況,可以根CDN廠商約定一個字段名來記錄用戶真實ip,然後代理將這個字段逐層傳遞,最後到服務端。

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