執行個體環境:
使用者IP 120.22.11.11
CDN前端 61.22.22.22
CDN中轉 121.207.33.33
公司NGINX前端代理 192.168.50.121(外網121.207.231.22)
1、使用CDN自定義IP頭來擷取
假如說你的CDN廠商使用nginx,那麼在nginx上将$remote_addr指派給你指定的頭,方法如下:
1
proxy_set_header remote-user-ip $remote_addr;
2
3
4
<?php
$ip = getenv("HTTP_REMOTE_USER_IP");
echo $ip;
?>
通路getRemoteUserIP.php,結果如下:
120.22.11.11 //取到了真實的使用者IP,如果CDN能給定義這個頭的話,那這個方法最佳
2、通過HTTP_X_FORWARDED_FOR擷取IP位址
一般情況下CDN伺服器都會傳送HTTP_X_FORWARDED_FOR頭,這是一個ip串,後端的真實伺服器擷取HTTP_X_FORWARDED_FOR頭,截取字元串第一個不為unkown的IP作為使用者真實IP位址, 例如:
120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121(使用者IP,CDN前端IP,CDN中轉,公司NGINX代理)
getFor.php
$ip = getenv("HTTP_X_FORWARDED_FOR");
echo $ip;
通路getFor.php結果如下:
120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121
如果你是php程式員,你擷取第一個不為unknow的ip位址,這邊就是120.22.11.11.
3.使用nginx自帶子產品realip擷取使用者IP位址
安裝nginx之時加上realip子產品,我的參數如下:
./configure --prefix=/usr/local/nginx-1.4.1 --with-http_realip_module
真實伺服器nginx配置
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
listen 80;
server_name www.ttlsa.com;
access_log /data/logs/nginx/www.ttlsa.com.access.log main;
index index.php index.html index.html;
root /data/site/www.ttlsa.com;
location /
{
root /data/site/www.ttlsa.com;
}
location = /getRealip.php
set_real_ip_from 192.168.50.0/24;
set_real_ip_from 61.22.22.22;
set_real_ip_from 121.207.33.33;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
fastcgi_pass unix:/var/run/phpfpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
getRealip.php内容
<?php
$ip = $_SERVER['REMOTE_ADDR'];
echo $ip;
?>
通路www.ttlsa.com/getRealip.php,傳回:
120.22.11.11
如果注釋 real_ip_recursive on或者 real_ip_recursive off
121.207.33.33
很不幸,擷取到了中繼的IP,real_ip_recursive的效果看明白了吧.
set_real_ip_from:真實伺服器上一級代理的IP位址或者IP段,可以寫多行
real_ip_header:從哪個header頭檢索出要的IP位址
real_ip_recursive:遞歸排除IP位址,ip串從右到左開始排除set_real_ip_from裡面出現的IP,如果出現了未出現這些ip段的IP,那麼這個IP将被認為是使用者的IP。例如我這邊的例子,真實伺服器擷取到的IP位址串如下:
在real_ip_recursive on的情況下
61.22.22.22,121.207.33.33,192.168.50.121都出現在set_real_ip_from中,僅僅120.22.11.11沒出現,那麼他就被認為是使用者的ip位址,并且指派到remote_addr變量
在real_ip_recursive off或者不設定的情況下
192.168.50.121出現在set_real_ip_from中,排除掉,接下來的ip位址便認為是使用者的ip位址
如果僅僅如下配置:
set_real_ip_from 192.168.50.0/24;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
通路結果如下:
121.207.33.33
4、三種在CDN環境下擷取使用者IP方法總結
4.1 CDN自定義header頭
優點:擷取到最真實的使用者IP位址,使用者絕對不可能僞裝IP
缺點:需要CDN廠商提供
4.2 擷取forwarded-for頭
優點:可以擷取到使用者的IP位址
缺點:程式需要改動,以及使用者IP有可能是僞裝的
4.3 使用realip擷取
優點:程式不需要改動,直接使用remote_addr即可擷取IP位址
缺點:ip位址有可能被僞裝,而且需要知道所有CDN節點的ip位址或者ip段
轉載:http://www.ttlsa.com/nginx/nginx-get-user-real-ip/
本文轉自 亮公子 51CTO部落格,原文連結:http://blog.51cto.com/iyull/1864375