در PHP

تابع PHP برای به دست آوردن IP بازدید کننده در پشت CloudFlare یا Proxy

چند روز پیش یکی از سایت های زیر مجموعه شرکت به اسم رام ایران را منتقل کردیم روی سرویس ابری کلودفلر تا بتونیم از فایروال و CDN استفاده کنیم.

Cloudflare به عنوان یک CDN و فایروال DDoS بسیار عالیه اما نکته منفیش اینه که آدرس IP که توسط وب سرور شما مشاهده میشه همان پروکسی Clouflare است و نه IP واقعی مشتری.

ما بعد از گذشت چند ساعت و با زیاد شدن تعداد تیکت ها و نارضایتی کاربران از عدم امکان دانلود فایل متوجه شدیم. با بررسی متوجه شدم که تابعی که قبلا برای گرفتن IP کاربر نوشته بودم به جای یک IP دو تا بر می گردوند. از طرفی همان تابع روی سرور دانلود که روی سابدامین مستقلیه و پشت کلودفلر نیست یک IP بر میگردوند و شرط اجازه دانلود false میشد.

تابع قبلی

function get_user_ip ()
{
	if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) )
		$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
	else if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
		$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
	else if ( isset( $_SERVER['HTTP_X_FORWARDED'] ) )
		$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
	else if ( isset( $_SERVER['HTTP_FORWARDED_FOR'] ) )
		$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
	else if ( isset( $_SERVER['HTTP_FORWARDED'] ) )
		$ipaddress = $_SERVER['HTTP_FORWARDED'];
	else if ( isset( $_SERVER['REMOTE_ADDR'] ) )
		$ipaddress = $_SERVER['REMOTE_ADDR'];
	else
		$ipaddress = 'UNKNOWN';

	return $ipaddress;
}

مقدار بازگشتی . IP دوم مربوط به پروکسی Cloudflare هست و باعث مشکل شده بود.

84.242.51.236, 162.158.90.56

در نهایت برای رفع مشکل ، تابع زیر را جایگزین تابع قبلی کردم.

function get_user_ip ()
{
	if ( isset( $_SERVER["HTTP_CF_CONNECTING_IP"] ) )
	{
		$_SERVER['REMOTE_ADDR']    = $_SERVER["HTTP_CF_CONNECTING_IP"];
		$_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
	}
	
	$client  = @$_SERVER['HTTP_CLIENT_IP'];
	$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
	$remote  = $_SERVER['REMOTE_ADDR'];

	if ( filter_var( $client, FILTER_VALIDATE_IP ) )
		$ipaddress = $client;
	elseif ( filter_var( $forward, FILTER_VALIDATE_IP ) )
		$ipaddress = $forward;
	else
		$ipaddress = $remote;

	return $ipaddress;
}

ارسال نظر

دیدگاه