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
肆
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地址達到同樣目的。