使用 CDN 或反向代理後,$_SERVER['REMOTE_ADDR'] 獲取到的是代理服務器 IP,需從 HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR 等頭部提取真實客戶端 IP。
function checkip(checkstring)
dim re1
set re1 = new RegExp
re1.pattern = "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
re1.global = false
re1.IgnoreCase = false
checkip = re1.test(checkstring)
set re1 = nothing
end function
function get_cli_ip()
dim client_ip
if checkip(Request.ServerVariables("HTTP_CLIENT_IP")) = true then
get_cli_ip = Request.ServerVariables("HTTP_CLIENT_IP")
else
MyArray = split(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ",")
if ubound(MyArray) >= 0 then
client_ip = trim(MyArray(0))
if checkip(client_ip) = true then
get_cli_ip = client_ip
exit function
end if
end if
get_cli_ip = Request.ServerVariables("REMOTE_ADDR")
end if
end function
<?php
function getRealIp() {
$unknown = 'unknown';
$ip = $unknown;
// 1. HTTP_CLIENT_IP
if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), $unknown)) {
$ip = getenv('HTTP_CLIENT_IP');
}
// 2. HTTP_X_FORWARDED_FOR (可能包含多個 IP,取第一個非內網)
elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), $unknown)) {
$forwarded = explode(',', getenv('HTTP_X_FORWARDED_FOR'));
$firstIp = trim($forwarded[0]);
$parts = explode('.', $firstIp);
// 過濾私有網段
if (!($parts[0] == '10' || ($parts[0] == '192' && $parts[1] == '168') || ($parts[0] == '172' && $parts[1] >= 16 && $parts[1] <= 31))) {
$ip = $firstIp;
} else {
$ip = getenv('REMOTE_ADDR');
}
}
// 3. REMOTE_ADDR
elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), $unknown)) {
$ip = getenv('REMOTE_ADDR');
}
// 4. $_SERVER 兜底
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
// 使用
$realIp = getRealIp();
echo "客戶端真實 IP: $realIp";
?>
HTTP_CLIENT_IP > HTTP_X_FORWARDED_FOR(首個非私有 IP) > REMOTE_ADDRset_real_ip_from/real_ip_header 固化可信代理 IP,避免頭部偽造HTTP 頭部可被客戶端偽造,關鍵業務(登錄、支付、風控)應結合設備指紋、行為分析、短信驗證等多因子驗證,不可單純依賴 IP 判斷身份。