Nginx 與 X-Forwarded-For



HTTP擴展頭部 X-Forwarded-For,以及在nginx中使用http_x_forwarded_for變量來完成一些"特殊"功能,例如網站后台面向內部工作人員,希望只允許辦公室網絡IP訪問。

 X-Forwarded-For,它用來記錄代理服務器的地址,每經過一個代理該字段會追加上一個記錄。例如:6.6.6.6, 8.8.8.8。


拿出生產環境的一個例子,客戶端瀏覽網站發出一個請求,請求先經過阿里雲SLB負載均衡器,然后進入Rancher內部的LB負載均衡器,經過兩次負載均衡器轉發后請求到達nginx服務器。


X-Forwarded-For HTTP擴展頭部

日志中的記錄表示 client: 101.251.xxx.192 、proxy1: 100.97.xxx.187,不是說 X-Forwarded-For用來記錄代理服務器的地址,每經過一個代理該字段會追加上一個記錄,為什么client IP 會出現在這個字段中呢?

帶着疑惑這里有必要專門講一講 X-Forwarded-For HTTP頭部。X-Forwarded-For 是一個 HTTP擴展頭部,HTTP/1.1(RFC 2616)協議並沒有對它的定義,它最開始是由 Squid緩存代理軟件引入,用來表示 HTTP請求端真實IP。最終成為事實上的標准被寫入 RFC 7239(Forwarded HTTP Extension)標准之中。

X-Forwarded-For 標准格式

X-Forwarded-For: client, proxy1, proxy2
 

從標准格式可以看出,X-Forwarded-For頭部信息可以有多個,中間使用逗號分隔,第一項為真實的客戶端IP剩下的就是經過的代理或負載均衡的IP地址,經過幾個就會出現幾個。

回到上面的示例,HTTP請求到達nginx服務器之前,經過了兩個代理Proxy1、Proxy2,IP 分別為IP1、IP2,用戶真實IP為 IP0,那么按照 XFF標准格式,nginx服務器最終的XFF變量如下:

X-Forwarded-For: IP0, IP1

 

Proxy2是直連服務器的,它會給 XFF追加IP1,表示它是在幫 Proxy1轉發請求,IP2是在服務端通過 Remote Address 獲得。Remote Address 也無法偽造,因為建立TCP連接需要三次握手,如果偽造了源IP,無法建立TCP連接,更不會有后面的 HTTP請求。


nginx 中的 http_x_forwarded_for 變量用來表示 X-Forwarded-For ,下面用一個例子說明 nginx 如何使用 http_x_forwarded_for,例如借用這個變量限制網站后台訪問。

1. 環境

browser -> haproxy -> nginx

 

目標判斷 haproxy負載均衡傳遞的 http_x_forwarded_for變量,確定是否為辦公室IP?是否允許訪問網站后台?

2. 方法

a. 修改 nginx 虛擬主機配置文件,添加以下語句。

cat default.conf

server  
{    
  #... 其它配置項省略

    location ^~ /admin/ {

      if ($http_x_forwarded_for !~ 'your_office_ip') {
         return 403;
      }
      
      #... 其它配置項省略    
    }

}

 

b. 重新加載

nginx -t && nginx -s reload

 

c. 偽造XFF

需要特別說明的是XFF是可以偽造的,例如使用curl 發送一個帶有"X-Forwarded-For:8.8.8.8"的頭部信息。

curl -IL -H "X-Forwarded-For:8.8.8.8" https://www.test.com/static/09.png

 

假設你采用XFF對比IP方式來限制網站后台訪問,如果對方知道你的網站在用這個策略限制后台訪問,並且通過一些方法知道了你辦公室的IP地址,那么這個策略也就失效了。如果你的網站"前后台"可以分離,那么可以為分離后的后台服務器添加防火牆規則,通過網絡層限制來源IP地址達到同樣目的。


免責聲明!

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



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