經過代理如何獲取真實IP 及 laravel 中配置可信代理的原理

php_yt發表於2023-02-14

客戶端直接訪問後端伺服器時,$_SERVER['REMOTE_ADDR'] ji真實客戶端 IP:

經過代理如何獲取真實IP 及 laravel 中為何配置可信代理

remote_addr 是無法偽造的:因為建立 TCP 連線需要三次握手,如果偽造了源 IP,無法建立 TCP 連線。

可如果經過代理

經過代理如何獲取真實IP 及 laravel 中為何配置可信代理

$_SERVER['REMOTE_ADDR'] 是上一級代理的 IP。

真實 IP 通常在 headers 中的 X-Forwarded-ForX-Real-Ip 來獲取:

X-Forwarded-For 是一個 HTTP 擴充套件頭部。HTTP/1.1(RFC 2616)協議並沒有對它的定義,它最開始是由 Squid 這個快取代理軟體引入,用來表示 HTTP 請求端真實 IP。如今它已經成為事實上的標準,被各大 HTTP 代理、負載均衡等轉發服務廣泛使用,並被寫入 RFC 7239(Forwarded HTTP Extension)標準之中。

X-Real-IP,這又是一個自定義頭部欄位。X-Real-IP 通常被 HTTP 代理用來表示與它產生 TCP 連線的裝置 IP,這個裝置可能是其他代理,也可能是真正的請求端。需要注意的是,X-Real-IP 目前並不屬於任何標準,代理和 Web 應用之間可以約定用任何自定義頭來傳遞這個資訊。

我們只討論 X-Forwarded-For。圖2 中的 proxy 代理到 server 需如下配置

location / {
    proxy_pass http://server;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

經過代理如何獲取真實IP 及 laravel 中為何配置可信代理

同理,如果再有多個代理:

經過代理如何獲取真實IP 及 laravel 中為何配置可信代理

透過觀察,請求頭 X-Forwarded-For 的組成是:client,proxy1,proxy2..

第一個 ip 就是客戶端 ip,PHP 中獲取: $_SERVER['HTTP_X_FORWARDED_FOR'][0]

X-Forwarded-For 是可以偽造的,當 client 傳送這樣的請求時:

curl http://xx/ -H 'X-Forwarded-For: 123.123.123.123'

proxy1 再轉發給 proxy2

location / {
    proxy_pass http://proxy2;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

最終:

經過代理如何獲取真實IP 及 laravel 中為何配置可信代理

甚至是不法字串:

curl http://xx/ -H 'X-Forwarded-For: select 1 = 1'

所以取第一個不一定準確,如果沒有檢查 ip 的格式,還有安全隱患。

我們可以這樣配置面向客戶端的 proxy1 的代理轉發,把真實客戶端 ip $remote_addr 直接傳給 `X-Forwarded-For:

location / {
    proxy_pass http://proxy2;
    #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-For $remote_addr;
}

這樣就保證了第一個是真實地址。

假設第一個有可能偽造,便引入了可信代理的概念。假設中間代理是可信任的,即不可能偽造 X-Forwarded-For。如果 server 端獲取的 X-Forwarded-For 頭是:

"http_x_forwarded_for": "select 1 = 1,1.1.1,2.2.2.2,3.3.3.3,4.4.4.4"

配置可信代理:

protected $proxies = [
    '4.4.4.4',
    '3.3.3.3',
    '2.2.2.2',
];

由後向前依次排除,直到 1.1.1.1 不在可信列表中,就認為是真實客戶端 IP。

我們還可以透過 nginx 配置 set_real_ip_from 使 remote_addr 為客戶端真實地址,此配置項依賴 nginx 擴充套件模組 http_realip_module

參考:www.runoob.com/w3cnote/http-x-forw...

本作品採用《CC 協議》,轉載必須註明作者和本文連結
welcome come back

相關文章